From: Tim Keith Date: Fri, 26 Apr 2019 22:06:58 +0000 (-0700) Subject: [flang] Optionally dump all source members of parse tree X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e9b4cf42e472159973f89f6212f2372defb25db4;p=platform%2Fupstream%2Fllvm.git [flang] Optionally dump all source members of parse tree In the parse tree dumper, add a compile-time option to dump source locations for all nodes that have them. This is a useful way to check if they are correct, especially after parse tree rewrites. It is enabled by defining `SHOW_ALL_SOURCE_MEMBERS` in `dump-parse-tree.h`. Original-commit: flang-compiler/f18@ceae5632e2c5ec4d1083fcac4a9ad39b8ba2c1f3 Reviewed-on: https://github.com/flang-compiler/f18/pull/433 Tree-same-pre-rewrite: false --- diff --git a/flang/lib/parser/dump-parse-tree.h b/flang/lib/parser/dump-parse-tree.h index 6f3f024..453098b 100644 --- a/flang/lib/parser/dump-parse-tree.h +++ b/flang/lib/parser/dump-parse-tree.h @@ -21,11 +21,20 @@ #include "../common/indirection.h" #include #include +#include namespace Fortran::parser { using namespace std::string_literals; +// When SHOW_ALL_SOURCE_MEMBERS is defined, HasSource::value is true if T has +// a member named source +template struct HasSource : std::false_type {}; +#ifdef SHOW_ALL_SOURCE_MEMBERS +template +struct HasSource : std::true_type {}; +#endif + // // Dump the Parse Tree hierarchy of any node 'x' of the parse tree. // @@ -711,11 +720,14 @@ public: #undef NODE_NAME template bool Pre(const T &x) { - if (UnionTrait || WrapperTrait) { + if constexpr (!HasSource::value && (UnionTrait || WrapperTrait)) { Prefix(GetNodeName(x)); } else { IndentEmptyLine(); out_ << GetNodeName(x); + if constexpr (HasSource::value) { + out_ << " = '" << x.source.ToString() << '\''; + } EndLine(); ++indent_; } @@ -723,28 +735,25 @@ public: } template void Post(const T &x) { - if (UnionTrait || WrapperTrait) { + if constexpr (!HasSource::value && (UnionTrait || WrapperTrait)) { EndLineIfNonempty(); } else { --indent_; } } - bool PutName(const std::string &name) { + bool Pre(const parser::Name &x) { IndentEmptyLine(); - out_ << "Name = '" << name << '\''; - ++indent_; + out_ << "Name = '" << x.ToString() << '\''; EndLine(); - return true; + return false; + } + bool Pre(const std::string &x) { + IndentEmptyLine(); + out_ << "string = '" << x << '\''; + EndLine(); + return false; } - - bool Pre(const parser::Name &x) { return PutName(x.ToString()); } - - void Post(const parser::Name &) { --indent_; } - - bool Pre(const std::string &x) { return PutName(x); } - - void Post(const std::string &x) { --indent_; } bool Pre(const std::int64_t &x) { IndentEmptyLine(); @@ -759,30 +768,39 @@ public: bool Pre(const std::uint64_t &x) { IndentEmptyLine(); out_ << "int = '" << x << '\''; - ++indent_; EndLine(); - return true; + return false; } - void Post(const std::uint64_t &x) { --indent_; } - bool Pre(const parser::IntLiteralConstant &x) { IndentEmptyLine(); out_ << "int = '" << std::get(x.t).ToString() << '\''; - ++indent_; EndLine(); - return true; + ++indent_; + Walk(std::get>(x.t), *this); + --indent_; + return false; } - void Post(const parser::IntLiteralConstant &) { --indent_; } bool Pre(const parser::SignedIntLiteralConstant &x) { IndentEmptyLine(); out_ << "int = '" << std::get(x.t).ToString() << '\''; + EndLine(); ++indent_; + Walk(std::get>(x.t), *this); + --indent_; + return false; + } + + bool Pre(const parser::RealLiteralConstant &x) { + Prefix(GetNodeName(x)); + out_ << "Real = '" << x.real.source.ToString() << '\''; EndLine(); - return true; + ++indent_; + Walk(x.kind, *this); + --indent_; + return false; } - void Post(const parser::SignedIntLiteralConstant &) { --indent_; } // A few types we want to ignore