Index: mtype.c
===================================================================
--- mtype.c	(revision 30)
+++ mtype.c	(working copy)
@@ -182,6 +182,7 @@
     sizeTy[Ttuple] = sizeof(TypeTuple);
     sizeTy[Tslice] = sizeof(TypeSlice);
     sizeTy[Treturn] = sizeof(TypeReturn);
+    sizeTy[Twrap] = sizeof(TypeWrap);
 
     mangleChar[Tarray] = 'A';
     mangleChar[Tsarray] = 'G';
@@ -229,6 +230,7 @@
     mangleChar[Ttuple] = 'B';
     mangleChar[Tslice] = '@';
     mangleChar[Treturn] = '@';
+    mangleChar[Twrap] = '@';
 
     for (i = 0; i < TMAX; i++)
     {	if (!mangleChar[i])
@@ -4773,7 +4775,110 @@
     return s;
 }
 
+/***************************** TypeWrap *****************************/
 
+TypeWrap::TypeWrap(Loc loc, Type *type)
+    : TypeQualified(Twrap, loc)
+{
+    this->type = type;
+}
+
+Type *TypeWrap::syntaxCopy()
+{
+    TypeWrap *t;
+
+    t = new TypeWrap(loc, type->syntaxCopy());
+    t->syntaxCopyHelper(this);
+    t->mod = mod;
+    return t;
+}
+
+void TypeWrap::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
+{
+    if (mod != this->mod)
+    {	toCBuffer3(buf, hgs, mod);
+	return;
+    }
+    type->toCBuffer2(buf, hgs, mod);
+    toCBuffer2Helper(buf, hgs);
+}
+
+void TypeWrap::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
+{
+    Expression *e;
+    Type *t;
+    Dsymbol *s;
+
+    type->resolve(loc, sc, &e, &t, &s);
+    if (idents.dim)
+    {
+	if (!s && e)
+	{
+	    e = e->semantic(sc);
+	    t = e->type;
+	    s = getDsymbol(e);
+	}
+	if (!s && t)
+	{
+	    s = t->toDsymbol(sc);
+	    if (!s)
+	    {
+		s = new AliasDeclaration(loc, Lexer::uniqueId("__T"), t);
+		s->semantic(sc);
+	    }
+	}
+	resolveHelper(loc, sc, s, NULL, pe, pt, ps);
+    }
+    else
+    {
+	*pe = e;
+	*pt = t;
+	*ps = s;
+    }
+
+    if (*pt)
+	(*pt) = (*pt)->addMod(mod);
+}
+
+Type *TypeWrap::semantic(Loc loc, Scope *sc)
+{
+    Expression *e;
+    Type *t;
+    Dsymbol *s;
+
+    resolve(loc, sc, &e, &t, &s);
+    if (t == NULL)
+    {
+	error(loc, "%s is used as a type", toChars());
+	t = tvoid;
+    }
+    return t;
+}
+
+Dsymbol *TypeWrap::toDsymbol(Scope *sc)
+{
+    Expression *e;
+    Type *t;
+    Dsymbol *s;
+
+    resolve(loc, sc, &e, &t, &s);
+    if (e) s = getDsymbol(e);
+    if (t) s = t->toDsymbol(sc);
+    return s;
+}
+
+Expression *TypeWrap::toExpression()
+{
+    Expression *e = new TypeExp(loc, type);
+    for (size_t i = 0; i < idents.dim; i++)
+    {
+	Identifier *id = (Identifier *)idents.data[i];
+	e = new DotIdExp(loc, e, id);
+    }
+    return e;
+}
+
+
 /***************************** TypeTypeof *****************************/
 
 TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
Index: mtype.h
===================================================================
--- mtype.h	(revision 19)
+++ mtype.h	(working copy)
@@ -97,6 +97,7 @@
     Ttuple,
     Tslice,
     Treturn,
+    Twrap,
     TMAX
 };
 typedef unsigned char TY;	// ENUMTY
@@ -590,6 +591,19 @@
     MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
 };
 
+struct TypeWrap : TypeQualified
+{
+    Type *type;
+
+    TypeWrap(Loc loc, Type *type);
+    Type *syntaxCopy();
+    void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
+    void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
+    Type *semantic(Loc loc, Scope *sc);
+    Dsymbol *toDsymbol(Scope *sc);
+    Expression *toExpression();
+};
+
 struct TypeTypeof : TypeQualified
 {
     Expression *exp;
Index: parse.c
===================================================================
--- parse.c	(revision 19)
+++ parse.c	(working copy)
@@ -2199,6 +2199,9 @@
  *	t [expression .. expression]
  *	t function
  *	t delegate
+ *	t . ident
+ *	t . ident ! ident
+ *	t . ident ! ( template_arguments )
  */
 
 Type *Parser::parseBasicType2(Type *t)
@@ -2213,6 +2216,37 @@
 		nextToken();
 		continue;
 
+	    case TOKdot:
+	    {
+		TypeWrap *tw = new TypeWrap(loc, t);
+		while (token.value == TOKdot)
+		{
+		    nextToken();
+		    if (token.value != TOKidentifier)
+		    {   error("identifier expected following '.' instead of '%s'", token.toChars());
+			goto Lend;
+		    }
+		    Identifier *id = token.ident;
+		    nextToken();
+		    if (token.value == TOKnot)
+		    {
+			TemplateInstance *tempinst = new TemplateInstance(loc, id);
+			nextToken();
+			if (token.value == TOKlparen)
+			    // ident!(template_arguments)
+			    tempinst->tiargs = parseTemplateArgumentList();
+			else
+			    // ident!template_argument
+			    tempinst->tiargs = parseTemplateArgument();
+			tw->addIdent((Identifier *)tempinst);
+		    }
+		    else
+			tw->addIdent(id);
+		}
+		t = tw;
+		continue;
+	    }
+
 	    case TOKlbracket:
 		// Handle []. Make sure things like
 		//     int[3][1] a;
@@ -2282,6 +2316,7 @@
 		continue;
 	    }
 
+	    Lend:
 	    default:
 		return t;
 	}
@@ -4207,6 +4242,19 @@
 		t = peek(t);
 		continue;
 
+	    case TOKdot:
+		t = peek(t);
+		if (t->value != TOKidentifier)
+		    return FALSE;
+		if (peek(t)->value == TOKnot)
+		{
+		    if (!isTemplateInstance(t, &t))
+			return false;
+		}
+		else
+		    t = peek(t);
+		continue;
+
 	    case TOKlbracket:
 		t = peek(t);
 		if (t->value == TOKrbracket)
