aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-04-13 02:43:54 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-04-13 02:43:54 +0000
commit38afbc7361d861968232defaeaf8e302af75b5ee (patch)
tree2e1026be5c32198ab6f2de9ae98d7e5ed229bec5 /lib/Sema/SemaDecl.cpp
parent84083b74abc4a2d1a9013ce4c75d63ee7d6d1da3 (diff)
Annotate flavor of TLS variable (statically or dynamically initialized) onto the AST.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179447 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp30
1 files changed, 20 insertions, 10 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a2c3c2e147..b3cbbf203e 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2953,12 +2953,22 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
return New->setInvalidDecl();
}
- if (New->isThreadSpecified() && !Old->isThreadSpecified()) {
- Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
- } else if (!New->isThreadSpecified() && Old->isThreadSpecified()) {
- Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ if (New->getTLSKind() != Old->getTLSKind()) {
+ if (!Old->getTLSKind()) {
+ Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ } else if (!New->getTLSKind()) {
+ Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ } else {
+ // Do not allow redeclaration to change the variable between requiring
+ // static and dynamic initialization.
+ // FIXME: GCC allows this, but uses the TLS keyword on the first
+ // declaration to determine the kind. Do we need to be compatible here?
+ Diag(New->getLocation(), diag::err_thread_thread_different_kind)
+ << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic);
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ }
}
// C++ doesn't have tentative definitions, so go right ahead and check here.
@@ -4577,7 +4587,7 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
if (VarDecl *var = dyn_cast<VarDecl>(decl)) {
// Thread-local variables cannot have lifetime.
if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone &&
- var->isThreadSpecified()) {
+ var->getTLSKind()) {
Diag(var->getLocation(), diag::err_arc_thread_ownership)
<< var->getType();
return true;
@@ -4851,9 +4861,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
diag::err_thread_unsupported);
else
- // FIXME: Track which thread specifier was used; they have different
- // semantics.
- NewVD->setThreadSpecified(true);
+ NewVD->setTLSKind(TSCS == DeclSpec::TSCS_thread_local
+ ? VarDecl::TLS_Dynamic
+ : VarDecl::TLS_Static);
}
// C99 6.7.4p3