Почему clang создает эти неявные методы, когда класс содержит виртуальный метод?

Я работаю над инструментом, основанным на AST Clang, и мне любопытно узнать, почему Clang работает таким образом.

Вот мой вклад. У меня есть очень простой класс, который определяется следующим образом:

class Foo {
int foo();
};

Затем в моем RecursiveASTVisitor у меня есть код, который выглядит следующим образом:

bool MyASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl *D) {
for (auto const & method : D->methods()) {
llvm::outs() << method->getQualifiedNameAsString() << "(";
for (auto const & param : method->params())
llvm::outs() << param->getType().getAsString() << ", ";
llvm::outs() << ")";
if (method->isImplicit())
llvm::outs() << " [implicit]";
llvm::outs() << "\n";
}
return true;
}

Все, что он делает — это выдает список методов, определенных во всех посещаемых классах. Выход для этого, как мы и ожидали:

Foo::foo()

Теперь давайте внесем небольшое изменение в наш класс Foo. Давайте сделаем метод foo () виртуальным:

class Foo {
virtual int foo();
};

Теперь мой вывод меняется:

Foo::foo()
Foo::operator=(const class Foo &, ) [implicit]
Foo::~Foo() [implicit]

Мой вопрос: почему добавление виртуального метода в класс заставляет clang создать неявный оператор присваивания и деструктор? Если я добавлю —std = c ++ 11, это также создаст неявный оператор присваивания перемещения. Это деталь реализации clang, или это часть стандарта C ++?

3

Решение

Оказывается, я должен просто прочитать исходный код Clang. SemaDeclCXX.cpp имеет метод, называемый Sema::AddImplicitlyDeclaredMembersToClass, Там есть комментарий о том, почему он объявляет неявное присвоение копии:

if (!ClassDecl->hasUserDeclaredCopyAssignment()) {
++ASTContext::NumImplicitCopyAssignmentOperators;

// If we have a dynamic class, then the copy assignment operator may be
// virtual, so we have to declare it immediately. This ensures that, e.g.,
// it shows up in the right place in the vtable and that we diagnose
// problems with the implicit exception specification.
if (ClassDecl->isDynamicClass() ||
ClassDecl->needsOverloadResolutionForCopyAssignment())
DeclareImplicitCopyAssignment(ClassDecl);
}

Таким образом, это делается для того, чтобы неявно определенные методы, которые могут быть виртуальными, оказались в нужном месте в vtable.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]