fix a couple of problems with section attributes:
1. Passing something that isn't a string used to cause:
"argument to annotate attribute was not a string literal"
make it say "section attribute" instead.
2. Fix the location of the above message to point to the
bad argument instead of the section token.
3. Implement rdar://4341926, by diagnosing invalid section
specifiers in the frontend rather than letting them slip all
the way to the assembler (a QoI win).
An example of #3 is that we used to produce something like this:
/var/folders/n7/n7Yno9ihEm894640nJdSQU+++TI/-Tmp-//ccFPFGtT.s:2:Expected comma after segment-name
/var/folders/n7/n7Yno9ihEm894640nJdSQU+++TI/-Tmp-//ccFPFGtT.s:2:Rest of line ignored. 1st junk character valued 46 (.).
Daniel improved clang to use llvm_report_error, so now we got:
$ clang t.c -c
fatal error: error in backend: Global variable 'x' has an invalid section specifier 'sadf': mach-o section specifier
requires a segment and section separated by a comma.
with no loc info. Now we get:
$ clang t.c -fsyntax-only
t.c:4:30: error: argument to 'section' attribute is not valid for this target: mach-o section specifier requires a segment
and section separated by a comma
int x __attribute__((section("sadf")));
^
which is nice :)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78586 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 9d1b084..d5d3840 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -17,7 +17,7 @@
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Parse/DeclSpec.h"
-#include <llvm/ADT/StringExtras.h>
+#include "llvm/ADT/StringExtras.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -981,15 +981,25 @@
// Make sure that there is a string literal as the sections's single
// argument.
- StringLiteral *SE =
- dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
+ Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
+ StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
if (!SE) {
- // FIXME
- S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
+ S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
return;
}
- D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
- SE->getByteLength())));
+
+ std::string SectionStr(SE->getStrData(), SE->getByteLength());
+
+ // If the target wants to validate the section specifier, make it happen.
+ std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr);
+ if (Error.empty()) {
+ D->addAttr(::new (S.Context) SectionAttr(SectionStr));
+ return;
+ }
+
+ S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
+ << Error;
+
}
static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1405,13 +1415,13 @@
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
}
- Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
- StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
+ Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
+ StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
// Make sure that there is a string literal as the annotation's single
// argument.
if (!SE) {
- S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
+ S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
return;
}
d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),