[IR] Properly handle escape characters in Attribute::getAsString()

If an attribute name has special characters such as '\01', it is not
properly printed in LLVM assembly language format.  Since the format
expects the special characters are printed as it is, it has to contain
escape characters to make it printable.

Before:
  attributes #0 = { ... "counting-function"="^A__gnu_mcount_nc" ...

After:
  attributes #0 = { ... "counting-function"="\01__gnu_mcount_nc" ...

Reviewers: hfinkel, rengolin, rjmccall, compnerd

Subscribers: nemanjai, mcrosier, hans, shenhan, majnemer, llvm-commits

Differential Revision: https://reviews.llvm.org/D23792

llvm-svn: 280357
This commit is contained in:
Honggyu Kim 2016-09-01 11:44:06 +00:00
parent 2e50d8edc6
commit 9eb6a10251
3 changed files with 17 additions and 6 deletions

View File

@ -19,6 +19,7 @@
#include <iterator> #include <iterator>
namespace llvm { namespace llvm {
class raw_ostream;
template<typename T> class SmallVectorImpl; template<typename T> class SmallVectorImpl;
/// hexdigit - Return the hexadecimal character for the /// hexdigit - Return the hexadecimal character for the
@ -150,6 +151,10 @@ static inline StringRef getOrdinalSuffix(unsigned Val) {
} }
} }
/// PrintEscapedString - Print each character of the specified string, escaping
/// it if it is not printable or if it is an escape char.
void PrintEscapedString(StringRef Name, raw_ostream &Out);
template <typename IteratorT> template <typename IteratorT>
inline std::string join_impl(IteratorT Begin, IteratorT End, inline std::string join_impl(IteratorT Begin, IteratorT End,
StringRef Separator, std::input_iterator_tag) { StringRef Separator, std::input_iterator_tag) {

View File

@ -337,9 +337,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
} }
} }
// PrintEscapedString - Print each character of the specified string, escaping void llvm::PrintEscapedString(StringRef Name, raw_ostream &Out) {
// it if it is not printable or if it is an escape char.
static void PrintEscapedString(StringRef Name, raw_ostream &Out) {
for (unsigned i = 0, e = Name.size(); i != e; ++i) { for (unsigned i = 0, e = Name.size(); i != e; ++i) {
unsigned char C = Name[i]; unsigned char C = Name[i];
if (isprint(C) && C != '\\' && C != '"') if (isprint(C) && C != '\\' && C != '"')

View File

@ -381,10 +381,18 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
std::string Result; std::string Result;
Result += (Twine('"') + getKindAsString() + Twine('"')).str(); Result += (Twine('"') + getKindAsString() + Twine('"')).str();
StringRef Val = pImpl->getValueAsString(); std::string AttrVal = pImpl->getValueAsString();
if (Val.empty()) return Result; if (AttrVal.empty()) return Result;
Result += ("=\"" + Val + Twine('"')).str(); // Since some attribute strings contain special characters that cannot be
// printable, those have to be escaped to make the attribute value printable
// as is. e.g. "\01__gnu_mcount_nc"
{
raw_string_ostream OS(Result);
OS << "=\"";
PrintEscapedString(AttrVal, OS);
OS << "\"";
}
return Result; return Result;
} }