aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/typesem.c
blob: 2933e983b019caf458d3b7a56c8d4993c94c6194 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

/* Compiler implementation of the D programming language
 * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
 * written by Walter Bright
 * http://www.digitalmars.com
 * Distributed under the Boost Software License, Version 1.0.
 * http://www.boost.org/LICENSE_1_0.txt
 */

#include "mtype.h"
#include "expression.h"
#include "template.h"

Expression *typeToExpression(Type *t);
Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);

class TypeToExpressionVisitor : public Visitor
{
public:
    Expression *result;
    Type *itype;

    TypeToExpressionVisitor(Type *itype)
    {
        this->result = NULL;
        this->itype = itype;
    }

    void visit(Type *)
    {
        result = NULL;
    }

    void visit(TypeSArray *t)
    {
        Expression *e = typeToExpression(t->next);
        if (e)
            e = new ArrayExp(t->dim->loc, e, t->dim);
        result = e;
    }

    void visit(TypeAArray *t)
    {
        Expression *e = typeToExpression(t->next);
        if (e)
        {
            Expression *ei = typeToExpression(t->index);
            if (ei)
            {
                result = new ArrayExp(t->loc, e, ei);
                return;
            }
        }
        result = NULL;
    }

    void visit(TypeIdentifier *t)
    {
        result = typeToExpressionHelper(t, new IdentifierExp(t->loc, t->ident));
    }

    void visit(TypeInstance *t)
    {
        result = typeToExpressionHelper(t, new ScopeExp(t->loc, t->tempinst));
    }
};

/* We've mistakenly parsed this as a type.
 * Redo it as an Expression.
 * NULL if cannot.
 */
Expression *typeToExpression(Type *t)
{
    TypeToExpressionVisitor v = TypeToExpressionVisitor(t);
    t->accept(&v);
    return v.result;
}

/* Helper function for `typeToExpression`. Contains common code
 * for TypeQualified derived classes.
 */
Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i)
{
    //printf("toExpressionHelper(e = %s %s)\n", Token::toChars(e->op), e->toChars());
    for (; i < t->idents.length; i++)
    {
        RootObject *id = t->idents[i];
        //printf("\t[%d] e: '%s', id: '%s'\n", i, e->toChars(), id->toChars());

        switch (id->dyncast())
        {
            case DYNCAST_IDENTIFIER:
            {
                // ... '. ident'
                e = new DotIdExp(e->loc, e, (Identifier *)id);
                break;
            }
            case DYNCAST_DSYMBOL:
            {
                // ... '. name!(tiargs)'
                TemplateInstance *ti = ((Dsymbol *)id)->isTemplateInstance();
                assert(ti);
                e = new DotTemplateInstanceExp(e->loc, e, ti->name, ti->tiargs);
                break;
            }
            case DYNCAST_TYPE:          // Bugzilla 1215
            {
                // ... '[type]'
                e = new ArrayExp(t->loc, e, new TypeExp(t->loc, (Type *)id));
                break;
            }
            case DYNCAST_EXPRESSION:    // Bugzilla 1215
            {
                // ... '[expr]'
                e = new ArrayExp(t->loc, e, (Expression *)id);
                break;
            }
            default:
                assert(0);
        }
    }
    return e;
}