summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--lib/Sema/SemaDeclAttr.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 094e5b5..1a12208 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "Sema.h"
+#include "TargetAttributesSema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
@@ -925,14 +926,19 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// If the target wants to validate the section specifier, make it happen.
std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
- if (Error.empty()) {
- D->addAttr(::new (S.Context) SectionAttr(SE->getString()));
+ if (!Error.empty()) {
+ S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
+ << Error;
return;
}
- S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
- << Error;
-
+ // This attribute cannot be applied to local variables.
+ if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
+ S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
+ return;
+ }
+
+ D->addAttr(::new (S.Context) SectionAttr(SE->getString()));
}
static void HandleCDeclAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1959,7 +1965,10 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
// Just ignore
break;
default:
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+ // Ask target about the attribute.
+ const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
+ if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
break;
}
}
OpenPOWER on IntegriCloud