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 中获取,但不可用。