RecordDecls are special. They have implicitly injected class names.
struct C { // C is implicitly declared here as a synonym for the class name. }; C::C c; // same as "C c;" In this example clang will inject another declaration to provide the name C within the record decl. For unknown reason it is added to the redecl chain. When we revert a class decl we must make sure that the implicitly injected name in the chain is gone.
This commit is contained in:
parent
8b4b340f6e
commit
fa9fe845cd
@ -165,6 +165,14 @@ namespace cling {
|
||||
///
|
||||
bool VisitTagDecl(TagDecl* TD);
|
||||
|
||||
///\brief Removes a RecordDecl. We shouldn't remove the implicit class
|
||||
/// declaration.
|
||||
///\param[in] RD - The declaration to be removed.
|
||||
///
|
||||
///\returns true on success.
|
||||
///
|
||||
bool VisitRecordDecl(RecordDecl* RD);
|
||||
|
||||
///\brief Remove the macro from the Preprocessor.
|
||||
/// @param[in] MD - The MacroDirectiveInfo containing the IdentifierInfo and
|
||||
/// MacroDirective to forward.
|
||||
@ -608,6 +616,31 @@ namespace cling {
|
||||
return Successful;
|
||||
}
|
||||
|
||||
bool DeclReverter::VisitRecordDecl(RecordDecl* RD) {
|
||||
if (RD->isInjectedClassName())
|
||||
return true;
|
||||
|
||||
/// The injected class name in C++ is the name of the class that
|
||||
/// appears inside the class itself. For example:
|
||||
///
|
||||
/// \code
|
||||
/// struct C {
|
||||
/// // C is implicitly declared here as a synonym for the class name.
|
||||
/// };
|
||||
///
|
||||
/// C::C c; // same as "C c;"
|
||||
/// \endcode
|
||||
// It is another question why it is on the redecl chain.
|
||||
RecordDecl* PrevRD = RD->getPreviousDecl();
|
||||
bool Successful = VisitTagDecl(RD);
|
||||
if (PrevRD) {
|
||||
assert(PrevRD->isInjectedClassName() && "Not injected classname?");
|
||||
Successful &= VisitTagDecl(PrevRD);
|
||||
}
|
||||
|
||||
return Successful;
|
||||
}
|
||||
|
||||
void DeclReverter::MaybeRemoveDeclFromModule(GlobalDecl& GD) const {
|
||||
if (!m_CurTransaction->getModule()) // syntax-only mode exit
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user