[llvm] r199536 - Debug info (LTO): Move the creation of accessibility flags to

Adrian Prantl aprantl at apple.com
Fri Aug 29 15:57:39 PDT 2014


> On Aug 29, 2014, at 3:56 PM, David Blaikie <dblaikie at gmail.com> wrote:
> 
> 
> 
> 
> On Fri, Aug 29, 2014 at 3:51 PM, Adrian Prantl <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
> 
> > On Aug 29, 2014, at 9:27 AM, David Blaikie <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
> >
> > As you mention in the comment, accessibility flags are mutually exclusive - we could take advantage of that fact and only use 2 bits instead of 3:
> >
> > FlagAccessibility = 3;
> >
> > FlagPrivate = 1;
> > FlagProtected = 2;
> > FlagPublic = 3;
> >
> > ...
> >
> > (getFlags() & FlagAccessibility) == FlagPrivate;
> >
> > Etc...
> >
> > (maybe some wordsmithing on the names so it's clear that "getFlags() & FlagPrivate" is not the right way to do things if we go that route)
> 
> I implemented that. As long as consumers always use the getter functions this should be fine.
> 
> (did you mean to attach a revised patch - or just going to commit & I'll look at it there?)

Didn’t mean to be all that mysterious, sorry!
LLVM r216799
 CFE r216800

In my previous patch I actually forgot about the static data members in the backend, in case you’re wondering why I touched so many more testcases.

-- adrian

>  
> 
> >
> > Might be worth leveraging DISubprogram::getFlags to implement the various flag checks, the same way DIType does this.
> >
> > While the source of the new test case is the same as a clang test, it might be helpful to include the source in the LLVM test anyway, so it's easy to understand what it's testing and why (as it stands, I can't look at the test case and tell whether what it's checking is correct - I don't know what those functions are and what accessibility they're meant to have) - and in case the source ends up diverging (more things might be added to the clang test at some point, for example - and if they all produce the same kind of IR, there might not be any reason to add them to the LLVM test (eg: clang test might test that 3 different constructs all produce similar IR, LLVM test only needs to test one case of that similar IR))
> 
> Done. Still, I’d rather have people keep tests like that in sync; it’s the closest we have to an end-to-end test. If they diverge, there is a risk that eventually we are testing for a form of IR that isn’t produced by any frontend, while frontends are producing IR that we don’t have tests for. Of course, LLVM should be able to handle all legal IR, but with our current state of test coverage I’m already happy if we are at least testing everything that clang produces.
> >
> > Why did the type-unique-simple test cases need to be updated?
> 
> They test for a bug where the access specifier was emitted twice after llvm-linking two modules that contained metadata for the same public member function, so the public bit needed to be updated.
> 
> >
> > Clang patch:
> > getAccessFlag has elses after returns - a switch might be more suitable there anyway. Is the "return 0" at the end reachable? Oh, I guess it is since you don't early exit on a non-record type.
> >
> > I imagine this whole function might make more sense with something like:
> > if (Access == clang::AS_none) // Does this cover the union case as well?
> >   return 0;
> 
> Nope it doesn’t. They come out as public; see below why:
> >
> > assert(isClass || isStruct)
> >
> > if ((isClass ? private : public) == Access) // or split the conditional out into initializing the local Default variable if you prefer)
> >   return 0;
> >
> > switch (Access)
> > case public: return
> > case private: return
> > case protected: return
> > case none: unreachable
> > }
> >
> > Maybe?
> >
> > It looks like unions do support accessibility, though...
> > union x { private: int a; public: int b; } y;
> > GCC produces an "a" with DW_AT_accessibility (0x03) and "b" with no DW_AT_accessibility
> 
> Whoa, I wasn’t aware of that! Always a new corner to discover in C++ :-)
> Handled similar to structs now.
> 
> >
> > Is there any way to just retrieve the default accessibility from the CXXRecordDecl or query it if this is the default? I wonder where the code that initializes the field's accessibility is and whether we can reuse whatever its defaulting logic is rather than having to rewrite it here (not that it's a lot to rewrite, to be fair).
> It appears as if the defaulting logic is hardcoded in the frontend, but let me know if I’m missing something. It’s just two lines, though.
> >
> > in getOrCreateStaticDataMemberDeclarationOrNull does that need to be a dyn_cast? When is a static data member not a member of a record?
> Originally I wasn’t sure what the ObjC frontend might generate, but after digging through the sources, a static cast seems to be fine.
> >
> > In debug-info-access,.cpp, rather than having all the out of line definitions, you should hopefully just need an instance of each class to cause the type to be emitted, along with all its members. (unless you want to check that the definitions of the functions don't carry accessibility as well - it should only be on the declarations)
> Done.
> >
> > If any of those test cases don't need to be testing accessibility, you can just use {{.*}} to skip over the [public] annotation (and any other annotations that aren't relevant to the test) - you can commit such a change ahead of time, so that they pass with or without the LLVM change (thus you don't get that annoying revision skew when committing a breaking change). This makes the test less annoying the next time we change something in the annotation text that's also irrelevant to these tests.
> I’ll save this for a separate commit.
> >
> > I think that's just about enough nitpicking for my morning - thanks again for doing this!
> Thanks, especially for pointing out the union bit.
> 
> Adrian
> >
> > - David
> >
> >
> >
> > On Fri, Aug 29, 2014 at 8:49 AM, Adrian Prantl <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
> > Hi David,
> >
> > patch is pretty straight-forward, but since you came up with the idea I thought I’d give you a chance to nitpick first :-)
> > I rolled the addition of the public flag and the optimization into one commit, because I’m not going to update all the testcases twice (first for adding [public] and then for removing all the structs again).
> >
> > cheers,
> > adrian
> >
> >
> >
> >> On Aug 28, 2014, at 9:26 AM, Adrian Prantl <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
> >>
> >>
> >>> On Aug 27, 2014, at 3:44 PM, David Blaikie <dblaikie at gmail.com <mailto:dblaikie at gmail.com>> wrote:
> >>>
> >>>
> >>>
> >>>
> >>> On Fri, Jan 17, 2014 at 6:12 PM, Adrian Prantl <aprantl at apple.com <mailto:aprantl at apple.com>> wrote:
> >>> Author: adrian
> >>> Date: Fri Jan 17 20:12:00 2014
> >>> New Revision: 199536
> >>>
> >>> URL: http://llvm.org/viewvc/llvm-project?rev=199536&view=rev <http://llvm.org/viewvc/llvm-project?rev=199536&view=rev>
> >>> Log:
> >>> Debug info (LTO): Move the creation of accessibility flags to
> >>> getOrCreateSubprogramDIE to avoid attributes being added twice when DIEs
> >>> are merged.
> >>>
> >>> I believe this change may've caused DW_AT_accessibility to be emitted for all subprogram DIEs, not just member subprogram DIEs (ie: even for free functions).
> >>
> >> Confirmed!
> >>>
> >>> Honestly, probably the right fix is to add another flag (FlagPublic) and then just emit DW_AT_accessibility if one of the three flags is set. This would allow the frontend to omit the flag even for members, if their accessibility is the default (eg: public members in structs, private members in classes) - it's something I've seen GCC do that Clang doesn't (could be a very minor DWARF size reduction benefit).
> >>
> >> I agree. Also, the previous default of “everything in a class/struct/union is marked as public” does really only make sense for C++.
> >> I will come up with a patch.
> >>
> >> thanks,
> >> adrian
> >>
> >>>
> >>> (I came across this while trying to improve -gmlt, in which case I'd like to not emit accessibility at all, even for member functions)
> >>>
> >>> - David
> >>>
> >>>
> >>> rdar://problem/15842330.
> >>>
> >>> Added:
> >>>     llvm/trunk/test/Linker/type-unique-simple2-a.ll
> >>>     llvm/trunk/test/Linker/type-unique-simple2-b.ll
> >>> Modified:
> >>>     llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
> >>>
> >>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
> >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=199536&r1=199535&r2=199536&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=199536&r1=199535&r2=199536&view=diff>
> >>> ==============================================================================
> >>> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
> >>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Fri Jan 17 20:12:00 2014
> >>> @@ -1191,21 +1191,9 @@ void DwarfUnit::constructTypeDIE(DIE &Bu
> >>>      for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
> >>>        DIDescriptor Element = Elements.getElement(i);
> >>>        DIE *ElemDie = NULL;
> >>> -      if (Element.isSubprogram()) {
> >>> -        DISubprogram SP(Element);
> >>> -        ElemDie = getOrCreateSubprogramDIE(SP);
> >>> -        if (SP.isProtected())
> >>> -          addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
> >>> -                  dwarf::DW_ACCESS_protected);
> >>> -        else if (SP.isPrivate())
> >>> -          addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
> >>> -                  dwarf::DW_ACCESS_private);
> >>> -        else
> >>> -          addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
> >>> -                  dwarf::DW_ACCESS_public);
> >>> -        if (SP.isExplicit())
> >>> -          addFlag(ElemDie, dwarf::DW_AT_explicit);
> >>> -      } else if (Element.isDerivedType()) {
> >>> +      if (Element.isSubprogram())
> >>> +        ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
> >>> +      else if (Element.isDerivedType()) {
> >>>          DIDerivedType DDTy(Element);
> >>>          if (DDTy.getTag() == dwarf::DW_TAG_friend) {
> >>>            ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
> >>> @@ -1490,6 +1478,19 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE
> >>>    if (SP.isRValueReference())
> >>>      addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
> >>>
> >>> +  if (SP.isProtected())
> >>> +    addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
> >>> +            dwarf::DW_ACCESS_protected);
> >>> +  else if (SP.isPrivate())
> >>> +    addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
> >>> +            dwarf::DW_ACCESS_private);
> >>> +  else
> >>> +    addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
> >>> +            dwarf::DW_ACCESS_public);
> >>> +
> >>> +  if (SP.isExplicit())
> >>> +    addFlag(SPDie, dwarf::DW_AT_explicit);
> >>> +
> >>>    return SPDie;
> >>>  }
> >>>
> >>>
> >>> Added: llvm/trunk/test/Linker/type-unique-simple2-a.ll
> >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-simple2-a.ll?rev=199536&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-simple2-a.ll?rev=199536&view=auto>
> >>> ==============================================================================
> >>> --- llvm/trunk/test/Linker/type-unique-simple2-a.ll (added)
> >>> +++ llvm/trunk/test/Linker/type-unique-simple2-a.ll Fri Jan 17 20:12:00 2014
> >>> @@ -0,0 +1,129 @@
> >>> +; REQUIRES: object-emission
> >>> +;
> >>> +; RUN: llvm-link %s %p/type-unique-simple2-b.ll -S -o - | llc -filetype=obj -O0 | llvm-dwarfdump -debug-dump=info - | FileCheck %s
> >>> +;
> >>> +; Tests for a merge error where attributes are inserted twice into the same DIE.
> >>> +;
> >>> +; $ cat ab.h
> >>> +; typedef int foo_t;
> >>> +; class A {
> >>> +; public:
> >>> +;   virtual void setFoo();
> >>> +;   virtual const foo_t getFoo();
> >>> +; };
> >>> +;
> >>> +; $ cat a.cpp
> >>> +; #include "ab.h"
> >>> +; foo_t bar() {
> >>> +;     return A().getFoo();
> >>> +; }
> >>> +;
> >>> +; CHECK: _ZN1A6setFooEv
> >>> +; CHECK: DW_AT_accessibility [DW_FORM_data1]   (0x01)
> >>> +; CHECK-NOT: DW_AT_accessibility
> >>> +; CHECK: DW_TAG
> >>> +
> >>> +; ModuleID = 'a.cpp'
> >>> +
> >>> +%class.A = type { i32 (...)** }
> >>> +
> >>> + at _ZTV1A = external unnamed_addr constant [4 x i8*]
> >>> +
> >>> +; Function Attrs: nounwind
> >>> +define i32 @_Z3barv() #0 {
> >>> +entry:
> >>> +  %tmp = alloca %class.A, align 8
> >>> +  %0 = bitcast %class.A* %tmp to i8*, !dbg !38
> >>> +  call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 8, i32 8, i1 false), !dbg !38
> >>> +  call void @_ZN1AC1Ev(%class.A* %tmp) #1, !dbg !38
> >>> +  %call = call i32 @_ZN1A6getFooEv(%class.A* %tmp), !dbg !38
> >>> +  ret i32 %call, !dbg !38
> >>> +}
> >>> +
> >>> +; Function Attrs: nounwind
> >>> +declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #1
> >>> +
> >>> +; Function Attrs: inlinehint nounwind
> >>> +define linkonce_odr void @_ZN1AC1Ev(%class.A* %this) unnamed_addr #2 align 2 {
> >>> +entry:
> >>> +  %this.addr = alloca %class.A*, align 8
> >>> +  store %class.A* %this, %class.A** %this.addr, align 8
> >>> +  call void @llvm.dbg.declare(metadata !{%class.A** %this.addr}, metadata !39), !dbg !41
> >>> +  %this1 = load %class.A** %this.addr
> >>> +  call void @_ZN1AC2Ev(%class.A* %this1) #1, !dbg !42
> >>> +  ret void, !dbg !42
> >>> +}
> >>> +
> >>> +declare i32 @_ZN1A6getFooEv(%class.A*)
> >>> +
> >>> +; Function Attrs: nounwind readnone
> >>> +declare void @llvm.dbg.declare(metadata, metadata) #4
> >>> +
> >>> +; Function Attrs: inlinehint nounwind
> >>> +define linkonce_odr void @_ZN1AC2Ev(%class.A* %this) unnamed_addr #2 align 2 {
> >>> +entry:
> >>> +  %this.addr = alloca %class.A*, align 8
> >>> +  store %class.A* %this, %class.A** %this.addr, align 8
> >>> +  call void @llvm.dbg.declare(metadata !{%class.A** %this.addr}, metadata !44), !dbg !45
> >>> +  %this1 = load %class.A** %this.addr
> >>> +  %0 = bitcast %class.A* %this1 to i8***, !dbg !46
> >>> +  store i8** getelementptr inbounds ([4 x i8*]* @_ZTV1A, i64 0, i64 2), i8*** %0, !dbg !46
> >>> +  ret void, !dbg !46
> >>> +}
> >>> +
> >>> +attributes #0 = { nounwind }
> >>> +attributes #1 = { nounwind }
> >>> +attributes #2 = { inlinehint nounwind }
> >>> +attributes #4 = { nounwind readnone }
> >>> +
> >>> +!llvm.dbg.cu <http://llvm.dbg.cu/> = !{!0}
> >>> +!llvm.module.flags = !{!35, !36}
> >>> +!llvm.ident = !{!37}
> >>> +
> >>> +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !26, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/<unknown>] [DW_LANG_C_plus_plus]
> >>> +!1 = metadata !{metadata !"<unknown>", metadata !""}
> >>> +!2 = metadata !{i32 0}
> >>> +!3 = metadata !{metadata !4}
> >>> +!4 = metadata !{i32 786434, metadata !5, null, metadata !"A", i32 2, i64 64, i64 64, i32 0, i32 0, null, metadata !6, i32 0, metadata !"_ZTS1A", null, metadata !"_ZTS1A"} ; [ DW_TAG_class_type ] [A] [line 2, size 64, align 64, offset 0] [def] [from ]
> >>> +!5 = metadata !{metadata !"./ab.h", metadata !""}
> >>> +!6 = metadata !{metadata !7, metadata !14, metadata !19}
> >>> +!7 = metadata !{i32 786445, metadata !5, metadata !8, metadata !"_vptr$A", i32 0, i64 64, i64 0, i64 0, i32 64, metadata !9} ; [ DW_TAG_member ] [_vptr$A] [line 0, size 64, align 0, offset 0] [artificial] [from ]
> >>> +!8 = metadata !{i32 786473, metadata !5}          ; [ DW_TAG_file_type ] [/./ab.h]
> >>> +!9 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 0, offset 0] [from __vtbl_ptr_type]
> >>> +!10 = metadata !{i32 786447, null, null, metadata !"__vtbl_ptr_type", i32 0, i64 64, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_pointer_type ] [__vtbl_ptr_type] [line 0, size 64, align 0, offset 0] [from ]
> >>> +!11 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!12 = metadata !{metadata !13}
> >>> +!13 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
> >>> +!14 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"setFoo", metadata !"setFoo", metadata !"_ZN1A6setFooEv", i32 4, metadata !15, i1 false, i1 false, i32 1, i32 0, metadata !"_ZTS1A", i32 256, i1 false, null, null, i32 0, metadata !18, i32 4} ; [ DW_TAG_subprogram ] [line 4] [setFoo]
> >>> +!15 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !16, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!16 = metadata !{null, metadata !17}
> >>> +!17 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1A]
> >>> +!18 = metadata !{i32 786468}
> >>> +!19 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"getFoo", metadata !"getFoo", metadata !"_ZN1A6getFooEv", i32 5, metadata !20, i1 false, i1 false, i32 1, i32 1, metadata !"_ZTS1A", i32 256, i1 false, null, null, i32 0, metadata !25, i32 5} ; [ DW_TAG_subprogram ] [line 5] [getFoo]
> >>> +!20 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !21, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!21 = metadata !{metadata !22, metadata !17}
> >>> +!22 = metadata !{i32 786470, null, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, metadata !23} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from foo_t]
> >>> +!23 = metadata !{i32 786454, metadata !24, null, metadata !"foo_t", i32 1, i64 0, i64 0, i64 0, i32 0, metadata !13} ; [ DW_TAG_typedef ] [foo_t] [line 1, size 0, align 0, offset 0] [from int]
> >>> +!24 = metadata !{metadata !"a.cpp", metadata !""}
> >>> +!25 = metadata !{i32 786468}
> >>> +!26 = metadata !{metadata !27, metadata !31, metadata !34}
> >>> +!27 = metadata !{i32 786478, metadata !24, metadata !28, metadata !"bar", metadata !"bar", metadata !"_Z3barv", i32 2, metadata !29, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 ()* @_Z3barv, null, null, metadata !2, i32 2} ; [ DW_TAG_subprogram ] [line 2] [def] [bar]
> >>> +!28 = metadata !{i32 786473, metadata !24}        ; [ DW_TAG_file_type ] [/a.cpp]
> >>> +!29 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !30, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!30 = metadata !{metadata !23}
> >>> +!31 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"A", metadata !"A", metadata !"_ZN1AC1Ev", i32 2, metadata !15, i1 false, i1 true, i32 0, i32 0, null, i32 320, i1 false, void (%class.A*)* @_ZN1AC1Ev, null, metadata !32, metadata !2, i32 2} ; [ DW_TAG_subprogram ] [line 2] [def] [A]
> >>> +!32 = metadata !{i32 786478, null, metadata !"_ZTS1A", metadata !"A", metadata !"A", metadata !"", i32 0, metadata !15, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null, i32 0, metadata !33, i32 0} ; [ DW_TAG_subprogram ] [line 0] [A]
> >>> +!33 = metadata !{i32 786468}
> >>> +!34 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"A", metadata !"A", metadata !"_ZN1AC2Ev", i32 2, metadata !15, i1 false, i1 true, i32 0, i32 0, null, i32 320, i1 false, void (%class.A*)* @_ZN1AC2Ev, null, metadata !32, metadata !2, i32 2} ; [ DW_TAG_subprogram ] [line 2] [def] [A]
> >>> +!35 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
> >>> +!36 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
> >>> +!37 = metadata !{metadata !"clang version 3.5 "}
> >>> +!38 = metadata !{i32 3, i32 0, metadata !27, null}
> >>> +!39 = metadata !{i32 786689, metadata !31, metadata !"this", null, i32 16777216, metadata !40, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
> >>> +!40 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS1A]
> >>> +!41 = metadata !{i32 0, i32 0, metadata !31, null}
> >>> +!42 = metadata !{i32 2, i32 0, metadata !43, null}
> >>> +!43 = metadata !{i32 786443, metadata !5, metadata !31} ; [ DW_TAG_lexical_block ] [/./ab.h]
> >>> +!44 = metadata !{i32 786689, metadata !34, metadata !"this", null, i32 16777216, metadata !40, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
> >>> +!45 = metadata !{i32 0, i32 0, metadata !34, null}
> >>> +!46 = metadata !{i32 2, i32 0, metadata !34, null}
> >>>
> >>> Added: llvm/trunk/test/Linker/type-unique-simple2-b.ll
> >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-simple2-b.ll?rev=199536&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-simple2-b.ll?rev=199536&view=auto>
> >>> ==============================================================================
> >>> --- llvm/trunk/test/Linker/type-unique-simple2-b.ll (added)
> >>> +++ llvm/trunk/test/Linker/type-unique-simple2-b.ll Fri Jan 17 20:12:00 2014
> >>> @@ -0,0 +1,88 @@
> >>> +; RUN: true
> >>> +; This file belongs to type-unique-simple2-a.ll.
> >>> +;
> >>> +; $ cat b.cpp
> >>> +; #include "ab.h"
> >>> +; void A::setFoo() {}
> >>> +; const
> >>> +; foo_t A::getFoo() { return 1; }
> >>> +; ModuleID = 'b.cpp'
> >>> +; target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
> >>> +; target triple = "x86_64-apple-macosx10.9.0"
> >>> +
> >>> +%class.A = type { i32 (...)** }
> >>> +
> >>> + at _ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*), i8* bitcast (void (%class.A*)* @_ZN1A6setFooEv to i8*), i8* bitcast (i32 (%class.A*)* @_ZN1A6getFooEv to i8*)]
> >>> + at _ZTVN10__cxxabiv117__class_type_infoE = external global i8*
> >>> + at _ZTS1A = constant [3 x i8] c"1A\00"
> >>> + at _ZTI1A = unnamed_addr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8]* @_ZTS1A, i32 0, i32 0) }
> >>> +
> >>> +; Function Attrs: nounwind
> >>> +define void @_ZN1A6setFooEv(%class.A* %this) unnamed_addr #0 align 2 {
> >>> +entry:
> >>> +  %this.addr = alloca %class.A*, align 8
> >>> +  store %class.A* %this, %class.A** %this.addr, align 8
> >>> +  call void @llvm.dbg.declare(metadata !{%class.A** %this.addr}, metadata !32), !dbg !34
> >>> +  %this1 = load %class.A** %this.addr
> >>> +  ret void, !dbg !35
> >>> +}
> >>> +
> >>> +; Function Attrs: nounwind readnone
> >>> +declare void @llvm.dbg.declare(metadata, metadata) #1
> >>> +
> >>> +; Function Attrs: nounwind
> >>> +define i32 @_ZN1A6getFooEv(%class.A* %this) unnamed_addr #0 align 2 {
> >>> +entry:
> >>> +  %this.addr = alloca %class.A*, align 8
> >>> +  store %class.A* %this, %class.A** %this.addr, align 8
> >>> +  call void @llvm.dbg.declare(metadata !{%class.A** %this.addr}, metadata !36), !dbg !37
> >>> +  %this1 = load %class.A** %this.addr
> >>> +  ret i32 1, !dbg !38
> >>> +}
> >>> +
> >>> +attributes #0 = { nounwind }
> >>> +attributes #1 = { nounwind readnone }
> >>> +
> >>> +!llvm.dbg.cu <http://llvm.dbg.cu/> = !{!0}
> >>> +!llvm.module.flags = !{!29, !30}
> >>> +!llvm.ident = !{!31}
> >>> +
> >>> +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !25, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/<unknown>] [DW_LANG_C_plus_plus]
> >>> +!1 = metadata !{metadata !"<unknown>", metadata !""}
> >>> +!2 = metadata !{i32 0}
> >>> +!3 = metadata !{metadata !4}
> >>> +!4 = metadata !{i32 786434, metadata !5, null, metadata !"A", i32 2, i64 64, i64 64, i32 0, i32 0, null, metadata !6, i32 0, metadata !"_ZTS1A", null, metadata !"_ZTS1A"} ; [ DW_TAG_class_type ] [A] [line 2, size 64, align 64, offset 0] [def] [from ]
> >>> +!5 = metadata !{metadata !"./ab.h", metadata !""}
> >>> +!6 = metadata !{metadata !7, metadata !14, metadata !19}
> >>> +!7 = metadata !{i32 786445, metadata !5, metadata !8, metadata !"_vptr$A", i32 0, i64 64, i64 0, i64 0, i32 64, metadata !9} ; [ DW_TAG_member ] [_vptr$A] [line 0, size 64, align 0, offset 0] [artificial] [from ]
> >>> +!8 = metadata !{i32 786473, metadata !5}          ; [ DW_TAG_file_type ] [/./ab.h]
> >>> +!9 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 0, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 0, offset 0] [from __vtbl_ptr_type]
> >>> +!10 = metadata !{i32 786447, null, null, metadata !"__vtbl_ptr_type", i32 0, i64 64, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_pointer_type ] [__vtbl_ptr_type] [line 0, size 64, align 0, offset 0] [from ]
> >>> +!11 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!12 = metadata !{metadata !13}
> >>> +!13 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
> >>> +!14 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"setFoo", metadata !"setFoo", metadata !"_ZN1A6setFooEv", i32 4, metadata !15, i1 false, i1 false, i32 1, i32 0, metadata !"_ZTS1A", i32 256, i1 false, null, null, i32 0, metadata !18, i32 4} ; [ DW_TAG_subprogram ] [line 4] [setFoo]
> >>> +!15 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !16, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!16 = metadata !{null, metadata !17}
> >>> +!17 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1A]
> >>> +!18 = metadata !{i32 786468}
> >>> +!19 = metadata !{i32 786478, metadata !5, metadata !"_ZTS1A", metadata !"getFoo", metadata !"getFoo", metadata !"_ZN1A6getFooEv", i32 5, metadata !20, i1 false, i1 false, i32 1, i32 1, metadata !"_ZTS1A", i32 256, i1 false, null, null, i32 0, metadata !24, i32 5} ; [ DW_TAG_subprogram ] [line 5] [getFoo]
> >>> +!20 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !21, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> >>> +!21 = metadata !{metadata !22, metadata !17}
> >>> +!22 = metadata !{i32 786470, null, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, metadata !23} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from foo_t]
> >>> +!23 = metadata !{i32 786454, metadata !5, null, metadata !"foo_t", i32 1, i64 0, i64 0, i64 0, i32 0, metadata !13} ; [ DW_TAG_typedef ] [foo_t] [line 1, size 0, align 0, offset 0] [from int]
> >>> +!24 = metadata !{i32 786468}
> >>> +!25 = metadata !{metadata !26, metadata !28}
> >>> +!26 = metadata !{i32 786478, metadata !27, metadata !"_ZTS1A", metadata !"setFoo", metadata !"setFoo", metadata !"_ZN1A6setFooEv", i32 2, metadata !15, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%class.A*)* @_ZN1A6setFooEv, null, metadata !14, metadata !2, i32 2} ; [ DW_TAG_subprogram ] [line 2] [def] [setFoo]
> >>> +!27 = metadata !{metadata !"b.cpp", metadata !""}
> >>> +!28 = metadata !{i32 786478, metadata !27, metadata !"_ZTS1A", metadata !"getFoo", metadata !"getFoo", metadata !"_ZN1A6getFooEv", i32 4, metadata !20, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (%class.A*)* @_ZN1A6getFooEv, null, metadata !19, metadata !2, i32 4} ; [ DW_TAG_subprogram ] [line 4] [def] [getFoo]
> >>> +!29 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
> >>> +!30 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
> >>> +!31 = metadata !{metadata !"clang version 3.5 "}
> >>> +!32 = metadata !{i32 786689, metadata !26, metadata !"this", null, i32 16777216, metadata !33, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
> >>> +!33 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !"_ZTS1A"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS1A]
> >>> +!34 = metadata !{i32 0, i32 0, metadata !26, null}
> >>> +!35 = metadata !{i32 2, i32 0, metadata !26, null}
> >>> +!36 = metadata !{i32 786689, metadata !28, metadata !"this", null, i32 16777216, metadata !33, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
> >>> +!37 = metadata !{i32 0, i32 0, metadata !28, null}
> >>> +!38 = metadata !{i32 4, i32 0, metadata !28, null}
> >>>
> >>>
> >>> _______________________________________________
> >>> llvm-commits mailing list
> >>> llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>
> >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits <http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits>
> >>>
> >>
> >> _______________________________________________
> >> llvm-commits mailing list
> >> llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>
> >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits <http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits>
> >
> >
> >
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140829/d591fa20/attachment.html>


More information about the llvm-commits mailing list