OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [go/] [gofrontend/] [ast-dump.cc] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 714 jeremybenn
// ast-dump.cc -- AST debug dump.    -*- C++ -*-
2
 
3
// Copyright 2011 The Go Authors. All rights reserved.
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file.
6
 
7
#include "go-system.h"
8
 
9
#include <iostream>
10
#include <fstream>
11
 
12
#include "gogo.h"
13
#include "expressions.h"
14
#include "statements.h"
15
#include "types.h"
16
#include "ast-dump.h"
17
#include "go-c.h"
18
#include "go-dump.h"
19
 
20
// The -fgo-dump-ast flag to activate AST dumps.
21
 
22
Go_dump ast_dump_flag("ast");
23
 
24
// This class is used to traverse the tree to look for blocks and
25
// function headers.
26
 
27
class Ast_dump_traverse_blocks_and_functions : public Traverse
28
{
29
 public:
30
  Ast_dump_traverse_blocks_and_functions(Ast_dump_context* ast_dump_context)
31
      : Traverse(traverse_blocks | traverse_functions),
32
      ast_dump_context_(ast_dump_context)
33
  { }
34
 
35
 protected:
36
  int
37
  block(Block*);
38
 
39
  int
40
  function(Named_object*);
41
 
42
 private:
43
  Ast_dump_context* ast_dump_context_;
44
};
45
 
46
// This class is used to traverse the tree to look for statements.
47
 
48
class Ast_dump_traverse_statements : public Traverse
49
{
50
 public:
51
  Ast_dump_traverse_statements(Ast_dump_context* ast_dump_context)
52
      : Traverse(traverse_statements),
53
      ast_dump_context_(ast_dump_context)
54
  { }
55
 
56
 protected:
57
  int
58
  statement(Block*, size_t* pindex, Statement*);
59
 
60
 private:
61
  Ast_dump_context* ast_dump_context_;
62
};
63
 
64
// For each block we enclose it in brackets.
65
 
66
int Ast_dump_traverse_blocks_and_functions::block(Block * block)
67
{
68
  this->ast_dump_context_->print_indent();
69
  this->ast_dump_context_->ostream() << "{" << std::endl;
70
  this->ast_dump_context_->indent();
71
 
72
  // Dump statememts.
73
  Ast_dump_traverse_statements adts(this->ast_dump_context_);
74
  block->traverse(&adts);
75
 
76
  this->ast_dump_context_->unindent();
77
  this->ast_dump_context_->print_indent();
78
  this->ast_dump_context_->ostream() << "}" << std::endl;
79
 
80
  return TRAVERSE_SKIP_COMPONENTS;
81
}
82
 
83
// Dump each traversed statement.
84
 
85
int
86
Ast_dump_traverse_statements::statement(Block* block, size_t* pindex,
87
                                        Statement* statement)
88
{
89
  statement->dump_statement(this->ast_dump_context_);
90
 
91
  if (statement->is_block_statement())
92
    {
93
      Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
94
      statement->traverse(block, pindex, &adtbf);
95
    }
96
 
97
  return TRAVERSE_SKIP_COMPONENTS;
98
}
99
 
100
// Dump the function header.
101
 
102
int
103
Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
104
{
105
  this->ast_dump_context_->ostream() << no->name();
106
 
107
  go_assert(no->is_function());
108
  Function* func = no->func_value();
109
 
110
  this->ast_dump_context_->ostream() << "(";
111
  this->ast_dump_context_->dump_typed_identifier_list(
112
                              func->type()->parameters());
113
 
114
  this->ast_dump_context_->ostream() << ")";
115
 
116
  Function::Results* res = func->result_variables();
117
  if (res != NULL && !res->empty())
118
    {
119
      this->ast_dump_context_->ostream() << " (";
120
 
121
      for (Function::Results::const_iterator it = res->begin();
122
          it != res->end();
123
          it++)
124
        {
125
          if (it != res->begin())
126
            this->ast_dump_context_->ostream() << ",";
127
          Named_object* no = (*it);
128
 
129
          this->ast_dump_context_->ostream() << no->name() << " ";
130
          go_assert(no->is_result_variable());
131
          Result_variable* resvar = no->result_var_value();
132
 
133
          this->ast_dump_context_->dump_type(resvar->type());
134
 
135
        }
136
      this->ast_dump_context_->ostream() << ")";
137
    }
138
 
139
  this->ast_dump_context_->ostream() << " : ";
140
  this->ast_dump_context_->dump_type(func->type());
141
  this->ast_dump_context_->ostream() << std::endl;
142
 
143
  return TRAVERSE_CONTINUE;
144
}
145
 
146
// Class Ast_dump_context.
147
 
148
Ast_dump_context::Ast_dump_context(std::ostream* out /* = NULL */,
149
                                   bool dump_subblocks /* = true */)
150
  :  indent_(0), dump_subblocks_(dump_subblocks), ostream_(out), gogo_(NULL)
151
{
152
}
153
 
154
// Dump files will be named %basename%.dump.ast
155
 
156
const char* kAstDumpFileExtension = ".dump.ast";
157
 
158
// Dump the internal representation.
159
 
160
void
161
Ast_dump_context::dump(Gogo* gogo, const char* basename)
162
{
163
  std::ofstream* out = new std::ofstream();
164
  std::string dumpname(basename);
165
  dumpname += ".dump.ast";
166
  out->open(dumpname.c_str());
167
 
168
  if (out->fail())
169
    {
170
      error("cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
171
      return;
172
    }
173
 
174
  this->gogo_ = gogo;
175
  this->ostream_ = out;
176
 
177
  Ast_dump_traverse_blocks_and_functions adtbf(this);
178
  gogo->traverse(&adtbf);
179
 
180
  out->close();
181
}
182
 
183
// Dump a textual representation of a type to the
184
// the dump file.
185
 
186
void
187
Ast_dump_context::dump_type(const Type* t)
188
{
189
  if (t == NULL)
190
    this->ostream() << "(nil type)";
191
  else
192
    // FIXME: write a type pretty printer instead of
193
    // using mangled names.
194
    if (this->gogo_ != NULL)
195
      this->ostream() << "(" << t->mangled_name(this->gogo_) <<  ")";
196
}
197
 
198
// Dump a textual representation of a block to the
199
// the dump file.
200
 
201
void
202
Ast_dump_context::dump_block(Block* b)
203
{
204
  Ast_dump_traverse_blocks_and_functions adtbf(this);
205
  b->traverse(&adtbf);
206
}
207
 
208
// Dump a textual representation of an expression to the
209
// the dump file.
210
 
211
void
212
Ast_dump_context::dump_expression(const Expression* e)
213
{
214
  e->dump_expression(this);
215
}
216
 
217
// Dump a textual representation of an expression list to the
218
// the dump file.
219
 
220
void
221
Ast_dump_context::dump_expression_list(const Expression_list* el,
222
                                       bool as_pairs /* = false */)
223
{
224
  if (el == NULL)
225
    return;
226
 
227
  for (std::vector<Expression*>::const_iterator it = el->begin();
228
       it != el->end();
229
       it++)
230
    {
231
      if ( it != el->begin())
232
        this->ostream() << ",";
233
      if (*it != NULL)
234
        (*it)->dump_expression(this);
235
      else
236
        this->ostream() << "NULL";
237
      if (as_pairs)
238
        {
239
          this->ostream() << ":";
240
          ++it;
241
          (*it)->dump_expression(this);
242
        }
243
    }
244
}
245
 
246
// Dump a textual representation of a typed identifier to the
247
// the dump file.
248
 
249
void
250
Ast_dump_context::dump_typed_identifier(const Typed_identifier* ti)
251
{
252
  this->ostream() << ti->name() << " ";
253
  this->dump_type(ti->type());
254
}
255
 
256
// Dump a textual representation of a typed identifier list to the
257
// the dump file.
258
 
259
void
260
Ast_dump_context::dump_typed_identifier_list(
261
    const Typed_identifier_list* ti_list)
262
{
263
  if (ti_list == NULL)
264
    return;
265
 
266
  for (Typed_identifier_list::const_iterator it = ti_list->begin();
267
       it != ti_list->end();
268
       it++)
269
    {
270
      if (it != ti_list->begin())
271
        this->ostream() << ",";
272
      this->dump_typed_identifier(&(*it));
273
    }
274
}
275
 
276
// Dump a textual representation of a temporary variable to the
277
// the dump file.
278
 
279
void
280
Ast_dump_context::dump_temp_variable_name(const Statement* s)
281
{
282
  go_assert(s->classification() == Statement::STATEMENT_TEMPORARY);
283
  // Use the statement address as part of the name for the temporary variable.
284
  this->ostream() << "tmp." << (uintptr_t) s;
285
}
286
 
287
// Dump a textual representation of a label to the
288
// the dump file.
289
 
290
void
291
Ast_dump_context::dump_label_name(const Unnamed_label* l)
292
{
293
  // Use the unnamed label address as part of the name for the temporary
294
  // variable.
295
  this->ostream() << "label." << (uintptr_t) l;
296
}
297
 
298
// Produce a textual representation of an operator symbol.
299
 
300
static const char*
301
op_string(Operator op)
302
{
303
// FIXME: This should be in line with symbols that are parsed,
304
// exported and/or imported.
305
  switch (op)
306
    {
307
    case OPERATOR_PLUS:
308
      return "+";
309
    case OPERATOR_MINUS:
310
      return "-";
311
    case OPERATOR_NOT:
312
      return "!";
313
    case OPERATOR_XOR:
314
      return "^";
315
    case OPERATOR_OR:
316
      return "|";
317
    case OPERATOR_AND:
318
      return "&";
319
    case OPERATOR_MULT:
320
      return "*";
321
    case OPERATOR_OROR:
322
      return "||";
323
    case OPERATOR_ANDAND:
324
      return "&&";
325
    case OPERATOR_EQEQ:
326
      return "==";
327
    case OPERATOR_NOTEQ:
328
      return "!=";
329
    case OPERATOR_LT:
330
      return "<";
331
    case OPERATOR_LE:
332
      return "<=";
333
    case OPERATOR_GT:
334
      return ">";
335
    case OPERATOR_GE:
336
      return ">=";
337
    case OPERATOR_DIV:
338
      return "/";
339
    case OPERATOR_MOD:
340
      return "%";
341
    case OPERATOR_LSHIFT:
342
      return "<<";
343
    case OPERATOR_RSHIFT:
344
      return "//";
345
    case OPERATOR_BITCLEAR:
346
      return "&^";
347
    case OPERATOR_CHANOP:
348
      return "<-";
349
    case OPERATOR_PLUSEQ:
350
      return "+=";
351
    case OPERATOR_MINUSEQ:
352
      return "-=";
353
    case OPERATOR_OREQ:
354
      return "|=";
355
    case OPERATOR_XOREQ:
356
      return "^=";
357
    case OPERATOR_MULTEQ:
358
      return "*=";
359
    case OPERATOR_DIVEQ:
360
      return "/=";
361
    case OPERATOR_MODEQ:
362
      return "%=";
363
    case OPERATOR_LSHIFTEQ:
364
      return "<<=";
365
    case OPERATOR_RSHIFTEQ:
366
      return ">>=";
367
    case OPERATOR_ANDEQ:
368
      return "&=";
369
    case OPERATOR_BITCLEAREQ:
370
      return "&^=";
371
    case OPERATOR_PLUSPLUS:
372
      return "++";
373
    case OPERATOR_MINUSMINUS:
374
      return "--";
375
    case OPERATOR_COLON:
376
      return ":";
377
    case OPERATOR_COLONEQ:
378
      return ":=";
379
    case OPERATOR_SEMICOLON:
380
      return ";";
381
    case OPERATOR_DOT:
382
      return ".";
383
    case OPERATOR_ELLIPSIS:
384
      return "...";
385
    case OPERATOR_COMMA:
386
      return ",";
387
    case OPERATOR_LPAREN:
388
      return "(";
389
    case OPERATOR_RPAREN:
390
      return ")";
391
    case OPERATOR_LCURLY:
392
      return "{";
393
    case OPERATOR_RCURLY:
394
      return "}";
395
    case OPERATOR_LSQUARE:
396
      return "[";
397
    case OPERATOR_RSQUARE:
398
      return "]";
399
    default:
400
      go_unreachable();
401
    }
402
  return NULL;
403
}
404
 
405
// Dump a textual representation of an operator to the
406
// the dump file.
407
 
408
void
409
Ast_dump_context::dump_operator(Operator op)
410
{
411
  this->ostream() << op_string(op);
412
}
413
 
414
// Size of a single indent.
415
 
416
const int Ast_dump_context::offset_ = 2;
417
 
418
// Print indenting spaces to dump file.
419
 
420
void
421
Ast_dump_context::print_indent()
422
{
423
  for (int i = 0; i < this->indent_ * this->offset_; i++)
424
    this->ostream() << " ";
425
}
426
 
427
// Dump a textual representation of the ast to the
428
// the dump file.
429
 
430
void Gogo::dump_ast(const char* basename)
431
{
432
  if (::ast_dump_flag.is_enabled())
433
    {
434
      Ast_dump_context adc;
435
      adc.dump(this, basename);
436
    }
437
}
438
 
439
// Implementation of String_dump interface.
440
 
441
void
442
Ast_dump_context::write_c_string(const char* s)
443
{
444
  this->ostream() << s;
445
}
446
 
447
void
448
Ast_dump_context::write_string(const std::string& s)
449
{
450
  this->ostream() << s;
451
}
452
 
453
// Dump statment to stream.
454
 
455
void
456
Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
457
{
458
  Ast_dump_context adc(out, false);
459
  stm->dump_statement(&adc);
460
}
461
 
462
// Dump expression to stream.
463
 
464
void
465
Ast_dump_context::dump_to_stream(const Expression* expr, std::ostream* out)
466
{
467
  Ast_dump_context adc(out, false);
468
  expr->dump_expression(&adc);
469
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.