/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /*! * \file source_map.h * \brief A map from source names to source code. */ #ifndef TVM_IR_SOURCE_MAP_H_ #define TVM_IR_SOURCE_MAP_H_ #include #include #include #include #include #include #include #include namespace tvm { /*! * \brief The source name in the Span * \sa SourceNameNode, Span */ class SourceName; /*! * \brief The name of a source fragment. */ class SourceNameNode : public ffi::Object { public: /*! \brief The source name. */ ffi::String name; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("name", &SourceNameNode::name); } static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode; TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.SourceName", SourceNameNode, ffi::Object); }; /*! * \brief The source name of a file span. * \sa SourceNameNode, Span */ class SourceName : public ffi::ObjectRef { public: /*! * \brief Get an SourceName for a given operator name. * Will raise an error if the source name has not been registered. * \param name Name of the operator. * \return SourceName valid throughout program lifetime. */ TVM_DLL static SourceName Get(const ffi::String& name); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(SourceName, ffi::ObjectRef, SourceNameNode); }; /*! * \brief Span information for debugging purposes */ class Span; /*! * \brief Stores locations in frontend source that generated a node. */ class SpanNode : public ffi::Object { public: /*! \brief The source name. */ SourceName source_name; /*! \brief The line number. */ int line; /*! \brief The column offset. */ int column; /*! \brief The end line number. */ int end_line; /*! \brief The end column number. */ int end_column; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("source_name", &SpanNode::source_name) .def_ro("line", &SpanNode::line) .def_ro("column", &SpanNode::column) .def_ro("end_line", &SpanNode::end_line) .def_ro("end_column", &SpanNode::end_column); } static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode; TVM_FFI_DECLARE_OBJECT_INFO("ir.Span", SpanNode, ffi::Object); }; class Span : public ffi::ObjectRef { public: TVM_DLL Span(SourceName source_name, int line, int end_line, int column, int end_column); /*! \brief Merge two spans into one which captures the combined regions. */ TVM_DLL Span Merge(const Span& other) const; TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Span, ffi::ObjectRef, SpanNode); }; /*! * \brief Store a list of spans for an expr generated from mulitple source exprs */ class SequentialSpanNode : public SpanNode { public: /*! \brief The original source list of spans to construct a sequential span. */ ffi::Array spans; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("spans", &SequentialSpanNode::spans); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.SequentialSpan", SequentialSpanNode, SpanNode); }; /*! * \brief Reference class of SequentialSpanNode. * \sa SequentialSpanNode */ class SequentialSpan : public Span { public: TVM_DLL SequentialSpan(ffi::Array spans); TVM_DLL SequentialSpan(std::initializer_list init); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(SequentialSpan, Span, SequentialSpanNode); }; /*! \brief A program source in any language. * * Could represent the source from an ML framework or a source * representing a tvm::IRModule. */ class Source; class SourceNode : public ffi::Object { public: /*! \brief The source name. */ SourceName source_name; /*! \brief The raw source. */ ffi::String source; /*! \brief A mapping of line breaks into the raw source. */ std::vector> line_map; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef() .def_ro("source_name", &SourceNode::source_name) .def_ro("source", &SourceNode::source); } TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.Source", SourceNode, ffi::Object); }; class Source : public ffi::ObjectRef { public: TVM_DLL Source(SourceName src_name, std::string source); TVM_DLL tvm::ffi::String GetLine(int line); TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(Source, ffi::ObjectRef, SourceNode); }; /*! * \brief A mapping from a unique source name to source fragment. */ class SourceMap; /*! * \brief Stores locations in frontend source that generated a node. */ class SourceMapObj : public ffi::Object { public: /*! \brief The source mapping. */ ffi::Map source_map; static void RegisterReflection() { namespace refl = tvm::ffi::reflection; refl::ObjectDef().def_ro("source_map", &SourceMapObj::source_map); } static constexpr TVMFFISEqHashKind _type_s_eq_hash_kind = kTVMFFISEqHashKindTreeNode; TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.SourceMap", SourceMapObj, ffi::Object); }; class SourceMap : public ffi::ObjectRef { public: explicit SourceMap(ffi::Map source_map); explicit SourceMap(std::initializer_list> source_map) : SourceMap(ffi::Map(source_map)) {} SourceMap() : SourceMap(ffi::Map()) {} void Add(const Source& source); SourceMapObj* operator->() { TVM_FFI_ICHECK(get() != nullptr); return static_cast(get_mutable()); } TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(SourceMap, ffi::ObjectRef, SourceMapObj); }; } // namespace tvm #endif // TVM_IR_SOURCE_MAP_H_