Files
carbon-lang/source/source_buffer.h
T
Chandler Carruth d4a2d435b8 Enable most relevant clang-tidy checks and fix uncovered issues. (#220)
Most of these were fixed automatically (including things like adding
`[[nodiscard]]` and such). A number of others required manual edits.
I think all of them were pretty nice improvements.

There were a few places where the issues really stem from external
constraints and I've disabled the checks: GoogleTest macros or the
specific LibFuzzer entry points.

The only other places I disabled are the implicit conversions to
a private `enum` in the classes wrapping those `enum`s. These implicit
conversions are necessarily implicit to serve their only purpose:
enabling their use in `switch` statements and `case` labels. When these
were highlighted, it showed that one of these was actually converting to
an *`int`*. I've switched that to use the private `enum` instead as
doing so is important to enable warnings on non-covering `switch`
statements over than `enum`. And indeed, there is a `switch` that was
was implicitly relying on falling through in this way, so I've added the
explicit documentation of the intentional pattern to address that
warning.

Sorry this is so large, all of this somewhat fell out of enabling the
`clang-tidy` checks. If it is too difficult to review as lump, I can
work on breaking it apart as needed. Just let me know.
2020-12-08 14:43:37 -08:00

101 lines
3.3 KiB
C++

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef SOURCE_SOURCEBUFFER_H_
#define SOURCE_SOURCEBUFFER_H_
#include <string>
#include <utility>
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h"
namespace Carbon {
// A buffer of Carbon source code.
//
// This class holds a buffer of Carbon source code as text and makes it
// available for use in the rest of the Carbon compiler. It owns the memory for
// the underlying source code text and ensures it lives as long as the buffer
// objects.
//
// Every buffer of source code text is notionally loaded from a Carbon source
// file, even if provided directly when constructing the buffer. The name that
// should be used for that Carbon source file is also retained and made
// available.
//
// Because the underlying memory for the source code text may have been read
// from a file, and we may want to use facilities like `mmap` to simply map that
// file into memory, the buffer itself is not copyable to avoid needing to
// define copy semantics for a mapped file. We can relax this restriction with
// some implementation complexity in the future if needed.
class SourceBuffer {
public:
static auto CreateFromText(llvm::Twine text,
llvm::StringRef filename = "/text")
-> SourceBuffer;
static auto CreateFromFile(llvm::StringRef filename)
-> llvm::Expected<SourceBuffer>;
// Use one of the factory functions above to create a source buffer.
SourceBuffer() = delete;
// Cannot copy as there may be non-trivial owned file data, see the class
// comment for details.
SourceBuffer(const SourceBuffer& arg) = delete;
SourceBuffer(SourceBuffer&& arg) noexcept
: filename_(std::move(arg.filename_)),
text_(arg.text_),
is_string_rep_(arg.is_string_rep_) {
// The easy case in when we don't need to transfer an allocated string
// representation.
if (!arg.is_string_rep_) {
// Take ownership of a non-string representation by clearing its text.
arg.text_ = llvm::StringRef();
return;
}
// If the argument is using a string rep we need to move that storage over
// and recreate our text `StringRef` to point at our storage.
new (&string_storage_) std::string(std::move(arg.string_storage_));
text_ = string_storage_;
}
~SourceBuffer();
[[nodiscard]] auto Filename() const -> llvm::StringRef { return filename_; }
[[nodiscard]] auto Text() const -> llvm::StringRef { return text_; }
private:
std::string filename_;
llvm::StringRef text_;
bool is_string_rep_;
// We use a transparent union to avoid constructing the storage.
// FIXME: We should replace this and the boolean with an optional which would
// be much simpler.
union {
std::string string_storage_;
};
explicit SourceBuffer(llvm::StringRef fake_filename, std::string buffer_text)
: filename_(fake_filename.str()),
is_string_rep_(true),
string_storage_(std::move(buffer_text)) {
text_ = string_storage_;
}
explicit SourceBuffer(llvm::StringRef filename)
: filename_(filename.str()), text_(), is_string_rep_(false) {}
};
} // namespace Carbon
#endif // SOURCE_SOURCEBUFFER_H_