Index: clang/lib/Serialization/ASTReaderDecl.cpp =================================================================== --- clang/lib/Serialization/ASTReaderDecl.cpp +++ clang/lib/Serialization/ASTReaderDecl.cpp @@ -281,6 +281,8 @@ static Decl *getMostRecentDeclImpl(...); static Decl *getMostRecentDecl(Decl *D); + static void mergeInheritableAttributes(Decl *D, Decl *Previous); + template static void attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, Decl *Previous, @@ -3531,6 +3533,18 @@ return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl()); } +void ASTDeclReader::mergeInheritableAttributes(Decl *D, Decl *Previous) { + if (Previous->hasAttr() && + !D->hasAttr()) { + Attr *IA = Previous->getAttr(); + D->addAttr(IA); + } else if (!Previous->hasAttr() && + D->hasAttr()) { + Attr *IA = D->getAttr(); + Previous->addAttr(IA); + } +} + template void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable *D, @@ -3689,6 +3703,10 @@ if (auto *TD = dyn_cast(D)) inheritDefaultTemplateArguments(Reader.getContext(), cast(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. + mergeInheritableAttributes(D, Previous); } template Index: clang/test/Modules/Inputs/inherit-attribute/a.h =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/inherit-attribute/a.h @@ -0,0 +1,10 @@ +#ifndef FOO +#define FOO + +class Foo { +public: + void step(int v); + Foo(); +}; + +#endif \ No newline at end of file Index: clang/test/Modules/Inputs/inherit-attribute/b.h =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/inherit-attribute/b.h @@ -0,0 +1,12 @@ +#include "a.h" + +class Foo; + +void bar() { + &Foo::step; +} + +class B { +public: + B(); +}; \ No newline at end of file Index: clang/test/Modules/Inputs/inherit-attribute/c.h =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/inherit-attribute/c.h @@ -0,0 +1,7 @@ +#include "a.h" + +class Foo; +class C { +public: + C(); +}; \ No newline at end of file Index: clang/test/Modules/Inputs/inherit-attribute/module.modulemap =================================================================== --- /dev/null +++ clang/test/Modules/Inputs/inherit-attribute/module.modulemap @@ -0,0 +1,3 @@ +module "b" { header "b.h" } + +module "c" { header "c.h" } \ No newline at end of file Index: clang/test/Modules/inherit-attribute.cpp =================================================================== --- /dev/null +++ clang/test/Modules/inherit-attribute.cpp @@ -0,0 +1,10 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -ast-dump -I%S/Inputs/inherit-attribute -fmodules-cache-path=%t -fimplicit-module-maps -verify %s -fmodules-local-submodule-visibility + +#include "b.h" +#include "c.h" + +class Foo; + +Foo f; +// expected-no-diagnostics \ No newline at end of file