Emmiting llvm bytecode from clang: attribute 'byval' for passing objects with a nontrivial destructor to a function

I have C ++ source code that I parse with clang, creating llvm bytecode. From now on I want to process the file myself ... However, I ran into a problem. Consider the following scenario: - I am creating a class with a nontrivial destructor or copy constructor. - I define a function in which an object of this class is passed as a parameter, by value (without a link or pointer).

In the released bytecode, I get a pointer instead. For classes without a destructor, the parameter is annotated as "byval", but this is not the case in this case. As a result, I cannot distinguish whether a parameter is passed by value or indeed by a pointer.

Consider the following example:

The input file is cpass.cpp:

class C {
  public:
  int x;
  ~C() {}
};

void set(C val, int x) {val.x=x;};

void set(C *ptr, int x) {ptr->x=x;}

Compilation Command Line:

clang++ -c cpass.cpp -emit-llvm -o cpass.bc; llvm-dis cpass.bc

Produced output file (cpass.ll):

; ModuleID = 'cpass.bc'
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"
target triple = "x86_64-unknown-linux-gnu"

%class.C = type { i32 }

define void @_Z3set1Ci(%class.C* %val, i32 %x) nounwind {
  %1 = alloca i32, align 4
  store i32 %x, i32* %1, align 4
  %2 = load i32* %1, align 4
  %3 = getelementptr inbounds %class.C* %val, i32 0, i32 0
  store i32 %2, i32* %3, align 4
  ret void
}

define void @_Z3setP1Ci(%class.C* %ptr, i32 %x) nounwind {
  %1 = alloca %class.C*, align 8
  %2 = alloca i32, align 4
  store %class.C* %ptr, %class.C** %1, align 8
  store i32 %x, i32* %2, align 4
  %3 = load i32* %2, align 4
  %4 = load %class.C** %1, align 8
  %5 = getelementptr inbounds %class.C* %4, i32 0, i32 0
  store i32 %3, i32* %5, align 4
  ret void
}

As you can see, the parameters of both functions setlook exactly the same. So, how can I say that the first function was to take a parameter by value instead of a pointer?

One solution may be to somehow analyze the name of the distorted function, but it may not always be viable. What if someone poses a extern "C"function?

Is there a way to tell me to clangsave the annotation byvalor create an additional annotation for each parameter of the function passed by the value?

, - LLVM. , , . Internals Manual of clang -. , , , , , . ? ? ?


:

, ++ ABI . : http://agner.org./optimize/calling_conventions.pdf. ! .

, , , , . , . ( , , ), . , , .

, - ABI clang, . , , , , .bc/.ll. - .


+5
1

, "byval" - "", , alot . , / ++ ABI, byval .

, byval frontend. , ( ctor ). , - POD-, clang , ctor ctor/dtor out, "".

(, ) clang ​​ ctor dtor. , , .

set(), , .

+5

All Articles