Files
revng-revng/include/revng/Model/Identifier.h
Filippo Cremonese 74217b4fe5 Generate C++ model from YAML definition
Model classes are now described by a YAML document, which is used to
generate C++ headers containing classes and all the boilerplate
required for YAML serialization/deserialization, usage in
SortedVectors, etc. See the README in include/revng/Model for more
info.
2022-01-13 14:34:11 +01:00

85 lines
2.0 KiB
C++

#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "revng/ADT/KeyedObjectTraits.h"
#include "revng/Model/VerifyHelper.h"
namespace model {
extern const std::set<llvm::StringRef> ReservedKeywords;
/// \note Zero-sized identifiers are valid
class Identifier : public llvm::SmallString<16> {
public:
using llvm::SmallString<16>::SmallString;
using llvm::SmallString<16>::operator=;
public:
static const Identifier Empty;
public:
static Identifier fromString(llvm::StringRef Name) {
revng_assert(not Name.empty());
Identifier Result;
// For reserved C keywords prepend a non-reserved prefix and we're done.
if (ReservedKeywords.count(Name)) {
Result += "prefix_";
Result += Name;
return Result;
}
const auto BecomesUnderscore = [](const char C) {
return not std::isalnum(C) or C == '_';
};
// For invalid C identifiers prepend the our reserved prefix.
if (std::isdigit(Name[0]) or BecomesUnderscore(Name[0]))
Result += "prefix_";
// Append the rest of the name
Result += Name;
// Convert all non-alphanumeric chars to underscores
for (char &C : Result)
if (not std::isalnum(C))
C = '_';
return Result;
}
public:
bool verify() const debug_function;
bool verify(bool Assert) const debug_function;
bool verify(VerifyHelper &VH) const;
};
} // namespace model
/// KeyedObjectTraits for std::string based on its value
template<>
struct KeyedObjectTraits<model::Identifier>
: public IdentityKeyedObjectTraits<model::Identifier> {};
template<>
struct llvm::yaml::ScalarTraits<model::Identifier> {
static void
output(const model::Identifier &Value, void *, llvm::raw_ostream &Output) {
Output << Value;
}
static StringRef
input(llvm::StringRef Scalar, void *, model::Identifier &Value) {
Value = model::Identifier(Scalar);
return StringRef();
}
static QuotingType mustQuote(StringRef) { return QuotingType::Double; }
};