diff options
author | Hans Wennborg <hans@hanshq.net> | 2012-06-23 11:51:46 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2012-06-23 11:51:46 +0000 |
commit | d3b01bc7c6735a78ebdff0071647a15de5716bc7 (patch) | |
tree | 1bea08b4886b9dac974ae24ea644795b8b2fd0f6 /clang/lib/Sema | |
parent | cbe34b4cc98148b386a0c96cd195e7f62f52a6e3 (diff) | |
download | bcm5719-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.cpp | 40 |
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: |