summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2012-06-23 11:51:46 +0000
committerHans Wennborg <hans@hanshq.net>2012-06-23 11:51:46 +0000
commitd3b01bc7c6735a78ebdff0071647a15de5716bc7 (patch)
tree1bea08b4886b9dac974ae24ea644795b8b2fd0f6 /clang/lib/Sema
parentcbe34b4cc98148b386a0c96cd195e7f62f52a6e3 (diff)
downloadbcm5719-llvm-d3b01bc7c6735a78ebdff0071647a15de5716bc7.tar.gz
bcm5719-llvm-d3b01bc7c6735a78ebdff0071647a15de5716bc7.zip
Support the tls_model attribute (PR9788)
This adds support for the tls_model attribute. This allows the user to choose a TLS model that is better than what LLVM would select by default. For example, a variable might be declared as: __thread int x __attribute__((tls_model("initial-exec"))); if it will not be used in a shared library that is dlopen'ed. This depends on LLVM r159077. llvm-svn: 159078
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index b443911daf9..744d18bfd9f 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -43,7 +43,8 @@ enum AttributeDeclKind {
ExpectedMethod,
ExpectedVariableFunctionOrLabel,
ExpectedFieldOrGlobalVar,
- ExpectedStruct
+ ExpectedStruct,
+ ExpectedTLSVar
};
//===----------------------------------------------------------------------===//
@@ -1440,6 +1441,42 @@ static void handleAlwaysInlineAttr(Sema &S, Decl *D,
D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
}
+static void handleTLSModelAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ // Check the attribute arguments.
+ if (Attr.getNumArgs() != 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+ return;
+ }
+
+ Expr *Arg = Attr.getArg(0);
+ Arg = Arg->IgnoreParenCasts();
+ StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+
+ // Check that it is a string.
+ if (!Str) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_not_string) << "tls_model";
+ return;
+ }
+
+ if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+ << Attr.getName() << ExpectedTLSVar;
+ return;
+ }
+
+ // Check that the value.
+ StringRef Model = Str->getString();
+ if (Model != "global-dynamic" && Model != "local-dynamic"
+ && Model != "initial-exec" && Model != "local-exec") {
+ S.Diag(Attr.getLoc(), diag::err_attr_tlsmodel_arg);
+ return;
+ }
+
+ D->addAttr(::new (S.Context) TLSModelAttr(Attr.getRange(), S.Context,
+ Model));
+}
+
static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
// Check the attribute arguments.
if (Attr.hasParameterOrArguments()) {
@@ -3939,6 +3976,7 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
handleAlwaysInlineAttr (S, D, Attr); break;
case AttributeList::AT_AnalyzerNoReturn:
handleAnalyzerNoReturnAttr (S, D, Attr); break;
+ case AttributeList::AT_TLSModel: handleTLSModelAttr (S, D, Attr); break;
case AttributeList::AT_Annotate: handleAnnotateAttr (S, D, Attr); break;
case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
case AttributeList::AT_CarriesDependency:
OpenPOWER on IntegriCloud