-
-
Save ewokhias/3ec3eb19d5d3a7c1cba5ce58e5040d8c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp | |
index ac1a133..24facd9 100644 | |
--- a/lib/CodeGen/CodeGenFunction.cpp | |
+++ b/lib/CodeGen/CodeGenFunction.cpp | |
@@ -1158,9 +1158,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, | |
PGO.assignRegionCounters(GD, CurFn); | |
if (isa<CXXDestructorDecl>(FD)) | |
EmitDestructorBody(Args); | |
- else if (isa<CXXConstructorDecl>(FD)) | |
- EmitConstructorBody(Args); | |
- else if (getLangOpts().CUDA && | |
+ else if (isa<CXXConstructorDecl>(FD)) { | |
+ EmitConstructorBody(Args); | |
+ llvm::MDNode* MetadataNode =llvm::MDNode::get(Fn->getContext(), llvm::MDString::get(Fn->getContext(), "constructor")); | |
+ Fn->setMetadata("constructor_mark", MetadataNode); | |
+ } else if (getLangOpts().CUDA && | |
!getLangOpts().CUDAIsDevice && | |
FD->hasAttr<CUDAGlobalAttr>()) | |
CGM.getCUDARuntime().emitDeviceStub(*this, Args); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ../../llvm/build/debug/bin/llc test.ll | |
inlinable function call in a function with debug info must have a !dbg location | |
call void @_ZN12MyFunnyClassC2EvCloned(%struct.MyFunnyClass* %0) | |
../../llvm/build/debug/bin/llc: test.ll: error: input module is broken! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "llvm/Pass.h" | |
#include "llvm/IR/Function.h" | |
#include "llvm/IR/Instructions.h" | |
#include "llvm/IR/LegacyPassManager.h" | |
#include "llvm/Transforms/IPO/PassManagerBuilder.h" | |
#include <llvm/IR/Operator.h> | |
#include <llvm/IR/Module.h> | |
#include "llvm/IR/IRBuilder.h" | |
#include <llvm/Support/raw_os_ostream.h> | |
#include "llvm/Support/RandomNumberGenerator.h" | |
#include "llvm/Transforms/Utils/Cloning.h" | |
using namespace llvm; | |
namespace { | |
struct SkeletonPass : public FunctionPass { | |
static char ID; | |
SkeletonPass() : FunctionPass(ID) {} | |
virtual bool runOnFunction(Function &F) { | |
if (F.getMetadata("constructor_mark")) { | |
Module *M = F.getParent(); | |
const llvm::FunctionType *OldFTy = F.getFunctionType(); | |
std::vector<Type *> Params(OldFTy->param_begin(), OldFTy->param_end()); | |
FunctionType *NewFTy = FunctionType::get(F.getReturnType(), ArrayRef<Type *>(Params), | |
OldFTy->isVarArg()); | |
ValueToValueMapTy Map; | |
ClonedCodeInfo *CI; | |
Function *NF = Function::Create(NewFTy, F.getLinkage(), F.getName() + "Cloned", F.getParent()); | |
SmallVector<ReturnInst *, 8> Returns; | |
Function::arg_iterator DestI = NF->arg_begin(); | |
for (const Argument &I : F.args()) { | |
DestI->setName(I.getName()); | |
Map[&I] = &*DestI++; | |
} | |
CloneFunctionInto(NF, &F, Map, true, Returns, "Cloned"); | |
NF->setMetadata("constructor_mark", NULL); | |
errs() << "Cloned Function " << F.getName() << ". New name is " << NF->getName() << "\n"; | |
replaceCallSites(&F, NF); | |
errs() << "Call sites replaced\n"; | |
return true; | |
} | |
return false; | |
} | |
void replaceCallSites(Function *Old, Function *New) { | |
Module *Module = Old->getParent(); | |
while (!Old->use_empty()) { | |
llvm::CallSite CS(Old->user_back()); | |
llvm::Instruction *Call = CS.getInstruction(); | |
llvm::Function *CallingF = Call->getParent()->getParent(); | |
std::vector<llvm::Value *> Args; | |
Args.reserve(CS.arg_size()); | |
llvm::CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); | |
for (unsigned i = 0, e = Old->getFunctionType()->getNumParams(); i != e; ++i, ++AI) { | |
llvm::Value *v = *AI; | |
Args.push_back(v); | |
} | |
llvm::Instruction *Before = Call; | |
if (llvm::InvokeInst *II = llvm::dyn_cast<llvm::InvokeInst>(Call)) { | |
llvm::InvokeInst *Invoke; | |
Invoke = llvm::InvokeInst::Create(New, II->getNormalDest(), II->getUnwindDest(), | |
ArrayRef<Value *>(Args), "", | |
Before); | |
Invoke->setCallingConv(CS.getCallingConv()); | |
} else { | |
CallInst *CallInst; | |
CallInst = CallInst::Create(New, ArrayRef<Value *>(Args), "", Before); | |
CallInst->setCallingConv(CS.getCallingConv()); | |
if (CallInst->isTailCall()) { | |
CallInst->setTailCall(); | |
} | |
} | |
errs() << "Unlinking call " << Call->getName() << "\n"; | |
Call->eraseFromParent(); | |
} | |
} | |
}; | |
} | |
char SkeletonPass::ID = 0; | |
// Automatically enable the pass. | |
// http://adriansampson.net/blog/clangpass.html | |
static void registerSkeletonPass(const PassManagerBuilder &, | |
legacy::PassManagerBase &PM) { | |
PM.add(new SkeletonPass()); | |
} | |
static RegisterStandardPasses | |
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible, | |
registerSkeletonPass); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct MyFunnyClass { | |
virtual int overridden_function() { | |
return 5; | |
}; | |
virtual void second_function() {}; | |
virtual void third_function() {}; | |
}; | |
int main() { | |
MyFunnyClass *obj = new MyFunnyClass(); | |
return obj->overridden_function(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; ModuleID = 'test.cpp' | |
source_filename = "test.cpp" | |
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | |
target triple = "x86_64-unknown-linux-gnu" | |
%struct.MyFunnyClass = type { i32 (...)** } | |
$_ZN12MyFunnyClassC2Ev = comdat any | |
$_ZN12MyFunnyClass19overridden_functionEv = comdat any | |
$_ZN12MyFunnyClass15second_functionEv = comdat any | |
$_ZN12MyFunnyClass14third_functionEv = comdat any | |
$_ZTV12MyFunnyClass = comdat any | |
$_ZTS12MyFunnyClass = comdat any | |
$_ZTI12MyFunnyClass = comdat any | |
@_ZTV12MyFunnyClass = linkonce_odr unnamed_addr constant { [5 x i8*] } { [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI12MyFunnyClass to i8*), i8* bitcast (i32 (%struct.MyFunnyClass*)* @_ZN12MyFunnyC$ | |
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8* | |
@_ZTS12MyFunnyClass = linkonce_odr constant [15 x i8] c"12MyFunnyClass\00", comdat | |
@_ZTI12MyFunnyClass = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([15 x i8], $ | |
; Function Attrs: noinline norecurse optnone uwtable | |
define i32 @main() #0 !dbg !7 { | |
entry: | |
%retval = alloca i32, align 4 | |
%obj = alloca %struct.MyFunnyClass*, align 8 | |
store i32 0, i32* %retval, align 4 | |
call void @llvm.dbg.declare(metadata %struct.MyFunnyClass** %obj, metadata !11, metadata !26), !dbg !27 | |
%call = call i8* @_Znwm(i64 8) #5, !dbg !28 | |
%0 = bitcast i8* %call to %struct.MyFunnyClass*, !dbg !28 | |
%1 = bitcast %struct.MyFunnyClass* %0 to i8*, !dbg !29 | |
call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 8, i32 8, i1 false), !dbg !29 | |
call void @_ZN12MyFunnyClassC2EvCloned(%struct.MyFunnyClass* %0) | |
store %struct.MyFunnyClass* %0, %struct.MyFunnyClass** %obj, align 8, !dbg !27 | |
%2 = load %struct.MyFunnyClass*, %struct.MyFunnyClass** %obj, align 8, !dbg !30 | |
%3 = bitcast %struct.MyFunnyClass* %2 to i32 (%struct.MyFunnyClass*)***, !dbg !31 | |
%vtable = load i32 (%struct.MyFunnyClass*)**, i32 (%struct.MyFunnyClass*)*** %3, align 8, !dbg !31 | |
%vfn = getelementptr inbounds i32 (%struct.MyFunnyClass*)*, i32 (%struct.MyFunnyClass*)** %vtable, i64 0, !dbg !31 | |
%4 = load i32 (%struct.MyFunnyClass*)*, i32 (%struct.MyFunnyClass*)** %vfn, align 8, !dbg !31 | |
%call1 = call i32 %4(%struct.MyFunnyClass* %2), !dbg !31 | |
ret i32 %call1, !dbg !32 | |
} | |
; Function Attrs: nounwind readnone speculatable | |
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 | |
; Function Attrs: nobuiltin | |
declare noalias i8* @_Znwm(i64) #2 | |
; Function Attrs: argmemonly nounwind | |
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1) #3 | |
; Function Attrs: noinline nounwind optnone uwtable | |
define linkonce_odr void @_ZN12MyFunnyClassC2Ev(%struct.MyFunnyClass* %this) unnamed_addr #4 comdat align 2 !dbg !33 !constructor_mark !35 { | |
entry: | |
%this.addr = alloca %struct.MyFunnyClass*, align 8 | |
store %struct.MyFunnyClass* %this, %struct.MyFunnyClass** %this.addr, align 8 | |
call void @llvm.dbg.declare(metadata %struct.MyFunnyClass** %this.addr, metadata !36, metadata !26), !dbg !37 | |
%this1 = load %struct.MyFunnyClass*, %struct.MyFunnyClass** %this.addr, align 8 | |
%0 = bitcast %struct.MyFunnyClass* %this1 to i32 (...)***, !dbg !38 | |
store i32 (...)** bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTV12MyFunnyClass, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** %0, align 8, !dbg !38 | |
ret void, !dbg !38 | |
} | |
; Function Attrs: noinline nounwind optnone uwtable | |
define linkonce_odr i32 @_ZN12MyFunnyClass19overridden_functionEv(%struct.MyFunnyClass* %this) unnamed_addr #4 comdat align 2 !dbg !39 { | |
entry: | |
%this.addr = alloca %struct.MyFunnyClass*, align 8 | |
store %struct.MyFunnyClass* %this, %struct.MyFunnyClass** %this.addr, align 8 | |
call void @llvm.dbg.declare(metadata %struct.MyFunnyClass** %this.addr, metadata !40, metadata !26), !dbg !41 | |
%this1 = load %struct.MyFunnyClass*, %struct.MyFunnyClass** %this.addr, align 8 | |
ret i32 5, !dbg !42 | |
} | |
; Function Attrs: noinline nounwind optnone uwtable | |
define linkonce_odr void @_ZN12MyFunnyClass15second_functionEv(%struct.MyFunnyClass* %this) unnamed_addr #4 comdat align 2 !dbg !43 { | |
entry: | |
%this.addr = alloca %struct.MyFunnyClass*, align 8 | |
store %struct.MyFunnyClass* %this, %struct.MyFunnyClass** %this.addr, align 8 | |
call void @llvm.dbg.declare(metadata %struct.MyFunnyClass** %this.addr, metadata !44, metadata !26), !dbg !45 | |
%this1 = load %struct.MyFunnyClass*, %struct.MyFunnyClass** %this.addr, align 8 | |
ret void, !dbg !46 | |
} | |
; Function Attrs: noinline nounwind optnone uwtable | |
define linkonce_odr void @_ZN12MyFunnyClass14third_functionEv(%struct.MyFunnyClass* %this) unnamed_addr #4 comdat align 2 !dbg !47 { | |
entry: | |
%this.addr = alloca %struct.MyFunnyClass*, align 8 | |
store %struct.MyFunnyClass* %this, %struct.MyFunnyClass** %this.addr, align 8 | |
call void @llvm.dbg.declare(metadata %struct.MyFunnyClass** %this.addr, metadata !48, metadata !26), !dbg !49 | |
%this1 = load %struct.MyFunnyClass*, %struct.MyFunnyClass** %this.addr, align 8 | |
ret void, !dbg !50 | |
} | |
; Function Attrs: noinline nounwind optnone uwtable | |
define linkonce_odr void @_ZN12MyFunnyClassC2EvCloned(%struct.MyFunnyClass* %this) unnamed_addr #4 align 2 !dbg !51 { | |
entryCloned: | |
%this.addrCloned = alloca %struct.MyFunnyClass*, align 8 | |
store %struct.MyFunnyClass* %this, %struct.MyFunnyClass** %this.addrCloned, align 8 | |
call void @llvm.dbg.declare(metadata %struct.MyFunnyClass** %this.addrCloned, metadata !61, metadata !26), !dbg !63 | |
%this1Cloned = load %struct.MyFunnyClass*, %struct.MyFunnyClass** %this.addrCloned, align 8 | |
%0 = bitcast %struct.MyFunnyClass* %this1Cloned to i32 (...)***, !dbg !64 | |
store i32 (...)** bitcast (i8** getelementptr inbounds ({ [5 x i8*] }, { [5 x i8*] }* @_ZTV12MyFunnyClass, i32 0, inrange i32 0, i32 2) to i32 (...)**), i32 (...)*** %0, align 8, !dbg !64 | |
ret void, !dbg !64 | |
} | |
attributes #0 = { noinline norecurse optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointe$ | |
attributes #1 = { nounwind readnone speculatable } | |
attributes #2 = { nobuiltin "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs$ | |
attributes #3 = { argmemonly nounwind } | |
attributes #4 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer$ | |
attributes #5 = { builtin } | |
!llvm.dbg.cu = !{!0} | |
!llvm.module.flags = !{!3, !4, !5} | |
!llvm.ident = !{!6} | |
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 5.0.0 (https://bitbucket.org/sbspraktikum/clang.git 6adac51dabb51771aade9b29f059f562b7f457c3) (https://bitbucke$ | |
!1 = !DIFile(filename: "test.cpp", directory: "/home/mbernad/playground/cpptest") | |
!2 = !{} | |
!3 = !{i32 2, !"Dwarf Version", i32 4} | |
!4 = !{i32 2, !"Debug Info Version", i32 3} | |
!5 = !{i32 1, !"wchar_size", i32 4} | |
!6 = !{!"clang version 5.0.0 (https://bitbucket.org/sbspraktikum/clang.git 6adac51dabb51771aade9b29f059f562b7f457c3) (https://bitbucket.org/sbspraktikum/llvm.git 470c6959b7834acd5191390007439eaf95b087a6)"} | |
!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 9, type: !8, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) | |
!8 = !DISubroutineType(types: !9) | |
!9 = !{!10} | |
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) | |
!11 = !DILocalVariable(name: "obj", scope: !7, file: !1, line: 10, type: !12) | |
!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) | |
!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyFunnyClass", file: !1, line: 1, size: 64, elements: !14, vtableHolder: !13, identifier: "_ZTS12MyFunnyClass") | |
!14 = !{!15, !18, !22, !25} | |
!15 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$MyFunnyClass", scope: !1, file: !1, baseType: !16, size: 64, flags: DIFlagArtificial) | |
!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) | |
!17 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: !8, size: 64) | |
!18 = !DISubprogram(name: "overridden_function", linkageName: "_ZN12MyFunnyClass19overridden_functionEv", scope: !13, file: !1, line: 2, type: !19, isLocal: false, isDefinition: false, scopeLine: 2, contain$ | |
!19 = !DISubroutineType(types: !20) | |
!20 = !{!10, !21} | |
!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!22 = !DISubprogram(name: "second_function", linkageName: "_ZN12MyFunnyClass15second_functionEv", scope: !13, file: !1, line: 5, type: !23, isLocal: false, isDefinition: false, scopeLine: 5, containingType:$ | |
!23 = !DISubroutineType(types: !24) | |
!24 = !{null, !21} | |
!25 = !DISubprogram(name: "third_function", linkageName: "_ZN12MyFunnyClass14third_functionEv", scope: !13, file: !1, line: 6, type: !23, isLocal: false, isDefinition: false, scopeLine: 6, containingType: !$ | |
!26 = !DIExpression() | |
!27 = !DILocation(line: 10, column: 23, scope: !7) | |
!28 = !DILocation(line: 10, column: 29, scope: !7) | |
!29 = !DILocation(line: 10, column: 33, scope: !7) | |
!30 = !DILocation(line: 11, column: 16, scope: !7) | |
!31 = !DILocation(line: 11, column: 21, scope: !7) | |
!32 = !DILocation(line: 11, column: 9, scope: !7) | |
!33 = distinct !DISubprogram(name: "MyFunnyClass", linkageName: "_ZN12MyFunnyClassC2Ev", scope: !13, file: !1, line: 1, type: !23, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagArtificial |$ | |
!34 = !DISubprogram(name: "MyFunnyClass", scope: !13, type: !23, isLocal: false, isDefinition: false, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false) | |
!35 = !{!"constructor"} | |
!36 = !DILocalVariable(name: "this", arg: 1, scope: !33, type: !12, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!37 = !DILocation(line: 0, scope: !33) | |
!38 = !DILocation(line: 1, column: 8, scope: !33) | |
!39 = distinct !DISubprogram(name: "overridden_function", linkageName: "_ZN12MyFunnyClass19overridden_functionEv", scope: !13, file: !1, line: 2, type: !19, isLocal: false, isDefinition: true, scopeLine: 2,$ | |
!40 = !DILocalVariable(name: "this", arg: 1, scope: !39, type: !12, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!41 = !DILocation(line: 0, scope: !39) | |
!42 = !DILocation(line: 3, column: 17, scope: !39) | |
!43 = distinct !DISubprogram(name: "second_function", linkageName: "_ZN12MyFunnyClass15second_functionEv", scope: !13, file: !1, line: 5, type: !23, isLocal: false, isDefinition: true, scopeLine: 5, flags: $ | |
!44 = !DILocalVariable(name: "this", arg: 1, scope: !43, type: !12, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!45 = !DILocation(line: 0, scope: !43) | |
!46 = !DILocation(line: 5, column: 41, scope: !43) | |
!47 = distinct !DISubprogram(name: "third_function", linkageName: "_ZN12MyFunnyClass14third_functionEv", scope: !13, file: !1, line: 6, type: !23, isLocal: false, isDefinition: true, scopeLine: 6, flags: DI$ | |
!48 = !DILocalVariable(name: "this", arg: 1, scope: !47, type: !12, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!49 = !DILocation(line: 0, scope: !47) | |
!50 = !DILocation(line: 6, column: 40, scope: !47) | |
!51 = distinct !DISubprogram(name: "MyFunnyClass", linkageName: "_ZN12MyFunnyClassC2Ev", scope: !52, file: !1, line: 1, type: !23, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagArtificial |$ | |
!52 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyFunnyClass", file: !1, line: 1, size: 64, elements: !53, vtableHolder: !52, identifier: "_ZTS12MyFunnyClass") | |
!53 = !{!15, !54, !58, !59} | |
!54 = !DISubprogram(name: "overridden_function", linkageName: "_ZN12MyFunnyClass19overridden_functionEv", scope: !52, file: !1, line: 2, type: !55, isLocal: false, isDefinition: false, scopeLine: 2, contain$ | |
!55 = !DISubroutineType(types: !56) | |
!56 = !{!10, !57} | |
!57 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !52, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!58 = !DISubprogram(name: "second_function", linkageName: "_ZN12MyFunnyClass15second_functionEv", scope: !52, file: !1, line: 5, type: !23, isLocal: false, isDefinition: false, scopeLine: 5, containingType:$ | |
!59 = !DISubprogram(name: "third_function", linkageName: "_ZN12MyFunnyClass14third_functionEv", scope: !52, file: !1, line: 6, type: !23, isLocal: false, isDefinition: false, scopeLine: 6, containingType: !$ | |
!60 = !DISubprogram(name: "MyFunnyClass", scope: !52, type: !23, isLocal: false, isDefinition: false, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false) | |
!61 = !DILocalVariable(name: "this", arg: 1, scope: !51, type: !62, flags: DIFlagArtificial | DIFlagObjectPointer) | |
!62 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !52, size: 64) | |
!63 = !DILocation(line: 0, scope: !51) | |
!64 = !DILocation(line: 1, column: 8, scope: !51) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment