[cfe-dev] output metadata for extern declared functions?

Lewis Burns lewisurn at gmail.com
Sat Nov 16 12:30:03 PST 2013


I've finally figured out where a function declaration is lazily emitted. 
It is done in the CodeGenModule::GetOrCreateLLVMFunction() function, 
which is in turned called by EmitCall functions. I wrote a function 
which is similar to the CGDebugInfo::EmitFunctionStart() function and 
hooked it into the GetOrCreateLLVMFunction function. It seems to work, 
since it passed all LLVM & Clang regression tests except two.

I'm now having two other questions.

(1) How to add a Clang command line option to control the call to my 
function? The hook-up point in my code is as follows:

llvm::Constant *
CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
                                        llvm::Type *Ty,
                                        GlobalDecl D, bool ForVTable,
                                        llvm::AttributeSet ExtraAttrs) {
   ...
   llvm::Function *F = llvm::Function::Create(FTy,
llvm::Function::ExternalLinkage,
                                              MangledName, &getModule());
   ...
   if (ExtraAttrs.hasAttributes(llvm::AttributeSet::FunctionIndex)) {
     llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeSet::FunctionIndex);
     F->addAttributes(llvm::AttributeSet::FunctionIndex,
                      llvm::AttributeSet::get(VMContext,
llvm::AttributeSet::FunctionIndex,
                                              B));
   }

   // Emit subprogram debug descriptor for this new declaration
   // if "-gg" is given like clang -gg, then call this function
   EmitFunctionDeclaration(D, F); -- hook up line

   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at 
the end
   // of the file.
   llvm::StringMap<GlobalDecl>::iterator DDI = 
DeferredDecls.find(MangledName);
   ...
}

It seems to be very complicated to do this in Clang. I've spent hours 
and still couldn't solve it.

(2) I've run LLVM&Clang regression tests on my code and there are two 
failures. One of them is debug-info-class.cpp (the other is 
debug-info-template-quals.cpp), and the failure message is:

llvm-3.3.src/tools/clang/test/CodeGenCXX/debug-info-class.cpp:45:11: 
error: expected string not found in input
// CHECK: DW_TAG_class_type ] [B]
           ^
<stdin>:230:75: note: scanning from here
!49 = metadata !{i32 786445, metadata !1, metadata !46, metadata 
!"HdrSize", i32 17, i64 0, i64 0, i64 0, i32 4096, metadata !50, i32 52} 
; [ DW_TAG_member ] [HdrSize] [line 17, size 0, align 0, offset 0] 
[static] [from ]
^
<stdin>:231:109: note: possible intended match here
!50 = 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 int]
^
--

However, the generated bitcode assembly does have DW_TAG_class_type ] 
[B]. The related entry is:

!31 = metadata !{i32 786434, metadata !1, null, metadata !"B", i32 11, 
i64 64, i64 64, i32 0, i32 0, null, metadata !32, i32 0, metadata !31, 
null} ; [ DW_TAG_class_type ] [B] [line 11, size 64, align 64, offset 0] 
[from ]

I've attached the entire code to the letter. I'm wondering what is 
going, and how can I solve this?

Thanks very much



On 11/12/2013 03:06 PM, Eric Christopher wrote:
> On Mon, Nov 11, 2013 at 4:13 PM, Lewis Burns <lewisurn at gmail.com> wrote:
>> No, I don't care about those functions that aren't called.
>>
>> Okay, I walked through the EmitCall family of functions of CodeGenFunction,
>> but didn't notice much. I guess that I'll have to trace them through more
>> carefully to see when it is done.
>>
>> My thought is to copy the debug info metadata emission logic used during
>> generating the function prolog to function declarations. Do you think if it
>> works?
>>
> Easiest is looking at getOrCreateFunctionType. You can probably hook
> into EmitCall if you want to emit a debug info declaration for the
> function.
>
> -eric
>
>> Thanks,
>>
>>
>> On 11/12/2013 07:49 AM, David Blaikie wrote:
>>
>> Do you care about generating debug info for declarations of functions that
>> aren't even called? If so, then the approach you're taking will be
>> insufficient (since we won't even emit an IR declaration for such a
>> function)
>>
>> If not, then you might want to take a look at where the IR for the call is
>> constructed (I don't know where this is, but you seem to be gaining some
>> proficiency tracing through Clang/LLVM internals that will serve you well
>> here) and then see how the target of the call is built and passed in to
>> that.
>>
>>
>> On Mon, Nov 11, 2013 at 3:44 PM, Lewis Burns <lewisurn at gmail.com> wrote:
>>> I ran Clang in a debugger and traced how debug info metadata was emitted.
>>> It's a part of code generation of functions.
>>>
>>> I have a question about when the declaration of an extern function is
>>> emitted. For example, I have very simple code:
>>>
>>> extern int convert(unsigned u);
>>>
>>> void foo() {
>>>    int x = convert(0);
>>> }
>>>
>>> The corresponding LLVM code is:
>>>
>>> ...
>>> ; Function Attrs: nounwind uwtable
>>> define void @foo() #0 {
>>> entry:
>>>    %x = alloca i32, align 4
>>>    call void @llvm.dbg.declare(metadata !{i32* %x}, metadata !8), !dbg !10
>>>    %call = call i32 @convert(i32 0), !dbg !10
>>>    store i32 %call, i32* %x, align 4, !dbg !10
>>>    ret void, !dbg !11
>>> }
>>> ...
>>> declare i32 @convert(i32) #2  // when this line is emitted
>>>
>>> My question is where the "declare i32 @convert(i32) #2" line is emitted. I
>>> tried many breakpoints in EmitXXX family of functions in CodeGenModule and
>>> noticed that this piece of code
>>>
>>>    // Ignore declarations, they will be emitted on their first use.
>>>    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
>>>      // Forward declarations are emitted lazily on first use.
>>>      if (!FD->doesThisDeclarationHaveABody()) {
>>>        if (!FD->doesDeclarationForceExternallyVisibleDefinition())
>>>          return;
>>>
>>> causes the postpone of emission of the convert function declaration, but I
>>> couldn't figure out where and when the declaration is emitted. I set a
>>> breakpoint in the CodeGenModule::EmitDeferred() function, but nothing was
>>> done in that function.
>>>
>>> Any help is really appreciated.
>>>
>>>
>>> On 11/09/2013 04:14 PM, David Blaikie wrote:
>>>
>>> For those following this thread a critical detail would be that you want
>>> debug info metadata.
>>>
>>> There's no simple flag for this as we don't attach the function debug info
>>> metadata to every declaration, just to definitions (there's no filtering
>>> step)
>>>
>>> But why do you want this anyway? If you're performing
>>> optimizations/transformations based on debug info metadata, that's not
>>> really the desired approach. Debug info is not meant to affect code
>>> generation.
>>>
>>> On Nov 9, 2013 7:59 AM, "Lewis Burns" <lewisurn at gmail.com> wrote:
>>>> Hi,
>>>>
>>>> I haven't worked on Clang before and have a simple question (supposedly)
>>>> for those who are familiar with metadata and LLVM bitcode generation. Assume
>>>> that I have a function which is declared as extern as the following:
>>>>
>>>> extern int convert(unsigned u);
>>>>
>>>> I want to have Clang generate metadata nodes for it by adding a metadata
>>>> node of subprogram into the list of subprograms defined in the current
>>>> compilation unit. The subprogram metadata node and its associated nodes
>>>> should have the info of the type signature. For example, I get the following
>>>> set of metadata nodes for function
>>>>
>>>> int convert(unsigned u) {return 0;}
>>>>
>>>> !3 = metadata !{metadata !4, metadata !10, metadata !33}
>>>> !4 = metadata !{i32 786478, metadata !1, metadata !5, metadata
>>>> !"convert", metadata !"convert", metadata !"", i32 23, metadata !6, i1
>>>> false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32)* @convert,
>>>> null, null, metadata !2, i32 23} ; [ DW_TAG_subprogram ] [line 23] [def]
>>>> [convert]
>>>> !7 = metadata !{metadata !8, metadata !9}
>>>> !8 = 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]
>>>> !9 = metadata !{i32 786468, null, null, metadata !"unsigned int", i32 0,
>>>> i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] [unsigned int]
>>>> [line 0, size 32, align 32, offset 0, enc DW_ATE_unsigned]
>>>>
>>>> which allows me to extract the source-level type signature for the
>>>> function by using LLVM debug info APIs. I'd like to get the source-level
>>>> type signature of the extern declared function, but Clang does not produce
>>>> metadata for it.
>>>>
>>>> By looking at the Clang AST for the extern declared function
>>>>
>>>> |-FunctionDecl 0x70598c0 <line:23:1, col:30> convert 'int (unsigned int)'
>>>> extern
>>>> | |-ParmVarDecl 0x7059800 <col:20, col:29> u 'unsigned int'
>>>>
>>>> I know that Clang has the information I need, and I just need to turn off
>>>> or remove the filter that ignores functions whose bodies are not available
>>>> during metadata node or/and code generation. Are there simple switches that
>>>> do this? If not, can anyone please explain how to do it by pointing me to
>>>> the right code snippets?
>>>>
>>>> Thanks very much,
>>>>
>>>>
>>>> --
>>>> Lewis
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-dev mailing list
>>>> cfe-dev at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>>>
>>> --
>>> Lewis
>>
>>
>> --
>> Lewis
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>

-- 
Lewis

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131116/abb8d33b/attachment.html>
-------------- next part --------------
; ModuleID = 'debug-info-class.cpp'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

%struct.foo = type opaque
%class.bar = type opaque
%union.baz = type opaque
%class.B = type { i32 (...)** }
%struct.A = type { i32, i32 }

@_ZTV1B = external unnamed_addr constant [4 x i8*]

; Function Attrs: nounwind uwtable
define void @_Z4funcP3foo(%struct.foo* %f) #0 {
entry:
  %f.addr = alloca %struct.foo*, align 8
  store %struct.foo* %f, %struct.foo** %f.addr, align 8
  call void @llvm.dbg.declare(metadata !{%struct.foo** %f.addr}, metadata !57), !dbg !58
  ret void, !dbg !59
}

; Function Attrs: nounwind readnone
declare void @llvm.dbg.declare(metadata, metadata) #1

; Function Attrs: nounwind uwtable
define void @_Z4funcP3bar(%class.bar* %f) #0 {
entry:
  %f.addr = alloca %class.bar*, align 8
  store %class.bar* %f, %class.bar** %f.addr, align 8
  call void @llvm.dbg.declare(metadata !{%class.bar** %f.addr}, metadata !60), !dbg !61
  ret void, !dbg !62
}

; Function Attrs: nounwind uwtable
define void @_Z4funcP3baz(%union.baz* %f) #0 {
entry:
  %f.addr = alloca %union.baz*, align 8
  store %union.baz* %f, %union.baz** %f.addr, align 8
  call void @llvm.dbg.declare(metadata !{%union.baz** %f.addr}, metadata !63), !dbg !64
  ret void, !dbg !65
}

; Function Attrs: uwtable
define i32 @main(i32 %argc, i8** %argv) #2 {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  %b = alloca %class.B, align 8
  %a = alloca %struct.A, align 4
  %exn.slot = alloca i8*
  %ehselector.slot = alloca i32
  %cleanup.dest.slot = alloca i32
  store i32 0, i32* %retval
  store i32 %argc, i32* %argc.addr, align 4
  call void @llvm.dbg.declare(metadata !{i32* %argc.addr}, metadata !66), !dbg !67
  store i8** %argv, i8*** %argv.addr, align 8
  call void @llvm.dbg.declare(metadata !{i8*** %argv.addr}, metadata !68), !dbg !67
  call void @llvm.dbg.declare(metadata !{%class.B* %b}, metadata !69), !dbg !70
  call void @_ZN1BC1Ev(%class.B* %b) #6, !dbg !70
  %0 = load i32* %argc.addr, align 4, !dbg !71
  %tobool = icmp ne i32 %0, 0, !dbg !71
  br i1 %tobool, label %if.then, label %if.end, !dbg !71

if.then:                                          ; preds = %entry
  call void @llvm.dbg.declare(metadata !{%struct.A* %a}, metadata !72), !dbg !74
  invoke void @_ZN1AC1Ev(%struct.A* %a)
          to label %invoke.cont unwind label %lpad, !dbg !74

invoke.cont:                                      ; preds = %if.then
  br label %if.end, !dbg !75

lpad:                                             ; preds = %if.then
  %1 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
          cleanup, !dbg !74
  %2 = extractvalue { i8*, i32 } %1, 0, !dbg !74
  store i8* %2, i8** %exn.slot, !dbg !74
  %3 = extractvalue { i8*, i32 } %1, 1, !dbg !74
  store i32 %3, i32* %ehselector.slot, !dbg !74
  invoke void @_ZN1BD1Ev(%class.B* %b)
          to label %invoke.cont1 unwind label %terminate.lpad, !dbg !76

if.end:                                           ; preds = %invoke.cont, %entry
  store i32 0, i32* %retval, !dbg !77
  store i32 1, i32* %cleanup.dest.slot
  call void @_ZN1BD1Ev(%class.B* %b), !dbg !77
  %4 = load i32* %retval, !dbg !76
  ret i32 %4, !dbg !76

invoke.cont1:                                     ; preds = %lpad
  br label %eh.resume, !dbg !76

eh.resume:                                        ; preds = %invoke.cont1
  %exn = load i8** %exn.slot, !dbg !76
  %sel = load i32* %ehselector.slot, !dbg !76
  %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0, !dbg !76
  %lpad.val2 = insertvalue { i8*, i32 } %lpad.val, i32 %sel, 1, !dbg !76
  resume { i8*, i32 } %lpad.val2, !dbg !76

terminate.lpad:                                   ; preds = %lpad
  %5 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
          catch i8* null, !dbg !76
  %6 = extractvalue { i8*, i32 } %5, 0, !dbg !76
  call void @__clang_call_terminate(i8* %6) #7, !dbg !76
  unreachable, !dbg !76
}

; Function Attrs: inlinehint nounwind uwtable
define linkonce_odr void @_ZN1BC1Ev(%class.B* %this) unnamed_addr #3 align 2 {
entry:
  %this.addr = alloca %class.B*, align 8
  store %class.B* %this, %class.B** %this.addr, align 8
  call void @llvm.dbg.declare(metadata !{%class.B** %this.addr}, metadata !78), !dbg !80
  %this1 = load %class.B** %this.addr
  call void @_ZN1BC2Ev(%class.B* %this1) #6, !dbg !80
  ret void, !dbg !80
}

; Function Attrs: uwtable
define linkonce_odr void @_ZN1AC1Ev(%struct.A* %this) unnamed_addr #2 align 2 {
entry:
  %this.addr = alloca %struct.A*, align 8
  store %struct.A* %this, %struct.A** %this.addr, align 8
  call void @llvm.dbg.declare(metadata !{%struct.A** %this.addr}, metadata !81), !dbg !83
  %this1 = load %struct.A** %this.addr
  call void @_ZN1AC2Ev(%struct.A* %this1), !dbg !84
  ret void, !dbg !84
}

declare i32 @__gxx_personality_v0(...)

declare void @_ZN1BD1Ev(%class.B*) #4

; Function Attrs: noinline noreturn nounwind
define linkonce_odr hidden void @__clang_call_terminate(i8*) #5 {
  %2 = call i8* @__cxa_begin_catch(i8* %0) #6
  call void @_ZSt9terminatev() #7
  unreachable
}

declare i8* @__cxa_begin_catch(i8*)

declare void @_ZSt9terminatev()

; Function Attrs: nounwind uwtable
define linkonce_odr void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr #0 align 2 {
entry:
  %this.addr = alloca %struct.A*, align 8
  %x = alloca i32, align 4
  store %struct.A* %this, %struct.A** %this.addr, align 8
  call void @llvm.dbg.declare(metadata !{%struct.A** %this.addr}, metadata !85), !dbg !86
  %this1 = load %struct.A** %this.addr
  call void @llvm.dbg.declare(metadata !{i32* %x}, metadata !87), !dbg !89
  store i32 1, i32* %x, align 4, !dbg !89
  ret void, !dbg !90
}

; Function Attrs: inlinehint nounwind uwtable
define linkonce_odr void @_ZN1BC2Ev(%class.B* %this) unnamed_addr #3 align 2 {
entry:
  %this.addr = alloca %class.B*, align 8
  store %class.B* %this, %class.B** %this.addr, align 8
  call void @llvm.dbg.declare(metadata !{%class.B** %this.addr}, metadata !91), !dbg !92
  %this1 = load %class.B** %this.addr
  %0 = bitcast %class.B* %this1 to i8***, !dbg !92
  store i8** getelementptr inbounds ([4 x i8*]* @_ZTV1B, i64 0, i64 2), i8*** %0, !dbg !92
  ret void, !dbg !92
}

attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind readnone }
attributes #2 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { inlinehint nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #4 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #5 = { noinline noreturn nounwind }
attributes #6 = { nounwind }
attributes #7 = { noreturn nounwind }

!llvm.dbg.cu = !{!0}

!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.3 (tags/RELEASE_33/final)", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/lu/packages/llvm-git/llvm-3.3.src/tools/clang/test/CodeGenCXX/debug-info-class.cpp] [DW_LANG_C_plus_plus]
!1 = metadata !{metadata !"debug-info-class.cpp", metadata !"/home/lu/packages/llvm-git/llvm-3.3.src/tools/clang/test/CodeGenCXX"}
!2 = metadata !{i32 0}
!3 = metadata !{metadata !4, metadata !10, metadata !15, metadata !20, metadata !27, metadata !42, metadata !54, metadata !55, metadata !56}
!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"func", metadata !"func", metadata !"_Z4funcP3foo", i32 2, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%struct.foo*)* @_Z4funcP3foo, null, null, metadata !2, i32 2} ; [ DW_TAG_subprogram ] [line 2] [def] [func]
!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/home/lu/packages/llvm-git/llvm-3.3.src/tools/clang/test/CodeGenCXX/debug-info-class.cpp]
!6 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!7 = metadata !{null, metadata !8}
!8 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from foo]
!9 = metadata !{i32 786451, metadata !1, null, metadata !"foo", i32 1, i64 0, i64 0, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_structure_type ] [foo] [line 1, size 0, align 0, offset 0] [fwd] [from ]
!10 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"func", metadata !"func", metadata !"_Z4funcP3bar", i32 5, metadata !11, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%class.bar*)* @_Z4funcP3bar, null, null, metadata !2, i32 5} ; [ DW_TAG_subprogram ] [line 5] [def] [func]
!11 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !12, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!12 = metadata !{null, metadata !13}
!13 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from bar]
!14 = metadata !{i32 786434, metadata !1, null, metadata !"bar", i32 4, i64 0, i64 0, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_class_type ] [bar] [line 4, size 0, align 0, offset 0] [fwd] [from ]
!15 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"func", metadata !"func", metadata !"_Z4funcP3baz", i32 8, metadata !16, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%union.baz*)* @_Z4funcP3baz, null, null, metadata !2, i32 8} ; [ DW_TAG_subprogram ] [line 8] [def] [func]
!16 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !17, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!17 = metadata !{null, metadata !18}
!18 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !19} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from baz]
!19 = metadata !{i32 786455, metadata !1, null, metadata !"baz", i32 7, i64 0, i64 0, i32 0, i32 4, null, null, i32 0} ; [ DW_TAG_union_type ] [baz] [line 7, size 0, align 0, offset 0] [fwd] [from ]
!20 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"main", metadata !"main", metadata !"", i32 25, metadata !21, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, i32 (i32, i8**)* @main, null, null, metadata !2, i32 25} ; [ DW_TAG_subprogram ] [line 25] [def] [main]
!21 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !22, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!22 = metadata !{metadata !23, metadata !23, metadata !24}
!23 = 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]
!24 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !25} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
!25 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !26} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from char]
!26 = metadata !{i32 786468, null, null, metadata !"char", i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
!27 = metadata !{i32 786478, metadata !1, null, metadata !"~B", metadata !"~B", metadata !"_ZN1BD1Ev", i32 13, metadata !28, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, void (%class.B*)* @_ZN1BD1Ev, null, metadata !38, metadata !2, i32 13} ; [ DW_TAG_subprogram ] [line 13] [~B]
!28 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !29, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!29 = metadata !{null, metadata !30}
!30 = metadata !{i32 786447, i32 0, i32 0, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !31} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from B]
!31 = metadata !{i32 786434, metadata !1, null, metadata !"B", i32 11, i64 64, i64 64, i32 0, i32 0, null, metadata !32, i32 0, metadata !31, null} ; [ DW_TAG_class_type ] [B] [line 11, size 64, align 64, offset 0] [from ]
!32 = metadata !{metadata !33, metadata !38, metadata !40}
!33 = metadata !{i32 786445, metadata !1, metadata !5, metadata !"_vptr$B", i32 0, i64 64, i64 0, i64 0, i32 64, metadata !34} ; [ DW_TAG_member ] [_vptr$B] [line 0, size 64, align 0, offset 0] [artificial] [from ]
!34 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 0, i64 0, i32 0, metadata !35} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 0, offset 0] [from __vtbl_ptr_type]
!35 = metadata !{i32 786447, null, null, metadata !"__vtbl_ptr_type", i32 0, i64 64, i64 0, i64 0, i32 0, metadata !36} ; [ DW_TAG_pointer_type ] [__vtbl_ptr_type] [line 0, size 64, align 0, offset 0] [from ]
!36 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !37, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!37 = metadata !{metadata !23}
!38 = metadata !{i32 786478, metadata !1, metadata !31, metadata !"~B", metadata !"~B", metadata !"", i32 13, metadata !28, i1 false, i1 false, i32 1, i32 0, metadata !31, i32 256, i1 false, null, null, i32 0, metadata !39, i32 13} ; [ DW_TAG_subprogram ] [line 13] [~B]
!39 = metadata !{i32 786468}
!40 = metadata !{i32 786478, metadata !1, metadata !31, metadata !"B", metadata !"B", metadata !"", i32 11, metadata !28, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null, i32 0, metadata !41, i32 11} ; [ DW_TAG_subprogram ] [line 11] [B]
!41 = metadata !{i32 786468}
!42 = metadata !{i32 786478, metadata !1, null, metadata !"A", metadata !"A", metadata !"_ZN1AC1Ev", i32 19, metadata !43, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%struct.A*)* @_ZN1AC1Ev, null, metadata !52, metadata !2, i32 19} ; [ DW_TAG_subprogram ] [line 19] [def] [A]
!43 = metadata !{i32 786453, i32 0, i32 0, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !44, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
!44 = metadata !{null, metadata !45}
!45 = metadata !{i32 786447, i32 0, i32 0, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !46} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from A]
!46 = metadata !{i32 786451, metadata !1, null, metadata !"A", i32 15, i64 64, i64 32, i32 0, i32 0, null, metadata !47, i32 0, null, null} ; [ DW_TAG_structure_type ] [A] [line 15, size 64, align 32, offset 0] [from ]
!47 = metadata !{metadata !48, metadata !49, metadata !51, metadata !52}
!48 = metadata !{i32 786445, metadata !1, metadata !46, metadata !"one", i32 16, i64 32, i64 32, i64 0, i32 0, metadata !23} ; [ DW_TAG_member ] [one] [line 16, size 32, align 32, offset 0] [from int]
!49 = metadata !{i32 786445, metadata !1, metadata !46, metadata !"HdrSize", i32 17, i64 0, i64 0, i64 0, i32 4096, metadata !50, i32 52} ; [ DW_TAG_member ] [HdrSize] [line 17, size 0, align 0, offset 0] [static] [from ]
!50 = 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 int]
!51 = metadata !{i32 786445, metadata !1, metadata !46, metadata !"two", i32 18, i64 32, i64 32, i64 32, i32 0, metadata !23} ; [ DW_TAG_member ] [two] [line 18, size 32, align 32, offset 32] [from int]
!52 = metadata !{i32 786478, metadata !1, metadata !46, metadata !"A", metadata !"A", metadata !"", i32 19, metadata !43, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !53, i32 19} ; [ DW_TAG_subprogram ] [line 19] [A]
!53 = metadata !{i32 786468}
!54 = metadata !{i32 786478, metadata !1, null, metadata !"A", metadata !"A", metadata !"_ZN1AC2Ev", i32 19, metadata !43, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (%struct.A*)* @_ZN1AC2Ev, null, metadata !52, metadata !2, i32 19} ; [ DW_TAG_subprogram ] [line 19] [def] [A]
!55 = metadata !{i32 786478, metadata !1, null, metadata !"B", metadata !"B", metadata !"_ZN1BC1Ev", i32 11, metadata !28, i1 false, i1 true, i32 0, i32 0, null, i32 320, i1 false, void (%class.B*)* @_ZN1BC1Ev, null, metadata !40, metadata !2, i32 11} ; [ DW_TAG_subprogram ] [line 11] [def] [B]
!56 = metadata !{i32 786478, metadata !1, null, metadata !"B", metadata !"B", metadata !"_ZN1BC2Ev", i32 11, metadata !28, i1 false, i1 true, i32 0, i32 0, null, i32 320, i1 false, void (%class.B*)* @_ZN1BC2Ev, null, metadata !40, metadata !2, i32 11} ; [ DW_TAG_subprogram ] [line 11] [def] [B]
!57 = metadata !{i32 786689, metadata !4, metadata !"f", metadata !5, i32 16777218, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [f] [line 2]
!58 = metadata !{i32 2, i32 0, metadata !4, null}
!59 = metadata !{i32 3, i32 0, metadata !4, null}
!60 = metadata !{i32 786689, metadata !10, metadata !"f", metadata !5, i32 16777221, metadata !13, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [f] [line 5]
!61 = metadata !{i32 5, i32 0, metadata !10, null}
!62 = metadata !{i32 6, i32 0, metadata !10, null}
!63 = metadata !{i32 786689, metadata !15, metadata !"f", metadata !5, i32 16777224, metadata !18, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [f] [line 8]
!64 = metadata !{i32 8, i32 0, metadata !15, null}
!65 = metadata !{i32 9, i32 0, metadata !15, null}
!66 = metadata !{i32 786689, metadata !20, metadata !"argc", metadata !5, i32 16777241, metadata !23, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [argc] [line 25]
!67 = metadata !{i32 25, i32 0, metadata !20, null}
!68 = metadata !{i32 786689, metadata !20, metadata !"argv", metadata !5, i32 33554457, metadata !24, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [argv] [line 25]
!69 = metadata !{i32 786688, metadata !20, metadata !"b", metadata !5, i32 26, metadata !31, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [b] [line 26]
!70 = metadata !{i32 26, i32 0, metadata !20, null}
!71 = metadata !{i32 27, i32 0, metadata !20, null}
!72 = metadata !{i32 786688, metadata !73, metadata !"a", metadata !5, i32 28, metadata !46, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [a] [line 28]
!73 = metadata !{i32 786443, metadata !1, metadata !20, i32 27, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/home/lu/packages/llvm-git/llvm-3.3.src/tools/clang/test/CodeGenCXX/debug-info-class.cpp]
!74 = metadata !{i32 28, i32 0, metadata !73, null}
!75 = metadata !{i32 29, i32 0, metadata !73, null}
!76 = metadata !{i32 31, i32 0, metadata !20, null}
!77 = metadata !{i32 30, i32 0, metadata !20, null}
!78 = metadata !{i32 786689, metadata !55, metadata !"this", metadata !5, i32 16777227, metadata !79, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 11]
!79 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !31} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from B]
!80 = metadata !{i32 11, i32 0, metadata !55, null}
!81 = metadata !{i32 786689, metadata !42, metadata !"this", metadata !5, i32 16777235, metadata !82, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 19]
!82 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !46} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from A]
!83 = metadata !{i32 19, i32 0, metadata !42, null}
!84 = metadata !{i32 21, i32 0, metadata !42, null}
!85 = metadata !{i32 786689, metadata !54, metadata !"this", metadata !5, i32 16777235, metadata !82, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 19]
!86 = metadata !{i32 19, i32 0, metadata !54, null}
!87 = metadata !{i32 786688, metadata !88, metadata !"x", metadata !5, i32 20, metadata !23, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [x] [line 20]
!88 = metadata !{i32 786443, metadata !1, metadata !54, i32 19, i32 0, i32 1} ; [ DW_TAG_lexical_block ] [/home/lu/packages/llvm-git/llvm-3.3.src/tools/clang/test/CodeGenCXX/debug-info-class.cpp]
!89 = metadata !{i32 20, i32 0, metadata !88, null}
!90 = metadata !{i32 21, i32 0, metadata !54, null}
!91 = metadata !{i32 786689, metadata !56, metadata !"this", metadata !5, i32 16777227, metadata !79, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 11]
!92 = metadata !{i32 11, i32 0, metadata !56, null}


More information about the cfe-dev mailing list