forked from OSchip/llvm-project
[clang-diff] Fix assertion error when dealing with wide strings
Directly using StringLiteral::getString for wide string is not currently supported; therefore in ASTDiff, getStmtValue will fail when asserting that the StringLiteral has a width of 1. This patch also covers cases for UTF16 and UTF32 encoding, along with corresponding test cases. Fixes https://github.com/llvm/llvm-project/issues/55771. Reviewed By: johannes Differential Revision: https://reviews.llvm.org/D126651
This commit is contained in:
parent
4561352f7b
commit
e80748ff88
|
@ -16,6 +16,7 @@
|
|||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "llvm/ADT/PriorityQueue.h"
|
||||
#include "llvm/Support/ConvertUTF.h"
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
@ -463,8 +464,29 @@ std::string SyntaxTree::Impl::getStmtValue(const Stmt *S) const {
|
|||
}
|
||||
if (auto *D = dyn_cast<DeclRefExpr>(S))
|
||||
return getRelativeName(D->getDecl(), getEnclosingDeclContext(AST, S));
|
||||
if (auto *String = dyn_cast<StringLiteral>(S))
|
||||
if (auto *String = dyn_cast<StringLiteral>(S)) {
|
||||
if (String->isWide() || String->isUTF16() || String->isUTF32()) {
|
||||
std::string UTF8Str;
|
||||
unsigned int NumChars = String->getLength();
|
||||
const char *Bytes = String->getBytes().data();
|
||||
if (String->isWide()) {
|
||||
const auto *Chars = reinterpret_cast<const wchar_t *>(Bytes);
|
||||
if (!convertWideToUTF8({Chars, NumChars}, UTF8Str))
|
||||
return "";
|
||||
} else if (String->isUTF16()) {
|
||||
const auto *Chars = reinterpret_cast<const UTF16 *>(Bytes);
|
||||
if (!convertUTF16ToUTF8String({Chars, NumChars}, UTF8Str))
|
||||
return "";
|
||||
} else {
|
||||
assert(String->isUTF32() && "Unsupported string encoding.");
|
||||
const auto *Chars = reinterpret_cast<const UTF32 *>(Bytes);
|
||||
if (!convertUTF32ToUTF8String({Chars, NumChars}, UTF8Str))
|
||||
return "";
|
||||
}
|
||||
return UTF8Str;
|
||||
}
|
||||
return std::string(String->getString());
|
||||
}
|
||||
if (auto *B = dyn_cast<CXXBoolLiteralExpr>(S))
|
||||
return B->getValue() ? "true" : "false";
|
||||
return "";
|
||||
|
|
|
@ -47,6 +47,12 @@ class X : Base {
|
|||
if (i == 0)
|
||||
// CHECK: StringLiteral: foo(
|
||||
return "foo";
|
||||
// CHECK: StringLiteral: wide(
|
||||
(void)L"wide";
|
||||
// CHECK: StringLiteral: utf-16(
|
||||
(void)u"utf-16";
|
||||
// CHECK: StringLiteral: utf-32(
|
||||
(void)U"utf-32";
|
||||
// CHECK-NOT: ImplicitCastExpr
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue