Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/AST/Print.cpp	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -86,5 +86,5 @@
 
 		static constexpr auto StorageClasses = make_array<const char*>(
-			"extern", "static", "auto", "register", "_Thread_local"
+			"extern", "static", "auto", "register", "__thread", "_Thread_local"
 		);
 
@@ -215,5 +215,5 @@
 			++indent;
 			ptrToEnum->base->accept( *this );
-			--indent;  
+			--indent;
 		}
 
@@ -1623,5 +1623,5 @@
 // if the wrong size is specified
 constexpr array<const char*, 3> Printer::Names::FuncSpecifiers;
-constexpr array<const char*, 5> Printer::Names::StorageClasses;
+constexpr array<const char*, 6> Printer::Names::StorageClasses;
 constexpr array<const char*, 6> Printer::Names::Qualifiers;
 }
Index: src/AST/StorageClasses.hpp
===================================================================
--- src/AST/StorageClasses.hpp	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/AST/StorageClasses.hpp	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -24,10 +24,11 @@
 	/// Bitflags for storage classes
 	enum {
-		Extern      = 1 << 0,
-		Static      = 1 << 1,
-		Auto        = 1 << 2,
-		Register    = 1 << 3,
-		ThreadLocal = 1 << 4,
-		NumClasses       = 5
+		Extern         = 1 << 0,
+		Static         = 1 << 1,
+		Auto           = 1 << 2,
+		Register       = 1 << 3,
+		ThreadLocalGcc = 1 << 4,
+		ThreadLocalC11 = 1 << 5,
+		NumClasses          = 6
 	};
 
@@ -37,9 +38,10 @@
 			unsigned int val;
 			struct {
-				bool is_extern      : 1;
-				bool is_static      : 1;
-				bool is_auto        : 1;
-				bool is_register    : 1;
-				bool is_threadlocal : 1;
+				bool is_extern         : 1;
+				bool is_static         : 1;
+				bool is_auto           : 1;
+				bool is_register       : 1;
+				bool is_threadlocalGcc : 1;
+				bool is_threadlocalC11 : 1;
 			};
 
@@ -48,4 +50,6 @@
 
 		constexpr class_flags( unsigned int val = 0 ) : val(val) {}
+
+		bool is_threadlocal_any() { return this->is_threadlocalC11 || this->is_threadlocalGcc; }
 	};
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/InitTweak/InitTweak.cc	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -1241,5 +1241,5 @@
 	static const char * const tlsd_section = ".tdata" ASM_COMMENT;
 	void addDataSectionAttribute( ObjectDecl * objDecl ) {
-		const bool is_tls = objDecl->get_storageClasses().is_threadlocal;
+		const bool is_tls = objDecl->get_storageClasses().is_threadlocal_any();
 		const char * section = is_tls ? tlsd_section : data_section;
 		objDecl->attributes.push_back(new Attribute("section", {
@@ -1249,5 +1249,5 @@
 
 	void addDataSectionAttribute( ast::ObjectDecl * objDecl ) {
-		const bool is_tls = objDecl->storage.is_threadlocal;
+		const bool is_tls = objDecl->storage.is_threadlocal_any();
 		const char * section = is_tls ? tlsd_section : data_section;
 		objDecl->attributes.push_back(new ast::Attribute("section", {
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/Parser/DeclarationNode.cc	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -262,5 +262,5 @@
 	newnode->type->enumeration.anon = name == nullptr;
 	if ( base && base->type)  {
-		newnode->type->base = base->type;	
+		newnode->type->base = base->type;
 	} // if
 
@@ -505,5 +505,5 @@
 			} // for
 			// src is the new item being added and has a single bit
-		} else if ( ! src->storageClasses.is_threadlocal ) { // conflict ?
+		} else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
 			appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] +
 						 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/Parser/lex.ll	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -314,6 +314,6 @@
 switch			{ KEYWORD_RETURN(SWITCH); }
 thread			{ KEYWORD_RETURN(THREAD); }				// C11
-__thread		{ KEYWORD_RETURN(THREADLOCAL); }		// GCC
-_Thread_local	{ KEYWORD_RETURN(THREADLOCAL); }		// C11
+__thread		{ KEYWORD_RETURN(THREADLOCALGCC); }		// GCC
+_Thread_local	{ KEYWORD_RETURN(THREADLOCALC11); }		// C11
 throw			{ KEYWORD_RETURN(THROW); }				// CFA
 throwResume		{ KEYWORD_RETURN(THROWRESUME); }		// CFA
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/Parser/parser.yy	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -293,5 +293,5 @@
 %token TYPEDEF
 %token EXTERN STATIC AUTO REGISTER
-%token THREADLOCAL										// C11
+%token THREADLOCALGCC THREADLOCALC11						// GCC, C11
 %token INLINE FORTRAN									// C99, extension ISO/IEC 9899:1999 Section J.5.9(1)
 %token NORETURN											// C11
@@ -1345,5 +1345,5 @@
 		{
 			if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
-			else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 
+			else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
 		}
 	| comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
@@ -1357,5 +1357,5 @@
 		{
 			if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
-			else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 
+			else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
 		}
 	| comma_expression updowneq comma_expression '~' '@' // CFA, error
@@ -2082,6 +2082,8 @@
 	| REGISTER
 		{ $$ = DeclarationNode::newStorageClass( Type::Register ); }
-	| THREADLOCAL										// C11
-		{ $$ = DeclarationNode::newStorageClass( Type::Threadlocal ); }
+	| THREADLOCALGCC										// GCC
+		{ $$ = DeclarationNode::newStorageClass( Type::ThreadlocalGcc ); }
+	| THREADLOCALC11										// C11
+		{ $$ = DeclarationNode::newStorageClass( Type::ThreadlocalC11 ); }
 		// Put function specifiers here to simplify parsing rules, but separate them semantically.
 	| INLINE											// C99
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/SynTree/Type.cc	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -80,5 +80,5 @@
 // These must remain in the same order as the corresponding bit fields.
 const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
-const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
+const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "__thread", "_Thread_local" };
 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "mutex", "_Atomic" };
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 4858a889060e180ad11caac083e08e61be604048)
+++ src/SynTree/Type.h	(revision e4855f684383f7bd8f4a3a1ad28663c2f6d307c7)
@@ -84,5 +84,5 @@
 	}; // FuncSpecifiers
 
-	enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, Threadlocal = 1 << 4, NumStorageClass = 5 };
+	enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, ThreadlocalGcc = 1 << 4, ThreadlocalC11 = 1 << 5, NumStorageClass = 6 };
 	static const char * StorageClassesNames[];
 	union StorageClasses {
@@ -93,5 +93,6 @@
 			bool is_auto : 1;
 			bool is_register : 1;
-			bool is_threadlocal : 1;
+			bool is_threadlocalGcc : 1;
+			bool is_threadlocalC11 : 1;
 		};
 
@@ -100,4 +101,6 @@
 		// equality (==, !=) works implicitly on first field "val", relational operations are undefined.
 		BFCommon( StorageClasses, NumStorageClass )
+
+		bool is_threadlocal_any() { return this->is_threadlocalC11 || this->is_threadlocalGcc; }
 	}; // StorageClasses
 
