aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-02-17 21:13:15 +0000
committerZachary Turner <zturner@google.com>2016-02-17 21:13:15 +0000
commitb1d416923e1698d2847f16ed065ae1c41149632d (patch)
tree7cf76150c2040230357356486170d962a240f357
parent432a2b022d9c10bb3949f9efa2e82d6995633982 (diff)
[DebugInfoPDB] Teach Variant to support string types.
The IDiaSymbol::getValue() method returns a variant. Until now, I had never encountered a string value, so the Variant wrapper did not support VT_BSTR. Now we have need to support string values, so this patch just adds support for one extra type to Variant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261152 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/DebugInfo/PDB/PDBTypes.h30
-rw-r--r--lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp33
-rw-r--r--lib/DebugInfo/PDB/PDBExtras.cpp25
3 files changed, 64 insertions, 24 deletions
diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h
index 787107fdeea..77b98fb8574 100644
--- a/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -350,6 +350,7 @@ enum PDB_VariantType {
UInt32,
UInt64,
Bool,
+ String
};
struct Variant {
@@ -357,6 +358,15 @@ struct Variant {
: Type(PDB_VariantType::Empty) {
}
+ Variant(const Variant &Other) : Type(PDB_VariantType::Empty) {
+ *this = Other;
+ }
+
+ ~Variant() {
+ if (Type == PDB_VariantType::String && Value.String != nullptr)
+ delete[] Value.String;
+ }
+
PDB_VariantType Type;
union {
bool Bool;
@@ -370,10 +380,11 @@ struct Variant {
uint16_t UInt16;
uint32_t UInt32;
uint64_t UInt64;
- };
+ char *String;
+ } Value;
#define VARIANT_EQUAL_CASE(Enum) \
case PDB_VariantType::Enum: \
- return Enum == Other.Enum;
+ return Value.Enum == Other.Value.Enum;
bool operator==(const Variant &Other) const {
if (Type != Other.Type)
return false;
@@ -389,12 +400,27 @@ struct Variant {
VARIANT_EQUAL_CASE(UInt16)
VARIANT_EQUAL_CASE(UInt32)
VARIANT_EQUAL_CASE(UInt64)
+ VARIANT_EQUAL_CASE(String)
default:
return true;
}
}
#undef VARIANT_EQUAL_CASE
bool operator!=(const Variant &Other) const { return !(*this == Other); }
+ Variant &operator=(const Variant &Other) {
+ if (this == &Other)
+ return *this;
+ if (Type == PDB_VariantType::String && Value.String != nullptr)
+ delete[] Value.String;
+ Type = Other.Type;
+ Value = Other.Value;
+ if (Other.Type == PDB_VariantType::String &&
+ Other.Value.String != nullptr) {
+ Value.String = new char[strlen(Other.Value.String) + 1];
+ ::strcpy(Value.String, Other.Value.String);
+ }
+ return *this;
+ }
};
namespace PDB {
diff --git a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index abe0ab55e56..21b9a7aef82 100644
--- a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -22,49 +22,60 @@ Variant VariantFromVARIANT(const VARIANT &V) {
Variant Result;
switch (V.vt) {
case VT_I1:
- Result.Int8 = V.cVal;
+ Result.Value.Int8 = V.cVal;
Result.Type = PDB_VariantType::Int8;
break;
case VT_I2:
- Result.Int16 = V.iVal;
+ Result.Value.Int16 = V.iVal;
Result.Type = PDB_VariantType::Int16;
break;
case VT_I4:
- Result.Int32 = V.intVal;
+ Result.Value.Int32 = V.intVal;
Result.Type = PDB_VariantType::Int32;
break;
case VT_I8:
- Result.Int64 = V.llVal;
+ Result.Value.Int64 = V.llVal;
Result.Type = PDB_VariantType::Int64;
break;
case VT_UI1:
- Result.UInt8 = V.bVal;
+ Result.Value.UInt8 = V.bVal;
Result.Type = PDB_VariantType::UInt8;
break;
case VT_UI2:
- Result.UInt16 = V.uiVal;
+ Result.Value.UInt16 = V.uiVal;
Result.Type = PDB_VariantType::UInt16;
break;
case VT_UI4:
- Result.UInt32 = V.uintVal;
+ Result.Value.UInt32 = V.uintVal;
Result.Type = PDB_VariantType::UInt32;
break;
case VT_UI8:
- Result.UInt64 = V.ullVal;
+ Result.Value.UInt64 = V.ullVal;
Result.Type = PDB_VariantType::UInt64;
break;
case VT_BOOL:
- Result.Bool = (V.boolVal == VARIANT_TRUE) ? true : false;
+ Result.Value.Bool = (V.boolVal == VARIANT_TRUE) ? true : false;
Result.Type = PDB_VariantType::Bool;
break;
case VT_R4:
- Result.Single = V.fltVal;
+ Result.Value.Single = V.fltVal;
Result.Type = PDB_VariantType::Single;
break;
case VT_R8:
- Result.Double = V.dblVal;
+ Result.Value.Double = V.dblVal;
Result.Type = PDB_VariantType::Double;
break;
+ case VT_BSTR: {
+ const char *SrcBytes = reinterpret_cast<const char *>(V.bstrVal);
+ llvm::ArrayRef<char> SrcByteArray(SrcBytes, SysStringByteLen(V.bstrVal));
+ std::string Result8;
+ if (!llvm::convertUTF16ToUTF8String(SrcByteArray, Result8))
+ Result.Value.String = nullptr;
+ Result.Value.String = new char[Result8.length() + 1];
+ ::strcpy(Result.Value.String, Result8.c_str());
+ Result.Type = PDB_VariantType::String;
+ break;
+ }
default:
Result.Type = PDB_VariantType::Unknown;
break;
diff --git a/lib/DebugInfo/PDB/PDBExtras.cpp b/lib/DebugInfo/PDB/PDBExtras.cpp
index 29c0c32601d..52328db42c1 100644
--- a/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -284,37 +284,40 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_UniqueId &Id) {
raw_ostream &llvm::operator<<(raw_ostream &OS, const Variant &Value) {
switch (Value.Type) {
case PDB_VariantType::Bool:
- OS << (Value.Bool ? "true" : "false");
+ OS << (Value.Value.Bool ? "true" : "false");
break;
case PDB_VariantType::Double:
- OS << Value.Double;
+ OS << Value.Value.Double;
break;
case PDB_VariantType::Int16:
- OS << Value.Int16;
+ OS << Value.Value.Int16;
break;
case PDB_VariantType::Int32:
- OS << Value.Int32;
+ OS << Value.Value.Int32;
break;
case PDB_VariantType::Int64:
- OS << Value.Int64;
+ OS << Value.Value.Int64;
break;
case PDB_VariantType::Int8:
- OS << static_cast<int>(Value.Int8);
+ OS << static_cast<int>(Value.Value.Int8);
break;
case PDB_VariantType::Single:
- OS << Value.Single;
+ OS << Value.Value.Single;
break;
case PDB_VariantType::UInt16:
- OS << Value.Double;
+ OS << Value.Value.Double;
break;
case PDB_VariantType::UInt32:
- OS << Value.UInt32;
+ OS << Value.Value.UInt32;
break;
case PDB_VariantType::UInt64:
- OS << Value.UInt64;
+ OS << Value.Value.UInt64;
break;
case PDB_VariantType::UInt8:
- OS << static_cast<unsigned>(Value.UInt8);
+ OS << static_cast<unsigned>(Value.Value.UInt8);
+ break;
+ case PDB_VariantType::String:
+ OS << Value.Value.String;
break;
default:
OS << Value.Type;