Walk the decls looking for the last one that has an attribute. We do have to walk

them, otherwise we cannot produce an error for both

struct HIDDEN test4; // canonical
struct test4;
struct DEFAULT test4;

and

struct test5; // canonical
struct HIDDEN test5;
struct DEFAULT test5;

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156016 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2012-05-02 20:36:57 +00:00
Родитель 51c8bac81e
Коммит 548d17c977
2 изменённых файлов: 13 добавлений и 6 удалений

Просмотреть файл

@ -1757,13 +1757,16 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
return;
}
Decl *PrevDecl;
if (isa<FunctionDecl>(D))
PrevDecl = D->getMostRecentDecl()->getPreviousDecl();
else
PrevDecl = D->getCanonicalDecl();
// Find the last Decl that has an attribute.
VisibilityAttr *PrevAttr;
assert(D->redecls_begin() == D);
for (Decl::redecl_iterator I = D->redecls_begin(), E = D->redecls_end();
I != E; ++I) {
PrevAttr = I->getAttr<VisibilityAttr>() ;
if (PrevAttr)
break;
}
VisibilityAttr *PrevAttr = PrevDecl ? PrevDecl->getAttr<VisibilityAttr>() : 0;
if (PrevAttr) {
VisibilityAttr::VisibilityType PrevVisibility = PrevAttr->getVisibility();
if (PrevVisibility != type) {

Просмотреть файл

@ -10,3 +10,7 @@ void test3() __attribute__((visibility("protected"))); // expected-warning {{tar
struct __attribute__((visibility("hidden"))) test4; // expected-note {{previous attribute is here}}
struct test4;
struct __attribute__((visibility("default"))) test4; // expected-error {{visibility does not match previous declaration}}
struct test5;
struct __attribute__((visibility("hidden"))) test5; // expected-note {{previous attribute is here}}
struct __attribute__((visibility("default"))) test5; // expected-error {{visibility does not match previous declaration}}