Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/CodeGen/CodeGenerator.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -442,4 +442,15 @@
 		output << ")";
 	}
+
+	void CodeGenerator::visit( AlignofExpr *sizeofExpr ) {
+		// use GCC extension to avoid bumping std to C11
+		output << "__alignof__(";
+		if ( sizeofExpr->get_isType() ) {
+			output << genType( sizeofExpr->get_type(), "" );
+		} else {
+			sizeofExpr->get_expr()->accept( *this );
+		} // if
+		output << ")";
+	}
   
 	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/CodeGen/CodeGenerator.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -60,4 +60,5 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *alignofExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
 		virtual void visit( ConditionalExpr *conditionalExpr );
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/Box.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -28,4 +28,5 @@
 #include "Parser/ParseNode.h"
 
+#include "SynTree/Constant.h"
 #include "SynTree/Type.h"
 #include "SynTree/Expression.h"
@@ -50,4 +51,5 @@
 		FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
 
+		/// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
 		class Pass1 : public PolyMutator {
 		  public:
@@ -88,7 +90,7 @@
 		};
 
+		/// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
 		class Pass2 : public PolyMutator {
 		  public:
-			Pass2();
 			template< typename DeclClass >
 			DeclClass *handleDecl( DeclClass *decl, Type *type );
@@ -105,4 +107,5 @@
 		};
 
+		/// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
 		class Pass3 : public PolyMutator {
 		  public:
@@ -178,6 +181,5 @@
 		}
 
-		Pass1::Pass1()
-			: useRetval( false ), tempNamer( "_temp" ) {
+		Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
 			adapters.push(AdapterMap());
 		}
@@ -312,4 +314,6 @@
 					if ( concrete ) {
 						arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
+						arg++;
+						arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
 						arg++;
 					} else {
@@ -647,5 +651,5 @@
 		}
 
-		Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
+		Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
 			NameExpr *opExpr;
 			if ( isIncr ) {
@@ -660,5 +664,5 @@
 				addAssign->get_args().push_back( appExpr->get_args().front() );
 			} // if
-			addAssign->get_args().push_back( new NameExpr( polyName ) );
+			addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
 			addAssign->get_results().front() = appExpr->get_results().front()->clone();
 			if ( appExpr->get_env() ) {
@@ -687,5 +691,5 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
 							ret->get_args().push_back( appExpr->get_args().front() );
 							ret->get_args().push_back( multiply );
@@ -693,5 +697,5 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().front() );
-							multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) );
 							ret->get_args().push_back( multiply );
 							ret->get_args().push_back( appExpr->get_args().back() );
@@ -739,5 +743,5 @@
 								assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
 							} // if
-							CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
+							CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "?++" ) );
 							return new CommaExpr( firstComma, tempExpr );
 						} // if
@@ -746,5 +750,5 @@
 						assert( appExpr->get_args().size() == 1 );
 						if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
-							return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
+							return makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "++?" );
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
@@ -756,5 +760,5 @@
 							UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
 							divide->get_args().push_back( appExpr );
-							divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+							divide->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
 							divide->get_results().push_front( appExpr->get_results().front()->clone() );
 							if ( appExpr->get_env() ) {
@@ -766,10 +770,10 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
 							appExpr->get_args().back() = multiply;
 						} else if ( typeInst2 ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().front() );
-							multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) );
 							appExpr->get_args().front() = multiply;
 						} // if
@@ -781,5 +785,5 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) );
 							appExpr->get_args().back() = multiply;
 						} // if
@@ -963,6 +967,4 @@
 ////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
 
-		Pass2::Pass2() {}
-
 		void Pass2::addAdapters( FunctionType *functionType ) {
 			std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
@@ -1037,23 +1039,29 @@
 			std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
 			std::list< DeclarationWithType *> inferredParams;
-			ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
-///   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
+			ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
+//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
 			for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
-				ObjectDecl *thisParm;
-				// add all size parameters to parameter list
+				ObjectDecl *sizeParm, *alignParm;
+				// add all size and alignment parameters to parameter list
 				if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
-					thisParm = newObj->clone();
-					thisParm->set_name( (*tyParm)->get_name() );
-					last = funcType->get_parameters().insert( last, thisParm );
+					TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
+					
+					sizeParm = newObj.clone();
+					sizeParm->set_name( sizeofName( &parmType ) );
+					last = funcType->get_parameters().insert( last, sizeParm );
+					++last;
+
+					alignParm = newObj.clone();
+					alignParm->set_name( alignofName( &parmType ) );
+					last = funcType->get_parameters().insert( last, alignParm );
 					++last;
 				}
 				// move all assertions into parameter list
 				for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
-///      *assert = (*assert)->acceptMutator( *this );
+//      *assert = (*assert)->acceptMutator( *this );
 					inferredParams.push_back( *assert );
 				}
 				(*tyParm)->get_assertions().clear();
 			}
-			delete newObj;
 			funcType->get_parameters().splice( last, inferredParams );
 			addAdapters( funcType );
@@ -1092,11 +1100,11 @@
 
 		TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
-///   Initializer *init = 0;
-///   std::list< Expression *> designators;
-///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
-///   if ( typeDecl->get_base() ) {
-///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
-///   }
-///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
+//   Initializer *init = 0;
+//   std::list< Expression *> designators;
+//   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+//   if ( typeDecl->get_base() ) {
+//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
+//   }
+//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
 
 			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
@@ -1131,5 +1139,5 @@
 					assert( typeInst );
 					UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
-					alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
+					alloc->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) );
 
 					delete objectDecl->get_init();
Index: src/GenPoly/FindFunction.h
===================================================================
--- src/GenPoly/FindFunction.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/FindFunction.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -23,5 +23,7 @@
 	typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& );
 
+	/// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions`
 	void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
+	/// like `findFunction`, but also replaces the function type with void ()(void)
 	void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
 } // namespace GenPoly
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/GenPoly.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  1 15:18:54 2015
-// Update Count     : 12
+// Last Modified On : Tue Dec 15 16:11:18 2015
+// Update Count     : 13
 //
 
@@ -21,5 +21,5 @@
 
 namespace GenPoly {
-	// A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
+	/// A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
 	bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
 		if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -44,10 +44,8 @@
 		ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
 
-		/// Extracts types from a list of Expression* (which should be TypeExpr*)
-		ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
-			for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
-				TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
-				assert(param && "Aggregate parameters should be type expressions");
-				params.push_back( param->get_type()->clone() );
+		/// Extracts types from a list of TypeExpr*
+		ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
+			for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
+				params.push_back( (*param)->get_type()->clone() );
 			}
 		}
@@ -66,7 +64,7 @@
 
 		bool operator== (const ConcreteType& that) const {
+			if ( base != that.base ) return false;
+
 			SymTab::Indexer dummy;
-
-			if ( base != that.base ) return false;
 			if ( params.size() != that.params.size() ) return false;
 			for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
@@ -79,9 +77,15 @@
 		std::list< Type* > params;  ///< Instantiation parameters
 	};
-
+	
 	/// Maps a concrete type to the instantiated struct type, accounting for scope
 	class InstantiationMap {
-		/// Pair of concrete type and declaration that instantiates it
-		typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
+		/// Instantiation of a generic type, with key information to find it
+		struct Instantiation {
+			ConcreteType key;     ///< Instantiation parameters for this type
+			AggregateDecl *decl;  ///< Declaration of the instantiated generic type
+
+			Instantiation() : key(), decl(0) {}
+			Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {}
+		};
 		/// Map of generic types to instantiations of them
 		typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
@@ -107,5 +111,5 @@
 		/// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
 		/// Returns NULL on none such.
-		AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
+		AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
 			ConcreteType key(generic, params);
 			// scan scopes from innermost out
@@ -116,5 +120,5 @@
 				// look through instantiations for matches to concrete type
 				for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
-					if ( inst->first == key ) return inst->second;
+					if ( inst->key == key ) return inst->decl;
 				}
 			}
@@ -123,21 +127,23 @@
 		}
 	public:
-		StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
-		UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
+		StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
+		UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
 
 	private:
 		/// Adds a declaration for a concrete type to the current scope
-		void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
+		void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, AggregateDecl *decl ) {
 			ConcreteType key(generic, params);
-			scopes.back()[generic].push_back( std::make_pair( key, decl ) );
+			scopes.back()[generic].push_back( Instantiation( key, decl ) );
 		}
 	public:
-		void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
-		void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
+		void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
+		void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
 	};
 
 	/// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
 	class Instantiate : public DeclMutator {
+		/// Map of (generic type, parameter list) pairs to concrete type instantiations
 		InstantiationMap instantiations;
+		/// Namer for concrete types
 		UniqueName typeNamer;
 
@@ -147,4 +153,6 @@
 		virtual Type* mutate( StructInstType *inst );
 		virtual Type* mutate( UnionInstType *inst );
+
+// 		virtual Expression* mutate( MemberExpr *memberExpr );
 		
 		virtual void doBeginScope();
@@ -157,10 +165,56 @@
 	}
 
-	/// Substitutes types of members of in according to baseParams => params, appending the result to out
-	void substituteMembers( const std::list< Declaration* >& in,
-							const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
+	/// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
+	bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
+ 		bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
+
+		// substitute concrete types for given parameters, and incomplete types for placeholders
+		std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
+		std::list< Expression* >::const_iterator param = params.begin();
+		for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
+// 			switch ( (*baseParam)->get_kind() ) {
+// 			case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
+				TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
+				assert(paramType && "Aggregate parameters should be type expressions");
+				out.push_back( paramType->clone() );
+				// check that the substituted type isn't a type variable itself
+				if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
+ 					allConcrete = false;
+				}
+// 				break;
+// 			}
+// 			case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
+// 				out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
+// 				break;
+// 			case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
+// 				out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
+// 				break;
+// 			}
+		}
+
+		// if any parameters left over, not done
+		if ( baseParam != baseParams.end() ) return false;
+// 		// if not enough parameters given, substitute remaining incomplete types for placeholders
+// 		for ( ; baseParam != baseParams.end(); ++baseParam ) {
+// 			switch ( (*baseParam)->get_kind() ) {
+// 			case TypeDecl::Any:    // no more substitutions here, fail early
+// 				return false;
+// 			case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
+// 				out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
+// 				break;
+// 			case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
+// 				out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
+// 				break;
+// 			}
+// 		}
+
+ 		return allConcrete;
+	}
+
+	/// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
+	void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 
 						    std::list< Declaration* >& out ) {
 		// substitute types into new members
-		TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
+		TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
 		for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
 			Declaration *newMember = (*member)->clone();
@@ -178,19 +232,26 @@
 		// exit early if no need for further mutation
 		if ( inst->get_parameters().empty() ) return inst;
+		assert( inst->get_baseParameters() && "Base struct has parameters" );
+
+		// check if type can be concretely instantiated; put substitutions into typeSubs
+		std::list< TypeExpr* > typeSubs;
+		if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
+			deleteAll( typeSubs );
+			return inst;
+		}
 		
 		// make concrete instantiation of generic type
-		StructDecl *concDecl = instantiations.lookup( inst );
+		StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
 		if ( ! concDecl ) {
-			assert( inst->get_baseParameters() && "Base struct has parameters" );
 			// set concDecl to new type, insert type declaration into statements to add
 			concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
-			substituteMembers( inst->get_baseStruct()->get_members(),
-								*inst->get_baseParameters(), inst->get_parameters(),
-								concDecl->get_members() );
+			substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, 	concDecl->get_members() );
 			DeclMutator::addDeclaration( concDecl );
-			instantiations.insert( inst, concDecl );
+			instantiations.insert( inst, typeSubs, concDecl );
 		}
 		StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
 		newInst->set_baseStruct( concDecl );
+
+		deleteAll( typeSubs );
 		delete inst;
 		return newInst;
@@ -205,26 +266,82 @@
 		// exit early if no need for further mutation
 		if ( inst->get_parameters().empty() ) return inst;
-
+		assert( inst->get_baseParameters() && "Base union has parameters" );
+
+		// check if type can be concretely instantiated; put substitutions into typeSubs
+		std::list< TypeExpr* > typeSubs;
+		if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
+			deleteAll( typeSubs );
+			return inst;
+		}
+		
 		// make concrete instantiation of generic type
-		UnionDecl *concDecl = instantiations.lookup( inst );
+		UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
 		if ( ! concDecl ) {
 			// set concDecl to new type, insert type declaration into statements to add
-			assert( inst->get_baseParameters() && "Base union has parameters" );
 			concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
-			substituteMembers( inst->get_baseUnion()->get_members(),
-								*inst->get_baseParameters(), inst->get_parameters(),
-								concDecl->get_members() );
+			substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
 			DeclMutator::addDeclaration( concDecl );
-			instantiations.insert( inst, concDecl );
+			instantiations.insert( inst, typeSubs, concDecl );
 		}
 		UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
 		newInst->set_baseUnion( concDecl );
+
+		deleteAll( typeSubs );
 		delete inst;
 		return newInst;
 	}
+
+// 	/// Gets the base struct or union declaration for a member expression; NULL if not applicable
+// 	AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
+// 		// get variable for member aggregate
+// 		VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
+// 		if ( ! varExpr ) return NULL;
+// 
+// 		// get object for variable
+// 		ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
+// 		if ( ! objectDecl ) return NULL;
+// 
+// 		// get base declaration from object type
+// 		Type *objectType = objectDecl->get_type();
+// 		StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
+// 		if ( structType ) return structType->get_baseStruct();
+// 		UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
+// 		if ( unionType ) return unionType->get_baseUnion();
+// 
+// 		return NULL;
+// 	}
+// 
+// 	/// Finds the declaration with the given name, returning decls.end() if none such
+// 	std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
+// 		for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
+// 			if ( (*decl)->get_name() == name ) return decl;
+// 		}
+// 		return decls.end();
+// 	}
+// 	
+// 	Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
+// 		// mutate, exiting early if no longer MemberExpr
+// 		Expression *expr = Mutator::mutate( memberExpr );
+// 		memberExpr = dynamic_cast< MemberExpr* >( expr );
+// 		if ( ! memberExpr ) return expr;
+// 
+// 		// get declaration of member and base declaration of member, exiting early if not found
+// 		AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
+// 		if ( ! memberBase ) return memberExpr;
+// 		DeclarationWithType *memberDecl = memberExpr->get_member();
+// 		std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
+// 		if ( baseIt == memberBase->get_members().end() ) return memberExpr;
+// 		DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
+// 		if ( ! baseDecl ) return memberExpr;
+// 
+// 		// check if stated type of the member is not the type of the member's declaration; if so, need a cast
+// 		// this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
+// 		SymTab::Indexer dummy;
+// 		if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
+// 		else return new CastExpr( memberExpr, memberDecl->get_type() );
+// 	}
 	
 	void Instantiate::doBeginScope() {
 		DeclMutator::doBeginScope();
-		// push a new concrete type scope
 		instantiations.beginScope();
 	}
@@ -232,5 +349,4 @@
 	void Instantiate::doEndScope() {
 		DeclMutator::doEndScope();
-		// pop the last concrete type scope
 		instantiations.endScope();
 	}
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/Lvalue.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -35,4 +35,5 @@
 		const std::list<Label> noLabels;
 
+		/// Replace uses of lvalue returns with appropriate pointers
 		class Pass1 : public Mutator {
 		  public:
@@ -46,4 +47,5 @@
 		};
 
+		/// Replace declarations of lvalue returns with appropriate pointers
 		class Pass2 : public Visitor {
 		  public:
Index: src/GenPoly/ScrubTyVars.cc
===================================================================
--- src/GenPoly/ScrubTyVars.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/ScrubTyVars.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -14,6 +14,11 @@
 //
 
+#include <sstream>
+#include <string>
+
 #include "GenPoly.h"
 #include "ScrubTyVars.h"
+
+#include "SymTab/Mangler.h"
 
 #include "SynTree/Mutator.h"
@@ -42,10 +47,20 @@
 
 	Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
-		// sizeof( T ) => T parameter, which is the size of T
+		// sizeof( T ) => _sizeof_T parameter, which is the size of T
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
-			Expression *expr = new NameExpr( typeInst->get_name() );
+			Expression *expr = new NameExpr( sizeofName( typeInst ) );
 			return expr;
 		} else {
 			return Mutator::mutate( szeof );
+		} // if
+	}
+
+	Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
+		// alignof( T ) => _alignof_T parameter, which is the alignment of T
+		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( algnof->get_type() ) ) {
+			Expression *expr = new NameExpr( alignofName( typeInst ) );
+			return expr;
+		} else {
+			return Mutator::mutate( algnof );
 		} // if
 	}
@@ -63,4 +78,12 @@
 		return Mutator::mutate( pointer );
 	}
+	
+	std::string sizeofName( Type *ty ) {
+		return std::string( "_sizeof_" ) + SymTab::Mangler::mangle( ty, false, false );
+	}
+
+	std::string alignofName( Type *ty ) {
+		return std::string( "_alignof_" ) + SymTab::Mangler::mangle( ty, false, false );
+	}
 } // namespace GenPoly
 
Index: src/GenPoly/ScrubTyVars.h
===================================================================
--- src/GenPoly/ScrubTyVars.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/GenPoly/ScrubTyVars.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -17,4 +17,6 @@
 #define _SCRUBTYVARS_H
 
+#include <string>
+
 #include "GenPoly.h"
 
@@ -26,7 +28,9 @@
 	  public:
 		ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
-  
+
+		/// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars`
 		template< typename SynTreeClass >
 		static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
+		/// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable
 		template< typename SynTreeClass >
 		static SynTreeClass *scrub( SynTreeClass *target );
@@ -34,4 +38,5 @@
 		virtual Type* mutate( TypeInstType *typeInst );
 		Expression* mutate( SizeofExpr *szeof );
+		Expression* mutate( AlignofExpr *algnof );
 		virtual Type* mutate( PointerType *pointer );
 	  private:
@@ -54,4 +59,10 @@
 		return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );
 	}
+
+	/// Gets the name of the sizeof parameter for the type
+	std::string sizeofName( Type *ty );
+
+	/// Gets the name of the alignof parameter for the type
+	std::string alignofName( Type *ty );
 } // namespace GenPoly
 
Index: src/InitTweak/InitModel.h
===================================================================
--- src/InitTweak/InitModel.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/InitTweak/InitModel.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -72,4 +72,5 @@
 			void visit( ConstantExpr * );
 			void visit( SizeofExpr * ) { throw 0; }
+			void visit( AlignofExpr * ) { throw 0; }
 			void visit( AttrExpr * ) { throw 0; }
 			void visit( LogicalExpr * ) { throw 0; }
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/Parser/ExpressionNode.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -586,8 +586,13 @@
 		}
 	  case OperatorNode::AlignOf:
+		{
+			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
+				return new AlignofExpr( arg->get_decl()->buildType());
+			} else {
+				return new AlignofExpr( args.front());
+			} // if
+		}
 	  case OperatorNode::SizeOf:
 		{
-/// 	bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
-
 			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
 				return new SizeofExpr( arg->get_decl()->buildType());
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -792,4 +792,23 @@
 	}
 
+	void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
+		if ( alignofExpr->get_isType() ) {
+			alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
+		} else {
+			// find all alternatives for the argument to sizeof
+			AlternativeFinder finder( indexer, env );
+			finder.find( alignofExpr->get_expr() );
+			// find the lowest cost alternative among the alternatives, otherwise ambiguous
+			AltList winners;
+			findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
+			if ( winners.size() != 1 ) {
+				throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() );
+			} // if
+			// return the lowest cost alternative for the argument
+			Alternative &choice = winners.front();
+			alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
+		} // if
+	}
+
 	void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
 		// assume no polymorphism
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -56,4 +56,5 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *sizeofExpr );
 		virtual void visit( AttrExpr *attrExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SymTab/Indexer.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -215,4 +215,13 @@
 		} else {
 			maybeAccept( sizeofExpr->get_expr(), *this );
+		}
+	}
+
+	void Indexer::visit( AlignofExpr *alignofExpr ) {
+		acceptAllNewScope( alignofExpr->get_results(), *this );
+		if ( alignofExpr->get_isType() ) {
+			maybeAccept( alignofExpr->get_type(), *this );
+		} else {
+			maybeAccept( alignofExpr->get_expr(), *this );
 		}
 	}
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SymTab/Indexer.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -54,4 +54,5 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *alignofExpr );
 		virtual void visit( AttrExpr *attrExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SymTab/Mangler.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -30,11 +30,7 @@
 
 namespace SymTab {
-	Mangler::Mangler( bool mangleOverridable ) : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ) {
-	}
-
-//Mangler::Mangler( const Mangler & )
-//  : mangleName(), varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( isTopLevel )
-//{
-//}
+	Mangler::Mangler( bool mangleOverridable, bool includeQualifiers )
+		: nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), includeQualifiers(includeQualifiers) {}
+		
 	Mangler::Mangler( const Mangler &rhs ) : mangleName() {
 		varNums = rhs.varNums;
@@ -42,4 +38,5 @@
 		isTopLevel = rhs.isTopLevel;
 		mangleOverridable = rhs.mangleOverridable;
+		includeQualifiers = rhs.includeQualifiers;
 	}
 
@@ -209,4 +206,7 @@
 
 	void Mangler::printQualifiers( Type *type ) {
+		// skip if not including qualifiers
+		if ( ! includeQualifiers ) return;
+		
 		if ( ! type->get_forall().empty() ) {
 			std::list< std::string > assertionNames;
@@ -227,5 +227,5 @@
 				varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
 				for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
-					Mangler sub_mangler( mangleOverridable );
+					Mangler sub_mangler( mangleOverridable, includeQualifiers );
 					sub_mangler.nextVarNum = nextVarNum;
 					sub_mangler.isTopLevel = false;
Index: src/SymTab/Mangler.h
===================================================================
--- src/SymTab/Mangler.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SymTab/Mangler.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -22,10 +22,10 @@
 
 namespace SymTab {
+	/// Mangles names to a unique C identifier
 	class Mangler : public Visitor {
 	  public:
 		template< typename SynTreeClass >
-	    static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true ); // interface to clients
+	    static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool includeQualifiers = true ); // interface to clients
 
-///   using Visitor::visit;
 		virtual void visit( ObjectDecl *declaration );
 		virtual void visit( FunctionDecl *declaration );
@@ -45,12 +45,13 @@
 		std::string get_mangleName() { return mangleName.str(); }
 	  private:
-		std::ostringstream mangleName;
+		std::ostringstream mangleName;  ///< Mangled name being constructed
 		typedef std::map< std::string, std::pair< int, int > > VarMapType;
-		VarMapType varNums;
-		int nextVarNum;
-		bool isTopLevel;
-		bool mangleOverridable;
+		VarMapType varNums;             ///< Map of type variables to indices
+		int nextVarNum;                 ///< Next type variable index
+		bool isTopLevel;                ///< Is the Mangler at the top level
+		bool mangleOverridable;         ///< Specially mangle overridable built-in methods
+		bool includeQualifiers;         ///< Include type qualifiers in mangled name
   
-		Mangler( bool mangleOverridable );
+		Mangler( bool mangleOverridable, bool includeQualifiers );
 		Mangler( const Mangler & );
   
@@ -62,6 +63,6 @@
 
 	template< typename SynTreeClass >
-	std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable ) {
-		Mangler mangler( mangleOverridable );
+	std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool includeQualifiers ) {
+		Mangler mangler( mangleOverridable, includeQualifiers );
 		maybeAccept( decl, mangler );
 		return mangler.get_mangleName();
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/Expression.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -122,4 +122,35 @@
 void SizeofExpr::print( std::ostream &os, int indent) const {
 	os << std::string( indent, ' ' ) << "Sizeof Expression on: ";
+
+	if (isType)
+		type->print(os, indent + 2);
+	else
+		expr->print(os, indent + 2);
+
+	os << std::endl;
+	Expression::print( os, indent );
+}
+
+AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
+		Expression( _aname ), expr(expr_), type(0), isType(false) {
+	add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
+		Expression( _aname ), expr(0), type(type_), isType(true) {
+	add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
+	Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
+}
+
+AlignofExpr::~AlignofExpr() {
+	delete expr;
+	delete type;
+}
+
+void AlignofExpr::print( std::ostream &os, int indent) const {
+	os << std::string( indent, ' ' ) << "Alignof Expression on: ";
 
 	if (isType)
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/Expression.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -23,4 +23,5 @@
 #include "Constant.h"
 
+/// Expression is the root type for all expressions
 class Expression {
   public:
@@ -47,7 +48,6 @@
 };
 
-// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
-// but subject to decay-to-pointer and type parameter renaming
-
+/// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
+/// but subject to decay-to-pointer and type parameter renaming
 struct ParamEntry {
 	ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
@@ -65,7 +65,6 @@
 typedef std::map< UniqueId, ParamEntry > InferredParams;
 
-// ApplicationExpr represents the application of a function to a set of parameters.  This is the
-// result of running an UntypedExpr through the expression analyzer.
-
+/// ApplicationExpr represents the application of a function to a set of parameters.  This is the
+/// result of running an UntypedExpr through the expression analyzer.
 class ApplicationExpr : public Expression {
   public:
@@ -89,8 +88,7 @@
 };
 
-// UntypedExpr represents the application of a function to a set of parameters, but where the
-// particular overload for the function name has not yet been determined.  Most operators are
-// converted into functional form automatically, to permit operator overloading.
-
+/// UntypedExpr represents the application of a function to a set of parameters, but where the
+/// particular overload for the function name has not yet been determined.  Most operators are
+/// converted into functional form automatically, to permit operator overloading.
 class UntypedExpr : public Expression {
   public:
@@ -118,5 +116,5 @@
 };
 
-// this class contains a name whose meaning is still not determined
+/// NameExpr contains a name whose meaning is still not determined
 class NameExpr : public Expression {
   public:
@@ -139,5 +137,5 @@
 // function-call format.
 
-// AddressExpr represents a address-of expression, e.g. &e
+/// AddressExpr represents a address-of expression, e.g. &e
 class AddressExpr : public Expression {
   public:
@@ -174,5 +172,5 @@
 };
 
-// CastExpr represents a type cast expression, e.g. (int)e
+/// CastExpr represents a type cast expression, e.g. (int)e
 class CastExpr : public Expression {
   public:
@@ -193,5 +191,5 @@
 };
 
-// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
+/// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
 class UntypedMemberExpr : public Expression {
   public:
@@ -214,5 +212,5 @@
 };
 
-// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
+/// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
 class MemberExpr : public Expression {
   public:
@@ -235,5 +233,5 @@
 };
 
-// VariableExpr represents an expression that simply refers to the value of a named variable
+/// VariableExpr represents an expression that simply refers to the value of a named variable
 class VariableExpr : public Expression {
   public:
@@ -253,5 +251,5 @@
 };
 
-// ConstantExpr represents an expression that simply refers to the value of a constant 
+/// ConstantExpr represents an expression that simply refers to the value of a constant 
 class ConstantExpr : public Expression {
   public:
@@ -271,5 +269,5 @@
 };
 
-// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
+/// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
 class SizeofExpr : public Expression {
   public:
@@ -296,5 +294,30 @@
 };
 
-// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
+/// AlignofExpr represents an alignof expression
+class AlignofExpr : public Expression {
+  public:
+	AlignofExpr( Expression *expr, Expression *_aname = 0 );
+	AlignofExpr( const AlignofExpr &other );
+	AlignofExpr( Type *type, Expression *_aname = 0 );
+	virtual ~AlignofExpr();
+
+	Expression *get_expr() const { return expr; }
+	void set_expr( Expression *newValue ) { expr = newValue; }
+	Type *get_type() const { return type; }
+	void set_type( Type *newValue ) { type = newValue; }
+	bool get_isType() const { return isType; }
+	void set_isType( bool newValue ) { isType = newValue; }
+
+	virtual AlignofExpr *clone() const { return new AlignofExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	Expression *expr;
+	Type *type;
+	bool isType;
+};
+
+/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
 class AttrExpr : public Expression {
   public:
@@ -324,5 +347,5 @@
 };
 
-// LogicalExpr represents a short-circuit boolean expression (&& or ||)
+/// LogicalExpr represents a short-circuit boolean expression (&& or ||)
 class LogicalExpr : public Expression {
   public:
@@ -347,5 +370,5 @@
 };
 
-// ConditionalExpr represents the three-argument conditional ( p ? a : b )
+/// ConditionalExpr represents the three-argument conditional ( p ? a : b )
 class ConditionalExpr : public Expression {
   public:
@@ -371,5 +394,5 @@
 };
 
-// CommaExpr represents the sequence operator ( a, b )
+/// CommaExpr represents the sequence operator ( a, b )
 class CommaExpr : public Expression {
   public:
@@ -392,5 +415,5 @@
 };
 
-// TupleExpr represents a tuple expression ( [a, b, c] )
+/// TupleExpr represents a tuple expression ( [a, b, c] )
 class TupleExpr : public Expression {
   public:
@@ -410,5 +433,5 @@
 };
 
-// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
+/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
 class SolvedTupleExpr : public Expression {
   public:
@@ -428,5 +451,5 @@
 };
 
-// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
+/// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
 class TypeExpr : public Expression {
   public:
@@ -446,5 +469,5 @@
 };
 
-// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
+/// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
 class AsmExpr : public Expression {
   public:
@@ -472,5 +495,5 @@
 };
 
-// ValofExpr represents a GCC 'lambda expression'
+/// ValofExpr represents a GCC 'lambda expression'
 class UntypedValofExpr : public Expression {
   public:
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/Mutator.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -251,4 +251,14 @@
 }
 
+Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
+	mutateAll( alignofExpr->get_results(), *this );
+	if ( alignofExpr->get_isType() ) {
+		alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) );
+	} else {
+		alignofExpr->set_expr( maybeMutate( alignofExpr->get_expr(), *this ) );
+	}
+	return alignofExpr;
+}
+
 Expression *Mutator::mutate( AttrExpr *attrExpr ) {
 	mutateAll( attrExpr->get_results(), *this );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/Mutator.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -64,4 +64,5 @@
 	virtual Expression* mutate( ConstantExpr *constantExpr ); 
 	virtual Expression* mutate( SizeofExpr *sizeofExpr );
+	virtual Expression* mutate( AlignofExpr *alignofExpr );
 	virtual Expression* mutate( AttrExpr *attrExpr );
 	virtual Expression* mutate( LogicalExpr *logicalExpr );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/SynTree.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -69,4 +69,5 @@
 class ConstantExpr;
 class SizeofExpr;
+class AlignofExpr;
 class AttrExpr;
 class LogicalExpr;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/Visitor.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -210,4 +210,13 @@
 }
 
+void Visitor::visit( AlignofExpr *alignofExpr ) {
+	acceptAll( alignofExpr->get_results(), *this );
+	if ( alignofExpr->get_isType() ) {
+		maybeAccept( alignofExpr->get_type(), *this );
+	} else {
+		maybeAccept( alignofExpr->get_expr(), *this );
+	}
+}
+
 void Visitor::visit( AttrExpr *attrExpr ) {
 	acceptAll( attrExpr->get_results(), *this );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/SynTree/Visitor.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -64,4 +64,5 @@
 	virtual void visit( ConstantExpr *constantExpr ); 
 	virtual void visit( SizeofExpr *sizeofExpr );
+	virtual void visit( AlignofExpr *alignofExpr );
 	virtual void visit( AttrExpr *attrExpr );
 	virtual void visit( LogicalExpr *logicalExpr );
Index: src/Tuples/FlattenTuple.cc
===================================================================
--- src/Tuples/FlattenTuple.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/Tuples/FlattenTuple.cc	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -46,4 +46,5 @@
 	void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
 	void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( AlignofExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
 	void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
 	void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
Index: src/Tuples/FlattenTuple.h
===================================================================
--- src/Tuples/FlattenTuple.h	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ src/Tuples/FlattenTuple.h	(revision 43899667c202e39bf5ce46a74a02658953fe5bfb)
@@ -42,4 +42,5 @@
 			virtual void visit( ConstantExpr * ); 
 			virtual void visit( SizeofExpr * );
+			virtual void visit( AlignofExpr * );
 			virtual void visit( AttrExpr * );
 			virtual void visit( LogicalExpr * );
Index: c/examples/tests/log.txt
===================================================================
--- src/examples/tests/log.txt	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
+++ 	(revision )
@@ -1,1 +1,0 @@
-    vector_test	PASSED
