1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  */
9 
10 #include "mtype.h"
11 #include "expression.h"
12 #include "template.h"
13 
14 Expression *typeToExpression(Type *t);
15 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
16 
17 class TypeToExpressionVisitor : public Visitor
18 {
19 public:
20     Expression *result;
21     Type *itype;
22 
TypeToExpressionVisitor(Type * itype)23     TypeToExpressionVisitor(Type *itype)
24     {
25         this->result = NULL;
26         this->itype = itype;
27     }
28 
visit(Type *)29     void visit(Type *)
30     {
31         result = NULL;
32     }
33 
visit(TypeSArray * t)34     void visit(TypeSArray *t)
35     {
36         Expression *e = typeToExpression(t->next);
37         if (e)
38             e = new ArrayExp(t->dim->loc, e, t->dim);
39         result = e;
40     }
41 
visit(TypeAArray * t)42     void visit(TypeAArray *t)
43     {
44         Expression *e = typeToExpression(t->next);
45         if (e)
46         {
47             Expression *ei = typeToExpression(t->index);
48             if (ei)
49             {
50                 result = new ArrayExp(t->loc, e, ei);
51                 return;
52             }
53         }
54         result = NULL;
55     }
56 
visit(TypeIdentifier * t)57     void visit(TypeIdentifier *t)
58     {
59         result = typeToExpressionHelper(t, new IdentifierExp(t->loc, t->ident));
60     }
61 
visit(TypeInstance * t)62     void visit(TypeInstance *t)
63     {
64         result = typeToExpressionHelper(t, new ScopeExp(t->loc, t->tempinst));
65     }
66 };
67 
68 /* We've mistakenly parsed this as a type.
69  * Redo it as an Expression.
70  * NULL if cannot.
71  */
typeToExpression(Type * t)72 Expression *typeToExpression(Type *t)
73 {
74     TypeToExpressionVisitor v = TypeToExpressionVisitor(t);
75     t->accept(&v);
76     return v.result;
77 }
78 
79 /* Helper function for `typeToExpression`. Contains common code
80  * for TypeQualified derived classes.
81  */
typeToExpressionHelper(TypeQualified * t,Expression * e,size_t i)82 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i)
83 {
84     //printf("toExpressionHelper(e = %s %s)\n", Token::toChars(e->op), e->toChars());
85     for (; i < t->idents.dim; i++)
86     {
87         RootObject *id = t->idents[i];
88         //printf("\t[%d] e: '%s', id: '%s'\n", i, e->toChars(), id->toChars());
89 
90         switch (id->dyncast())
91         {
92             case DYNCAST_IDENTIFIER:
93             {
94                 // ... '. ident'
95                 e = new DotIdExp(e->loc, e, (Identifier *)id);
96                 break;
97             }
98             case DYNCAST_DSYMBOL:
99             {
100                 // ... '. name!(tiargs)'
101                 TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance();
102                 assert(ti);
103                 e = new DotTemplateInstanceExp(e->loc, e, ti->name, ti->tiargs);
104                 break;
105             }
106             case DYNCAST_TYPE:          // Bugzilla 1215
107             {
108                 // ... '[type]'
109                 e = new ArrayExp(t->loc, e, new TypeExp(t->loc, (Type *)id));
110                 break;
111             }
112             case DYNCAST_EXPRESSION:    // Bugzilla 1215
113             {
114                 // ... '[expr]'
115                 e = new ArrayExp(t->loc, e, (Expression *)id);
116                 break;
117             }
118             default:
119                 assert(0);
120         }
121     }
122     return e;
123 }
124