Passer la structure par paramètre avec LLVM

Est-il possible de passer structure par paramètre?

Est-ce compatible avec le C abi?

[modifier]

En gros, j’aimerais avoir un POD C ++ qui contiendrait deux membres (la structure serait un gros pointeur, avec un pointeur et un entier), et je pourrais passer cette structure comme paramètre de fonction dans les instructions d’appel (même en appelant C code).

Je n’utilise pas le gros pointeur maintenant (le pointeur et l’entier sont dans un paramètre de fonction différent), et j’aimerais savoir si c’est possible avant de commencer une refactorisation assez grosse!

Absolument, tu peux. Voici un exemple:

struct MyStruct_t { char *charPointer; int number; }; void myFunction(MyStruct_t myStructAsParam) { printf("Ssortingng: %s, Number: %i", myStructAsParam.charPointer, myStructAsParam.number); // Your stuff here. } 

Tu peux le faire.

Vous pouvez déterminer le code LLVM pour l’exemple C en copiant et en collant le code C dans la démonstration en ligne de LLVM à l’ adresse http://llvm.org/demo/index.cgi .

Si vous copiez et collez le code sur codepad.org dans, vous verrez que LLVM génère les éléments suivants pour myFunction:

 define void @_Z10myFunction10MyStruct_t(i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1) nounwind uwtable { %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1) ret void } 

Bien sûr, si vous regardez l’appel, vous remarquerez qu’aucune copie n’est en cours de création. C’est à la fonction appelante de le faire. Si nous écrivons une petite fonction C:

 void myCallingFunction(MyStruct_t *foobar) { myFunction(*foobar); } 

Nous pouvons voir que le bitcode LLVM généré pour myCallingFunction est:

 define void @_Z17myCallingFunctionP10MyStruct_t(%struct.MyStruct_t* nocapture %foobar) nounwind uwtable { %foobar.0 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 0 %tmp = load i8** %foobar.0, align 8 %foobar.1 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 1 %tmp1 = load i32* %foobar.1, align 8 %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %tmp, i32 %tmp1) nounwind ret void } 

La fonction appelante crée une copie de la structure, puis transmet l’adresse de la copie.