diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-05-18 01:47:00 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-05-18 01:47:00 +0000 |
commit | 3f664061e58aabd01996f01b96eb9f5c9e45c3e2 (patch) | |
tree | 0e367323517f4a19992a8c57893212fdf5484266 /lib/Sema/SemaDecl.cpp | |
parent | 1434518f17272968765602a54391c794c975350a (diff) |
Centralize the handling of the "attribute declaration must precede definition"
warning. This also makes us warn on tags, which, ironically, is the only case
gcc warns on.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157039 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cc42720a7b..6de5627f3d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1698,9 +1698,30 @@ bool Sema::mergeDeclAttribute(Decl *D, InheritableAttr *Attr) { return false; } +static const Decl *getDefinition(Decl *D) { + if (TagDecl *TD = dyn_cast<TagDecl>(D)) + return TD->getDefinition(); + if (VarDecl *VD = dyn_cast<VarDecl>(D)) + return VD->getDefinition(); + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + const FunctionDecl* Def; + if (FD->hasBody(Def)) + return Def; + } + return NULL; +} + /// mergeDeclAttributes - Copy attributes from the Old decl to the New one. void Sema::mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation) { + // attributes declared post-definition are currently ignored + const Decl *Def = getDefinition(Old); + if (Def && Def != New && New->hasAttrs()) { + Diag(New->getLocation(), diag::warn_attribute_precede_definition); + Diag(Def->getLocation(), diag::note_previous_definition); + New->dropAttrs(); + } + if (!Old->hasAttrs()) return; @@ -4251,18 +4272,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, CheckMemberSpecialization(NewVD, Previous)) NewVD->setInvalidDecl(); } - - // attributes declared post-definition are currently ignored - // FIXME: This should be handled in attribute merging, not - // here. - if (Previous.isSingleResult()) { - VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl()); - if (Def && (Def = Def->getDefinition()) && - Def != NewVD && D.hasAttributes()) { - Diag(NewVD->getLocation(), diag::warn_attribute_precede_definition); - Diag(Def->getLocation(), diag::note_previous_definition); - } - } // If this is a locally-scoped extern C variable, update the map of // such variables. @@ -5665,17 +5674,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - // attributes declared post-definition are currently ignored - // FIXME: This should happen during attribute merging - if (D.isRedeclaration() && Previous.isSingleResult()) { - const FunctionDecl *Def; - FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl()); - if (PrevFD && PrevFD->isDefined(Def) && D.hasAttributes()) { - Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition); - Diag(Def->getLocation(), diag::note_previous_definition); - } - } - AddKnownFunctionAttributes(NewFD); if (NewFD->hasAttr<OverloadableAttr>() && |