//===--- SourceLocationEncoding.h - Small serialized locations --*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // We wish to encode the SourceLocation from other module file not dependent // on the other module file. So that the source location changes from other // module file may not affect the contents of the current module file. Then the // users don't need to recompile the whole project due to a new line in a module // unit in the root of the dependency graph. // // To achieve this, we need to encode the index of the module file into the // encoding of the source location. The encoding of the source location may be: // // |-----------------------|-----------------------| // | A | B | C | // // * A: 32 bit. The index of the module file in the module manager + 1. The +1 // here is necessary since we wish 0 stands for the current module file. // * B: 31 bit. The offset of the source location to the module file containing // it. // * C: The macro bit. We rotate it to the lowest bit so that we can save some // space in case the index of the module file is 0. // // Specially, if the index of the module file is 0, we allow to encode a // sequence of locations we store only differences between successive elements. // //===----------------------------------------------------------------------===// #include "clang/Basic/SourceLocation.h" #include "llvm/Support/MathExtras.h" #include <climits> #ifndef LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H #define LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H namespace clang { class SourceLocationSequence; /// Serialized encoding of SourceLocations without context. /// Optimized to have small unsigned values (=> small after VBR encoding). /// // Macro locations have the top bit set, we rotate by one so it is the low bit. class SourceLocationEncoding { … }; /// Serialized encoding of a sequence of SourceLocations. /// /// Optimized to produce small values when locations with the sequence are /// similar. Each element can be delta-encoded against the last nonzero element. /// /// Sequences should be started by creating a SourceLocationSequence::State, /// and then passed around as SourceLocationSequence*. Example: /// /// // establishes a sequence /// void EmitTopLevelThing() { /// SourceLocationSequence::State Seq; /// EmitContainedThing(Seq); /// EmitRecursiveThing(Seq); /// } /// /// // optionally part of a sequence /// void EmitContainedThing(SourceLocationSequence *Seq = nullptr) { /// Record.push_back(SourceLocationEncoding::encode(SomeLoc, Seq)); /// } /// /// // establishes a sequence if there isn't one already /// void EmitRecursiveThing(SourceLocationSequence *ParentSeq = nullptr) { /// SourceLocationSequence::State Seq(ParentSeq); /// Record.push_back(SourceLocationEncoding::encode(SomeLoc, Seq)); /// EmitRecursiveThing(Seq); /// } /// class SourceLocationSequence { … }; /// This object establishes a SourceLocationSequence. class SourceLocationSequence::State { … }; inline SourceLocationEncoding::RawLocEncoding SourceLocationEncoding::encode(SourceLocation Loc, UIntTy BaseOffset, unsigned BaseModuleFileIndex, SourceLocationSequence *Seq) { … } inline std::pair<SourceLocation, unsigned> SourceLocationEncoding::decode(RawLocEncoding Encoded, SourceLocationSequence *Seq) { … } } // namespace clang #endif