Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/CodeGen/CodeGenerator.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -172,4 +172,6 @@
 	// *** Declarations
 	void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
+		// deleted decls should never be used, so don't print them
+		if ( functionDecl->isDeleted && genC ) return;
 		extension( functionDecl );
 		genAttributes( functionDecl->get_attributes() );
@@ -185,7 +187,12 @@
 			functionDecl->get_statements()->accept( *visitor );
 		} // if
+		if ( functionDecl->isDeleted ) {
+			output << " = void";
+		}
 	}
 
 	void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
+		// deleted decls should never be used, so don't print them
+		if ( objectDecl->isDeleted && genC ) return;
 		if (objectDecl->get_name().empty() && genC ) {
 			// only generate an anonymous name when generating C code, otherwise it clutters the output too much
@@ -206,4 +213,7 @@
 			objectDecl->get_init()->accept( *visitor );
 		} // if
+		if ( objectDecl->isDeleted ) {
+			output << " = void";
+		}
 
 		if ( objectDecl->get_bitfieldWidth() ) {
@@ -827,4 +837,27 @@
 		expr->expr->accept( *visitor );
 	}
+
+	void CodeGenerator::postvisit( GenericExpr * expr ) {
+		assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
+		output << "_Generic(";
+		expr->control->accept( *visitor );
+		output << ", ";
+		unsigned int numAssocs = expr->associations.size();
+		unsigned int i = 0;
+		for ( GenericExpr::Association & assoc : expr->associations ) {
+			if (assoc.isDefault) {
+				output << "default: ";
+			} else {
+				output << genType( assoc.type, "", pretty, genC ) << ": ";
+			}
+			assoc.expr->accept( *visitor );
+			if ( i+1 != numAssocs ) {
+				output << ", ";
+			}
+			i++;
+		}
+		output << ")";
+	}
+
 
 	// *** Statements
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/CodeGen/CodeGenerator.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -94,4 +94,5 @@
 		void postvisit( ConstructorExpr * );
 		void postvisit( DeletedExpr * );
+		void postvisit( GenericExpr * );
 
 		//*** Statements
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/Common/PassVisitor.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -125,4 +125,5 @@
 	virtual void visit( InitExpr *  initExpr ) override final;
 	virtual void visit( DeletedExpr *  delExpr ) override final;
+	virtual void visit( GenericExpr * genExpr ) override final;
 
 	virtual void visit( VoidType * basicType ) override final;
@@ -223,4 +224,5 @@
 	virtual Expression * mutate( InitExpr *  initExpr ) override final;
 	virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
+	virtual Expression * mutate( GenericExpr * genExpr ) override final;
 
 	virtual Type * mutate( VoidType * basicType ) override final;
@@ -311,5 +313,5 @@
 	void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
 	void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
-	void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith     ( pass, 0, exprs, withStmt ); }
+	void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
 
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/Common/PassVisitor.impl.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -2073,4 +2073,35 @@
 
 //--------------------------------------------------------------------------
+// GenericExpr
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( GenericExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl( node->control, *this );
+	for ( GenericExpr::Association & assoc : node->associations ) {
+		indexerScopedAccept( assoc.type, *this );
+		maybeAccept_impl( assoc.expr, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
+	MUTATE_START( node );
+
+	indexerScopedMutate( node->env, *this );
+	indexerScopedMutate( node->result, *this );
+	maybeMutate_impl( node->control, *this );
+	for ( GenericExpr::Association & assoc : node->associations ) {
+		indexerScopedMutate( assoc.type, *this );
+		maybeMutate_impl( assoc.expr, *this );
+	}
+
+	MUTATE_END( Expression, node );
+}
+
+//--------------------------------------------------------------------------
 // VoidType
 template< typename pass_type >
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/Parser/DeclarationNode.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -1067,5 +1067,11 @@
 			SemanticError( this, "invalid function specifier for " );
 		} // if
-		return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
+		bool isDelete = initializer && initializer->get_isDelete();
+		Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
+		if ( isDelete ) {
+			DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
+			dwt->isDeleted = true;
+		}
+		return decl;
 	} // if
 
Index: src/Parser/InitializerNode.cc
===================================================================
--- src/Parser/InitializerNode.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/Parser/InitializerNode.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -27,5 +27,5 @@
 
 InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des )
-		: expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {
+		: expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) {
 	if ( aggrp )
 		kids = dynamic_cast< InitializerNode * >( get_next() );
@@ -36,5 +36,5 @@
 
 InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des )
-		: expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {
+		: expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) {
 	if ( init )
 		set_last( init );
@@ -46,4 +46,6 @@
 		set_next( nullptr );
 } // InitializerNode::InitializerNode
+
+InitializerNode::InitializerNode( bool isDelete ) : expr( nullptr ), aggregate( false ), designator( nullptr ), kids( nullptr ), maybeConstructed( false ), isDelete( isDelete ) {}
 
 InitializerNode::~InitializerNode() {
@@ -84,4 +86,5 @@
 
 Initializer * InitializerNode::build() const {
+	assertf( ! isDelete, "Should not build delete stmt InitializerNode" );
 	if ( aggregate ) {
 		// steal designators from children
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/Parser/ParseNode.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -87,4 +87,5 @@
 	InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
 	InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
+	InitializerNode( bool isDelete );
 	~InitializerNode();
 	virtual InitializerNode * clone() const { assert( false ); return nullptr; }
@@ -97,4 +98,6 @@
 	InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
 	bool get_maybeConstructed() const { return maybeConstructed; }
+
+	bool get_isDelete() const { return isDelete; }
 
 	InitializerNode * next_init() const { return kids; }
@@ -110,4 +113,5 @@
 	InitializerNode * kids;
 	bool maybeConstructed;
+	bool isDelete;
 }; // InitializerNode
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/Parser/parser.yy	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -175,4 +175,5 @@
 	bool flag;
 	CatchStmt::Kind catch_kind;
+	GenericExpr * genexpr;
 }
 
@@ -259,4 +260,5 @@
 %type<flag> asm_volatile_opt
 %type<en> handler_predicate_opt
+%type<genexpr> generic_association generic_assoc_list
 
 // statements
@@ -501,15 +503,30 @@
 		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
 	| GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
-		{ SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
+		{
+			// add the missing control expression to the GenericExpr and return it
+			$5->control = maybeMoveBuild<Expression>( $3 );
+			$$ = new ExpressionNode( $5 );
+		}
 	;
 
 generic_assoc_list:										// C11
-	| generic_association
+	generic_association
 	| generic_assoc_list ',' generic_association
+		{
+			// steal the association node from the singleton and delete the wrapper
+			$1->associations.splice($1->associations.end(), $3->associations);
+			delete $3;
+			$$ = $1;
+		}
 	;
 
 generic_association:									// C11
 	type_no_function ':' assignment_expression
+		{
+			// create a GenericExpr wrapper with one association pair
+			$$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>($3) } } );
+		}
 	| DEFAULT ':' assignment_expression
+		{ $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>($3) } } ); }
 	;
 
@@ -2084,5 +2101,5 @@
 		{ $$ = $2; }
 	| '=' VOID
-		{ $$ = nullptr; }
+		{ $$ = new InitializerNode( true ); }
 	| ATassign initializer
 		{ $$ = $2->set_maybeConstructed( false ); }
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -97,4 +97,5 @@
 		void postvisit( InitExpr * initExpr );
 		void postvisit( DeletedExpr * delExpr );
+		void postvisit( GenericExpr * genExpr );
 
 		/// Adds alternatives for anonymous members
@@ -1756,4 +1757,8 @@
 		assertf( false, "AlternativeFinder should never see a DeletedExpr." );
 	}
+
+	void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
+		assertf( false, "_Generic is not yet supported." );
+	}
 } // namespace ResolvExpr
 
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SymTab/Indexer.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -148,5 +148,5 @@
 		for ( auto decl : copy ) {
 			if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
-				std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
+				std::list< DeclarationWithType * > & params = function->type->parameters;
 				assert( ! params.empty() );
 				// use base type of pointer, so that qualifiers on the pointer type aren't considered.
@@ -170,5 +170,5 @@
 				bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
 				bool isUserDefinedFunc = ball.isUserDefinedFunc;
-				bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
+				bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->linkage == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
 				bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
 				bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
@@ -471,5 +471,5 @@
 	void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
 		// default handling of conflicts is to raise an error
-		addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr );
+		addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
 	}
 
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SymTab/Mangler.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -171,6 +171,6 @@
 					"w",	// SignedInt128
 					"Uw",	// UnsignedInt128
-					"a",   // Float80
-					"A",   // Float128
+					"x",   // Float80
+					"y",   // Float128
 				};
 				static_assert(
@@ -225,8 +225,8 @@
 				GuardValue( inFunctionType );
 				inFunctionType = true;
-				std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
+				std::list< Type* > returnTypes = getTypes( functionType->returnVals );
 				acceptAll( returnTypes, *visitor );
 				mangleName << "_";
-				std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
+				std::list< Type* > paramTypes = getTypes( functionType->parameters );
 				acceptAll( paramTypes, *visitor );
 				mangleName << "_";
@@ -236,14 +236,14 @@
 				printQualifiers( refType );
 
-				mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
+				mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
 
 				if ( mangleGenericParams ) {
-					std::list< Expression* >& params = refType->get_parameters();
+					std::list< Expression* >& params = refType->parameters;
 					if ( ! params.empty() ) {
 						mangleName << "_";
 						for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
 							TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
-							assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
-							maybeAccept( paramType->get_type(), *visitor );
+							assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
+							maybeAccept( paramType->type, *visitor );
 						}
 						mangleName << "_";
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/Declaration.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -104,4 +104,5 @@
 }
 
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/Declaration.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -84,4 +84,5 @@
 	Expression *asmName;
 	std::list< Attribute * > attributes;
+	bool isDeleted = false;
 
 	DeclarationWithType( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, const std::list< Attribute * > & attributes, Type::FuncSpecifiers fs );
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/Expression.cc	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -748,4 +748,38 @@
 }
 
+GenericExpr::Association::Association( Type * type, Expression * expr ) : type( type ), expr( expr ), isDefault( false ) {}
+GenericExpr::Association::Association( Expression * expr ) : type( nullptr ), expr( expr ), isDefault( true ) {}
+GenericExpr::Association::Association( const Association & other ) : type( maybeClone( other.type ) ), expr( maybeClone( other.expr ) ), isDefault( other.isDefault ) {}
+GenericExpr::Association::~Association() {
+	delete type;
+	delete expr;
+}
+
+GenericExpr::GenericExpr( Expression * control, const std::list<Association> & assoc ) : Expression(), control( control ), associations( assoc ) {}
+GenericExpr::GenericExpr( const GenericExpr & other ) : Expression(other), control( maybeClone( other.control ) ), associations( other.associations ) {
+}
+GenericExpr::~GenericExpr() {
+	delete control;
+}
+
+void GenericExpr::print( std::ostream & os, Indenter indent ) const {
+	os << "C11 _Generic Expression" << std::endl << indent+1;
+	control->print( os, indent+1 );
+	os << std::endl << indent+1 << "... with associations: " << std::endl;
+	for ( const Association & assoc : associations ) {
+		os << indent+1;
+		if (assoc.isDefault) {
+			os << "... default: ";
+			assoc.expr->print( os, indent+1 );
+		} else {
+			os << "... type: ";
+			assoc.type->print( os, indent+1 );
+			os << std::endl << indent+1 << "... expression: ";
+			assoc.expr->print( os, indent+1 );
+			os << std::endl;
+		}
+		os << std::endl;
+	}
+}
 
 // Local Variables: //
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/Expression.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -865,4 +865,32 @@
 };
 
+/// C11 _Generic expression
+class GenericExpr : public Expression {
+public:
+	struct Association {
+		Type * type = nullptr;
+		Expression * expr = nullptr;
+		bool isDefault = false;
+
+		Association( Type * type, Expression * expr );
+		Association( Expression * expr );
+		Association( const Association & other );
+		Association & operator=( const Association & other ) = delete; // at the moment this isn't used, and I don't want to implement it
+		~Association();
+	};
+
+	Expression * control;
+	std::list<Association> associations;
+
+	GenericExpr( Expression * control, const std::list<Association> & assoc );
+	GenericExpr( const GenericExpr & other );
+	virtual ~GenericExpr();
+
+	virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const;
+};
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/Mutator.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -93,4 +93,5 @@
 	virtual Expression * mutate( InitExpr  * initExpr ) = 0;
 	virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
+	virtual Expression * mutate( GenericExpr * genExpr ) = 0;
 
 	virtual Type * mutate( VoidType * basicType ) = 0;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/SynTree.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -101,4 +101,5 @@
 class InitExpr;
 class DeletedExpr;
+class GenericExpr;
 
 class Type;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision c24ef9d02d48a8d5d71e71d8ccad0aec0a769fb6)
+++ src/SynTree/Visitor.h	(revision cb7caf838d4dc412c00958aaeab276dd4cea834c)
@@ -95,4 +95,5 @@
 	virtual void visit( InitExpr *  initExpr ) = 0;
 	virtual void visit( DeletedExpr * delExpr ) = 0;
+	virtual void visit( GenericExpr * genExpr ) = 0;
 
 	virtual void visit( VoidType * basicType ) = 0;
