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/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 51f5c87..605ee8c 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCSectionMachO.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -61,6 +62,7 @@
//===----------------------------------------------------------------------===//
// Defines specific to certain operating systems.
//===----------------------------------------------------------------------===//
+
namespace {
template<typename TgtInfo>
class OSTargetInfo : public TgtInfo {
@@ -78,7 +80,7 @@
};
}
-namespace {
+
/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
/// not defined, return 0's. Return true if we have -darwin in the string or
@@ -216,6 +218,7 @@
Opts.ObjCNonFragileABI = 1;
}
+namespace {
template<typename Target>
class DarwinTargetInfo : public OSTargetInfo<Target> {
protected:
@@ -245,8 +248,17 @@
virtual const char *getUnicodeStringSection() const {
return "__TEXT,__ustring";
}
+
+ virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
+ // Let MCSectionMachO validate this.
+ llvm::StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
+ TAA, StubSize);
+ }
};
+
// DragonFlyBSD Target
template<typename Target>
class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
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(),