summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-05-18 01:47:00 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-05-18 01:47:00 +0000
commit3619104239aad500853ea3d23214d3bc22c16692 (patch)
treea9205d4f95709d5435c02e888bea529ed279c77a /clang/lib
parent22d405f57b62d0eee7a994f074859e399583f7f1 (diff)
downloadbcm5719-llvm-3619104239aad500853ea3d23214d3bc22c16692.tar.gz
bcm5719-llvm-3619104239aad500853ea3d23214d3bc22c16692.zip
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. llvm-svn: 157039
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index cc42720a7b9..6de5627f3de 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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>() &&
OpenPOWER on IntegriCloud