Teach AttachPreviousImpl to inherit MSInheritanceAttr attribute

This commit teaches ASTDeclReader::attachPreviousDecl to successfully merge
two Decl's when one contains an inheritable attribute like the
MSInheritanceAttr. Usually, attributes that are needed to be present along the
redeclaration chain are attached during ASTReading from
ASTDeclReader::attachPreviousDecl, but no such thing is done for inheritable
attributes. Currently, only the logic for merging MSInheritanceAttr is
provided.
This commit is contained in:
Vaibhav Garg 2020-08-21 12:04:43 -04:00 committed by Aaron Ballman
parent 72d0f09489
commit 7a527f1777
6 changed files with 61 additions and 0 deletions

View file

@ -281,6 +281,9 @@ namespace clang {
static Decl *getMostRecentDeclImpl(...);
static Decl *getMostRecentDecl(Decl *D);
static void mergeInheritableAttributes(ASTReader &Reader, Decl *D,
Decl *Previous);
template <typename DeclT>
static void attachPreviousDeclImpl(ASTReader &Reader,
Redeclarable<DeclT> *D, Decl *Previous,
@ -3511,6 +3514,19 @@ Decl *ASTReader::getMostRecentExistingDecl(Decl *D) {
return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl());
}
void ASTDeclReader::mergeInheritableAttributes(ASTReader &Reader, Decl *D,
Decl *Previous) {
InheritableAttr *NewAttr = nullptr;
ASTContext &Context = Reader.getContext();
const auto *IA = Previous->getAttr<MSInheritanceAttr>();
if (IA && !D->hasAttr<MSInheritanceAttr>()) {
NewAttr = cast<InheritableAttr>(IA->clone(Context));
NewAttr->setInherited(true);
D->addAttr(NewAttr);
}
}
template<typename DeclT>
void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
Redeclarable<DeclT> *D,
@ -3669,6 +3685,12 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
if (auto *TD = dyn_cast<TemplateDecl>(D))
inheritDefaultTemplateArguments(Reader.getContext(),
cast<TemplateDecl>(Previous), TD);
// If any of the declaration in the chain contains an Inheritable attribute,
// it needs to be added to all the declarations in the redeclarable chain.
// FIXME: Only the logic of merging MSInheritableAttr is present, it should
// be extended for all inheritable attributes.
mergeInheritableAttributes(Reader, D, Previous);
}
template<typename DeclT>

View file

@ -0,0 +1,10 @@
#ifndef FOO
#define FOO
class Foo {
public:
void step(int v);
Foo();
};
#endif

View file

@ -0,0 +1,5 @@
#include "a.h"
void bar() {
&Foo::step;
}

View file

@ -0,0 +1 @@
#include "a.h"

View file

@ -0,0 +1,3 @@
module "b" { header "b.h" }
module "c" { header "c.h" }

View file

@ -0,0 +1,20 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -triple x86_64-pc-windows-msvc-unknown -I%S\Inputs\inherit-attribute -fmodules-cache-path=%t \
// RUN: -fimplicit-module-maps -fmodules-local-submodule-visibility %s -ast-dump-all \
// RUN: | FileCheck %s
#include "b.h"
#include "c.h"
class Foo;
Foo f;
// CHECK: CXXRecordDecl {{.*}} imported in b {{.*}} Foo
// CHECK: MSInheritanceAttr {{[^()]*$}}
// CHECK: CXXRecordDecl {{.*}} prev {{.*}} imported in c {{.*}} Foo
// CHECK: MSInheritanceAttr {{.*}} Inherited {{[^()]*$}}
// CHECK: CXXRecordDecl {{.*}} <line:9:1, col:7> col:7 referenced class Foo
// CHECK: MSInheritanceAttr {{.*}} Inherited {{[^()]*$}}