[llvm] r320996 - [YAML] Add support for non-printable characters
Francis Visoiu Mistrih via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 18 09:38:03 PST 2017
Author: thegameg
Date: Mon Dec 18 09:38:03 2017
New Revision: 320996
URL: http://llvm.org/viewvc/llvm-project?rev=320996&view=rev
Log:
[YAML] Add support for non-printable characters
LLVM IR function names which disable mangling start with '\01'
(https://www.llvm.org/docs/LangRef.html#identifiers).
When an identifier like "\01 at abc@" gets dumped to MIR, it is quoted, but
only with single quotes.
http://www.yaml.org/spec/1.2/spec.html#id2770814:
"The allowed character range explicitly excludes the C0 control block
allowed), the surrogate block #xD800-#xDFFF, #xFFFE, and #xFFFF."
http://www.yaml.org/spec/1.2/spec.html#id2776092:
"All non-printable characters must be escaped.
[...]
Note that escape sequences are only interpreted in double-quoted scalars."
This patch adds support for printing escaped non-printable characters
between double quotes if needed.
Should also fix PR31743.
Differential Revision: https://reviews.llvm.org/D41290
Added:
llvm/trunk/test/CodeGen/MIR/X86/escape-function-name.ll
Modified:
llvm/trunk/docs/YamlIO.rst
llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h
llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
llvm/trunk/include/llvm/ObjectYAML/YAML.h
llvm/trunk/include/llvm/Support/YAMLTraits.h
llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp
llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
llvm/trunk/lib/Support/Statistic.cpp
llvm/trunk/lib/Support/Timer.cpp
llvm/trunk/lib/Support/YAMLTraits.cpp
llvm/trunk/tools/dsymutil/DebugMap.h
llvm/trunk/unittests/Support/YAMLIOTest.cpp
Modified: llvm/trunk/docs/YamlIO.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/YamlIO.rst?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/docs/YamlIO.rst (original)
+++ llvm/trunk/docs/YamlIO.rst Mon Dec 18 09:38:03 2017
@@ -466,7 +466,7 @@ looks like:
return StringRef();
}
// Determine if this scalar needs quotes.
- static bool mustQuote(StringRef) { return true; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
Block Scalars
Modified: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Mon Dec 18 09:38:03 2017
@@ -56,7 +56,7 @@ template <> struct ScalarTraits<StringVa
return "";
}
- static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
};
struct FlowStringValue : StringValue {
@@ -73,7 +73,7 @@ template <> struct ScalarTraits<FlowStri
return ScalarTraits<StringValue>::input(Scalar, Ctx, S);
}
- static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
};
struct BlockStringValue {
@@ -120,7 +120,7 @@ template <> struct ScalarTraits<Unsigned
return ScalarTraits<unsigned>::input(Scalar, Ctx, Value.Value);
}
- static bool mustQuote(StringRef Scalar) {
+ static QuotingType mustQuote(StringRef Scalar) {
return ScalarTraits<unsigned>::mustQuote(Scalar);
}
};
Modified: llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h Mon Dec 18 09:38:03 2017
@@ -56,7 +56,7 @@ ArrayRef<uint8_t> toDebugH(const DebugHS
} // end namespace llvm
LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::DebugHSection)
-LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::GlobalHash, false)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::GlobalHash, QuotingType::None)
LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::GlobalHash)
#endif // LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
Modified: llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLTypes.h Mon Dec 18 09:38:03 2017
@@ -58,7 +58,7 @@ ArrayRef<uint8_t> toDebugT(ArrayRef<Leaf
} // end namespace llvm
-LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::GUID, true)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::GUID, QuotingType::Single)
LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::LeafRecord)
LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord)
Modified: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h Mon Dec 18 09:38:03 2017
@@ -261,7 +261,7 @@ using char_16 = char[16];
template <> struct ScalarTraits<char_16> {
static void output(const char_16 &Val, void *, raw_ostream &Out);
static StringRef input(StringRef Scalar, void *, char_16 &Val);
- static bool mustQuote(StringRef S);
+ static QuotingType mustQuote(StringRef S);
};
// This trait is used for UUIDs. It reads and writes them matching otool's
@@ -271,7 +271,7 @@ using uuid_t = raw_ostream::uuid_t;
template <> struct ScalarTraits<uuid_t> {
static void output(const uuid_t &Val, void *, raw_ostream &Out);
static StringRef input(StringRef Scalar, void *, uuid_t &Val);
- static bool mustQuote(StringRef S);
+ static QuotingType mustQuote(StringRef S);
};
// Load Command struct mapping traits
Modified: llvm/trunk/include/llvm/ObjectYAML/YAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/YAML.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/YAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/YAML.h Mon Dec 18 09:38:03 2017
@@ -107,7 +107,7 @@ inline bool operator==(const BinaryRef &
template <> struct ScalarTraits<BinaryRef> {
static void output(const BinaryRef &, void *, raw_ostream &);
static StringRef input(StringRef, void *, BinaryRef &);
- static bool mustQuote(StringRef S) { return needsQuotes(S); }
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
};
} // end namespace yaml
Modified: llvm/trunk/include/llvm/Support/YAMLTraits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/YAMLTraits.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/YAMLTraits.h (original)
+++ llvm/trunk/include/llvm/Support/YAMLTraits.h Mon Dec 18 09:38:03 2017
@@ -12,6 +12,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -117,6 +118,11 @@ struct ScalarBitSetTraits {
// static void bitset(IO &io, T &value);
};
+/// Describe which type of quotes should be used when quoting is necessary.
+/// Some non-printable characters need to be double-quoted, while some others
+/// are fine with simple-quoting, and some don't need any quoting.
+enum class QuotingType { None, Single, Double };
+
/// This class should be specialized by type that requires custom conversion
/// to/from a yaml scalar. For example:
///
@@ -131,7 +137,7 @@ struct ScalarBitSetTraits {
/// // return empty string on success, or error string
/// return StringRef();
/// }
-/// static bool mustQuote(StringRef) { return true; }
+/// static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
/// };
template<typename T>
struct ScalarTraits {
@@ -145,7 +151,7 @@ struct ScalarTraits {
//static StringRef input(StringRef scalar, void *ctxt, T &value);
//
// Function to determine if the value should be quoted.
- //static bool mustQuote(StringRef);
+ //static QuotingType mustQuote(StringRef);
};
/// This class should be specialized by type that requires custom conversion
@@ -270,7 +276,7 @@ struct has_ScalarTraits
{
using Signature_input = StringRef (*)(StringRef, void*, T&);
using Signature_output = void (*)(const T&, void*, raw_ostream&);
- using Signature_mustQuote = bool (*)(StringRef);
+ using Signature_mustQuote = QuotingType (*)(StringRef);
template <typename U>
static char test(SameType<Signature_input, &U::input> *,
@@ -495,28 +501,66 @@ inline bool isBool(StringRef S) {
S.equals("false") || S.equals("False") || S.equals("FALSE");
}
-inline bool needsQuotes(StringRef S) {
+// 5.1. Character Set
+// The allowed character range explicitly excludes the C0 control block #x0-#x1F
+// (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
+// control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
+// block #xD800-#xDFFF, #xFFFE, and #xFFFF.
+inline QuotingType needsQuotes(StringRef S) {
if (S.empty())
- return true;
+ return QuotingType::Single;
if (isspace(S.front()) || isspace(S.back()))
- return true;
+ return QuotingType::Single;
if (S.front() == ',')
- return true;
-
- static const char ScalarSafeChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
- if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
- return true;
-
+ return QuotingType::Single;
if (isNull(S))
- return true;
+ return QuotingType::Single;
if (isBool(S))
- return true;
+ return QuotingType::Single;
if (isNumeric(S))
- return true;
+ return QuotingType::Single;
- return false;
+ QuotingType MaxQuotingNeeded = QuotingType::None;
+ for (unsigned char C : S) {
+ // Alphanum is safe.
+ if (isAlnum(C))
+ continue;
+
+ switch (C) {
+ // Safe scalar characters.
+ case '_':
+ case '-':
+ case '/':
+ case '^':
+ case '.':
+ case ',':
+ case ' ':
+ // TAB (0x9), LF (0xA), CR (0xD) and NEL (0x85) are allowed.
+ case 0x9:
+ case 0xA:
+ case 0xD:
+ case 0x85:
+ continue;
+ // DEL (0x7F) are excluded from the allowed character range.
+ case 0x7F:
+ return QuotingType::Double;
+ default: {
+ // C0 control block (0x0 - 0x1F) is excluded from the allowed character
+ // range.
+ if (C <= 0x1F)
+ return QuotingType::Double;
+ // C1 control block (0x80 - 0x9F) is excluded from the allowed character
+ // range.
+ if (C >= 0x80 && C <= 0x9F)
+ return QuotingType::Double;
+
+ // The character is not safe, at least simple quoting needed.
+ MaxQuotingNeeded = QuotingType::Single;
+ }
+ }
+ }
+
+ return MaxQuotingNeeded;
}
template <typename T, typename Context>
@@ -581,7 +625,7 @@ public:
virtual bool bitSetMatch(const char*, bool) = 0;
virtual void endBitSetScalar() = 0;
- virtual void scalarString(StringRef &, bool) = 0;
+ virtual void scalarString(StringRef &, QuotingType) = 0;
virtual void blockScalarString(StringRef &) = 0;
virtual void setError(const Twine &) = 0;
@@ -911,91 +955,91 @@ template<>
struct ScalarTraits<bool> {
static void output(const bool &, void* , raw_ostream &);
static StringRef input(StringRef, void *, bool &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<StringRef> {
static void output(const StringRef &, void *, raw_ostream &);
static StringRef input(StringRef, void *, StringRef &);
- static bool mustQuote(StringRef S) { return needsQuotes(S); }
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
};
template<>
struct ScalarTraits<std::string> {
static void output(const std::string &, void *, raw_ostream &);
static StringRef input(StringRef, void *, std::string &);
- static bool mustQuote(StringRef S) { return needsQuotes(S); }
+ static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
};
template<>
struct ScalarTraits<uint8_t> {
static void output(const uint8_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, uint8_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<uint16_t> {
static void output(const uint16_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, uint16_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<uint32_t> {
static void output(const uint32_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, uint32_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<uint64_t> {
static void output(const uint64_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, uint64_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<int8_t> {
static void output(const int8_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, int8_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<int16_t> {
static void output(const int16_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, int16_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<int32_t> {
static void output(const int32_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, int32_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<int64_t> {
static void output(const int64_t &, void *, raw_ostream &);
static StringRef input(StringRef, void *, int64_t &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<float> {
static void output(const float &, void *, raw_ostream &);
static StringRef input(StringRef, void *, float &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<double> {
static void output(const double &, void *, raw_ostream &);
static StringRef input(StringRef, void *, double &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
// For endian types, we just use the existing ScalarTraits for the underlying
@@ -1019,7 +1063,7 @@ struct ScalarTraits<support::detail::pac
return R;
}
- static bool mustQuote(StringRef Str) {
+ static QuotingType mustQuote(StringRef Str) {
return ScalarTraits<value_type>::mustQuote(Str);
}
};
@@ -1148,7 +1192,7 @@ private:
bool beginBitSetScalar(bool &) override;
bool bitSetMatch(const char *, bool ) override;
void endBitSetScalar() override;
- void scalarString(StringRef &, bool) override;
+ void scalarString(StringRef &, QuotingType) override;
void blockScalarString(StringRef &) override;
void setError(const Twine &message) override;
bool canElideEmptySequence() override;
@@ -1293,7 +1337,7 @@ public:
bool beginBitSetScalar(bool &) override;
bool bitSetMatch(const char *, bool ) override;
void endBitSetScalar() override;
- void scalarString(StringRef &, bool) override;
+ void scalarString(StringRef &, QuotingType) override;
void blockScalarString(StringRef &) override;
void setError(const Twine &message) override;
bool canElideEmptySequence() override;
@@ -1371,28 +1415,28 @@ template<>
struct ScalarTraits<Hex8> {
static void output(const Hex8 &, void *, raw_ostream &);
static StringRef input(StringRef, void *, Hex8 &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<Hex16> {
static void output(const Hex16 &, void *, raw_ostream &);
static StringRef input(StringRef, void *, Hex16 &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<Hex32> {
static void output(const Hex32 &, void *, raw_ostream &);
static StringRef input(StringRef, void *, Hex32 &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template<>
struct ScalarTraits<Hex64> {
static void output(const Hex64 &, void *, raw_ostream &);
static StringRef input(StringRef, void *, Hex64 &);
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
// Define non-member operator>> so that Input can stream in a document list.
@@ -1681,7 +1725,7 @@ template <typename T> struct StdMapStrin
template <> struct ScalarTraits<Type> { \
static void output(const Type &Value, void *ctx, raw_ostream &Out); \
static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
- static bool mustQuote(StringRef) { return MustQuote; } \
+ static QuotingType mustQuote(StringRef) { return MustQuote; } \
}; \
} \
}
Modified: llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp Mon Dec 18 09:38:03 2017
@@ -66,7 +66,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModule
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
-LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, QuotingType::None)
LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
Modified: llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp Mon Dec 18 09:38:03 2017
@@ -42,8 +42,8 @@ using namespace llvm::yaml;
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
-LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
-LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
@@ -62,7 +62,7 @@ LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdin
LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
-LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, true)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
return ScalarTraits<StringRef>::input(S, V, T.value);
Modified: llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp Mon Dec 18 09:38:03 2017
@@ -48,8 +48,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRe
LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
-LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
-LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
+LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
LLVM_YAML_DECLARE_ENUM_TRAITS(TypeLeafKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(PointerToMemberRepresentation)
Modified: llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MachOYAML.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MachOYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MachOYAML.cpp Mon Dec 18 09:38:03 2017
@@ -52,7 +52,9 @@ StringRef ScalarTraits<char_16>::input(S
return StringRef();
}
-bool ScalarTraits<char_16>::mustQuote(StringRef S) { return needsQuotes(S); }
+QuotingType ScalarTraits<char_16>::mustQuote(StringRef S) {
+ return needsQuotes(S);
+}
void ScalarTraits<uuid_t>::output(const uuid_t &Val, void *, raw_ostream &Out) {
Out.write_uuid(Val);
@@ -75,7 +77,9 @@ StringRef ScalarTraits<uuid_t>::input(St
return StringRef();
}
-bool ScalarTraits<uuid_t>::mustQuote(StringRef S) { return needsQuotes(S); }
+QuotingType ScalarTraits<uuid_t>::mustQuote(StringRef S) {
+ return needsQuotes(S);
+}
void MappingTraits<MachOYAML::FileHeader>::mapping(
IO &IO, MachOYAML::FileHeader &FileHdr) {
Modified: llvm/trunk/lib/Support/Statistic.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Statistic.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Statistic.cpp (original)
+++ llvm/trunk/lib/Support/Statistic.cpp Mon Dec 18 09:38:03 2017
@@ -168,9 +168,10 @@ void llvm::PrintStatisticsJSON(raw_ostre
const char *delim = "";
for (const Statistic *Stat : Stats.Stats) {
OS << delim;
- assert(!yaml::needsQuotes(Stat->getDebugType()) &&
+ assert(yaml::needsQuotes(Stat->getDebugType()) == yaml::QuotingType::None &&
"Statistic group/type name is simple.");
- assert(!yaml::needsQuotes(Stat->getName()) && "Statistic name is simple");
+ assert(yaml::needsQuotes(Stat->getName()) == yaml::QuotingType::None &&
+ "Statistic name is simple");
OS << "\t\"" << Stat->getDebugType() << '.' << Stat->getName() << "\": "
<< Stat->getValue();
delim = ",\n";
Modified: llvm/trunk/lib/Support/Timer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Timer.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Timer.cpp (original)
+++ llvm/trunk/lib/Support/Timer.cpp Mon Dec 18 09:38:03 2017
@@ -362,8 +362,10 @@ void TimerGroup::printAll(raw_ostream &O
void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
const char *suffix, double Value) {
- assert(!yaml::needsQuotes(Name) && "TimerGroup name needs no quotes");
- assert(!yaml::needsQuotes(R.Name) && "Timer name needs no quotes");
+ assert(yaml::needsQuotes(Name) == yaml::QuotingType::None &&
+ "TimerGroup name needs no quotes");
+ assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None &&
+ "Timer name needs no quotes");
OS << "\t\"time." << Name << '.' << R.Name << suffix << "\": " << Value;
}
Modified: llvm/trunk/lib/Support/YAMLTraits.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/lib/Support/YAMLTraits.cpp (original)
+++ llvm/trunk/lib/Support/YAMLTraits.cpp Mon Dec 18 09:38:03 2017
@@ -19,6 +19,7 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Unicode.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -330,7 +331,7 @@ void Input::endBitSetScalar() {
}
}
-void Input::scalarString(StringRef &S, bool) {
+void Input::scalarString(StringRef &S, QuotingType) {
if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
S = SN->value();
} else {
@@ -338,7 +339,7 @@ void Input::scalarString(StringRef &S, b
}
}
-void Input::blockScalarString(StringRef &S) { scalarString(S, false); }
+void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
void Input::setError(HNode *hnode, const Twine &message) {
assert(hnode && "HNode must not be NULL");
@@ -617,7 +618,7 @@ void Output::endBitSetScalar() {
this->outputUpToEndOfLine(" ]");
}
-void Output::scalarString(StringRef &S, bool MustQuote) {
+void Output::scalarString(StringRef &S, QuotingType MustQuote) {
this->newLineCheck();
if (S.empty()) {
// Print '' for the empty string because leaving the field empty is not
@@ -625,27 +626,52 @@ void Output::scalarString(StringRef &S,
this->outputUpToEndOfLine("''");
return;
}
- if (!MustQuote) {
+ if (MustQuote == QuotingType::None) {
// Only quote if we must.
this->outputUpToEndOfLine(S);
return;
}
+
unsigned i = 0;
unsigned j = 0;
unsigned End = S.size();
- output("'"); // Starting single quote.
const char *Base = S.data();
+
+ const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
+ const char QuoteChar = MustQuote == QuotingType::Single ? '\'' : '"';
+
+ output(Quote); // Starting quote.
+
+ // When using single-quoted strings, any single quote ' must be doubled to be
+ // escaped.
+ // When using double-quoted strings, print \x + hex for non-printable ASCII
+ // characters, and escape double quotes.
while (j < End) {
- // Escape a single quote by doubling it.
- if (S[j] == '\'') {
- output(StringRef(&Base[i], j - i + 1));
- output("'");
+ if (S[j] == QuoteChar) { // Escape quotes.
+ output(StringRef(&Base[i], j - i)); // "flush".
+ if (MustQuote == QuotingType::Double) { // Print it as \"
+ output(StringLiteral("\\"));
+ output(StringRef(Quote, 1));
+ } else { // Single
+ output(StringLiteral("''")); // Print it as ''
+ }
+ i = j + 1;
+ } else if (MustQuote == QuotingType::Double &&
+ !sys::unicode::isPrintable(S[j])) {
+ output(StringRef(&Base[i], j - i)); // "flush"
+ output(StringLiteral("\\x"));
+
+ // Output the byte 0x0F as \x0f.
+ auto FormattedHex = format_hex_no_prefix(S[j], 2);
+ Out << FormattedHex;
+ Column += 4; // one for the '\', one for the 'x', and two for the hex
+
i = j + 1;
}
++j;
}
output(StringRef(&Base[i], j - i));
- this->outputUpToEndOfLine("'"); // Ending single quote.
+ this->outputUpToEndOfLine(Quote); // Ending quote.
}
void Output::blockScalarString(StringRef &S) {
Added: llvm/trunk/test/CodeGen/MIR/X86/escape-function-name.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/escape-function-name.ll?rev=320996&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/escape-function-name.ll (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/escape-function-name.ll Mon Dec 18 09:38:03 2017
@@ -0,0 +1,6 @@
+; RUN: llc -mtriple=x86_64-unknown-unknown -stop-after branch-folder -o - %s 2>&1 | FileCheck %s
+
+define void @"\01?f@@YAXXZ"() {
+; CHECK: name: "\x01?f@@YAXXZ"
+ ret void
+}
Modified: llvm/trunk/tools/dsymutil/DebugMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DebugMap.h?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DebugMap.h (original)
+++ llvm/trunk/tools/dsymutil/DebugMap.h Mon Dec 18 09:38:03 2017
@@ -232,7 +232,7 @@ template <> struct MappingTraits<dsymuti
template <> struct ScalarTraits<Triple> {
static void output(const Triple &val, void *, raw_ostream &out);
static StringRef input(StringRef scalar, void *, Triple &value);
- static bool mustQuote(StringRef) { return true; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
template <>
Modified: llvm/trunk/unittests/Support/YAMLIOTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=320996&r1=320995&r2=320996&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/YAMLIOTest.cpp (original)
+++ llvm/trunk/unittests/Support/YAMLIOTest.cpp Mon Dec 18 09:38:03 2017
@@ -860,7 +860,7 @@ namespace yaml {
return "malformed by";
}
}
- static bool mustQuote(StringRef) { return true; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
}
}
@@ -1064,7 +1064,7 @@ namespace yaml {
return StringRef();
}
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template <> struct ScalarTraits<MyString> {
@@ -1075,7 +1075,9 @@ namespace yaml {
static StringRef input(StringRef S, void *Ctx, MyString &V) {
return Impl::input(S, Ctx, V.value);
}
- static bool mustQuote(StringRef S) { return Impl::mustQuote(S); }
+ static QuotingType mustQuote(StringRef S) {
+ return Impl::mustQuote(S);
+ }
};
}
}
@@ -2232,7 +2234,7 @@ struct ScalarTraits<FlowSeq> {
return "";
}
- static bool mustQuote(StringRef S) { return false; }
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
};
}
}
@@ -2455,3 +2457,87 @@ TEST(YAMLIO, InvalidInput) {
yin >> Data;
EXPECT_TRUE((bool)yin.error());
}
+
+TEST(YAMLIO, TestEscapedSingleQuote) {
+ std::string Id = "@abc@";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("'@abc@'", out);
+}
+
+TEST(YAMLIO, TestEscapedNoQuote) {
+ std::string Id = "abc/";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("abc/", out);
+}
+
+TEST(YAMLIO, TestEscapedDoubleQuoteNonPrintable) {
+ std::string Id = "\01 at abc@";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("\"\\x01 at abc@\"", out);
+}
+
+TEST(YAMLIO, TestEscapedDoubleQuoteInsideSingleQuote) {
+ std::string Id = "abc\"fdf";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("'abc\"fdf'", out);
+}
+
+TEST(YAMLIO, TestEscapedDoubleQuoteInsideDoubleQuote) {
+ std::string Id = "\01bc\"fdf";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("\"\\x01bc\\\"fdf\"", out);
+}
+
+TEST(YAMLIO, TestEscapedSingleQuoteInsideSingleQuote) {
+ std::string Id = "abc'fdf";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("'abc''fdf'", out);
+}
More information about the llvm-commits
mailing list