ABI 标签¶
简介¶
本文档试图描述 gcc 对 mangling “abi_tag” 属性的语义,这些属性在 https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 中描述。
不能保证以下规则是正确、完整或有意义的,因为它们是通过对 gcc5 的实验经验确定的。
声明¶
ABI 标签在 abi_tag 属性中声明,可以应用于函数、变量、类或内联命名空间声明。该属性接受一个或多个字符串(称为标签);顺序无关紧要。
有关详细信息,请参阅 https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html。
内联命名空间上的标签称为“隐式标签”,所有其他标签都称为“显式标签”。
Mangling¶
在 <unqualified-name> 上“活动”的所有标签都将在 <unqualified-name> 之后、<template-args> 或 <discriminator> 之前发出,并且是与 <unqualified-name> 相同的 <substitution> 的一部分。
它们的 mangling 方式为
<abi-tags> ::= <abi-tag>* # sort by name
<abi-tag> ::= B <tag source-name>
示例
__attribute__((abi_tag("test")))
void Func();
// gets mangled as: _Z4FuncB4testv (prettified as `Func[abi:test]()`)
活动标签¶
命名空间没有任何活动标签。对于类型(类/结构体/联合体/枚举),显式标签是活动标签。
对于变量和函数,活动标签是显式标签加上任何不在“可用标签”集合中的“必需标签”。
derived-tags := (required-tags - available-tags)
active-tags := explicit-tags + derived-tags
函数的必需标签¶
如果函数用作另一个名称的局部作用域,并且是另一个函数的局部作用域的一部分,则它没有任何必需标签。
如果函数用作保护变量名称的局部作用域,则它没有任何必需标签。
否则,函数需要返回类型名称中使用的任何隐式或显式标签。
示例
namespace A {
inline namespace B __attribute__((abi_tag)) {
struct C { int x; };
}
}
A::C foo(); // gets mangled as: _Z3fooB1Bv (prettified as `foo[abi:B]()`)
变量的必需标签¶
变量需要其类型中使用的任何隐式或显式标签。
可用标签¶
名称的前缀和模板参数中使用的所有标签都可用。此外,对于函数,<bare-function-type>(可能包括模板函数的返回类型)中的所有标签都可用。
对于 <local-name>,局部部分(<function-encoding>)中使用的所有活动标签都可用,但未活动的隐式标签除外。
函数的 <unqualified-name>(如强制转换运算符的类型)中使用的隐式和显式标签不可用。
示例:强制转换为 std::string(即 std::__cxx11::basic_string<…>)将使用 ‘cxx11’ 作为活动标签,因为它需要从返回类型 std::string 中获取,但不可用。