Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/glog/src/demangle.cc')
-rw-r--r--extern/glog/src/demangle.cc64
1 files changed, 58 insertions, 6 deletions
diff --git a/extern/glog/src/demangle.cc b/extern/glog/src/demangle.cc
index e858181a68f..9369f9a65c2 100644
--- a/extern/glog/src/demangle.cc
+++ b/extern/glog/src/demangle.cc
@@ -30,15 +30,22 @@
// Author: Satoru Takabayashi
//
// For reference check out:
-// http://www.codesourcery.com/public/cxx-abi/abi.html#mangling
+// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
//
// Note that we only have partial C++0x support yet.
#include <stdio.h> // for NULL
+#include "utilities.h"
#include "demangle.h"
+#if defined(OS_WINDOWS)
+#include <dbghelp.h>
+#pragma comment(lib, "dbghelp")
+#endif
+
_START_GOOGLE_NAMESPACE_
+#if !defined(OS_WINDOWS)
typedef struct {
const char *abbrev;
const char *real_name;
@@ -416,6 +423,8 @@ static bool ParseNumber(State *state, int *number_out);
static bool ParseFloatNumber(State *state);
static bool ParseSeqId(State *state);
static bool ParseIdentifier(State *state, int length);
+static bool ParseAbiTags(State *state);
+static bool ParseAbiTag(State *state);
static bool ParseOperatorName(State *state);
static bool ParseSpecialName(State *state);
static bool ParseCallOffset(State *state);
@@ -587,13 +596,13 @@ static bool ParsePrefix(State *state) {
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
-// ::= <source-name>
-// ::= <local-source-name>
+// ::= <source-name> [<abi-tags>]
+// ::= <local-source-name> [<abi-tags>]
static bool ParseUnqualifiedName(State *state) {
return (ParseOperatorName(state) ||
ParseCtorDtorName(state) ||
- ParseSourceName(state) ||
- ParseLocalSourceName(state));
+ (ParseSourceName(state) && Optional(ParseAbiTags(state))) ||
+ (ParseLocalSourceName(state) && Optional(ParseAbiTags(state))));
}
// <source-name> ::= <positive length number> <identifier>
@@ -696,6 +705,23 @@ static bool ParseIdentifier(State *state, int length) {
return true;
}
+// <abi-tags> ::= <abi-tag> [<abi-tags>]
+static bool ParseAbiTags(State *state) {
+ State copy = *state;
+ DisableAppend(state);
+ if (OneOrMore(ParseAbiTag, state)) {
+ RestoreAppend(state, copy.append);
+ return true;
+ }
+ *state = copy;
+ return false;
+}
+
+// <abi-tag> ::= B <source-name>
+static bool ParseAbiTag(State *state) {
+ return ParseOneCharToken(state, 'B') && ParseSourceName(state);
+}
+
// <operator-name> ::= nw, and other two letters cases
// ::= cv <type> # (cast)
// ::= v <digit> <source-name> # vendor extended operator
@@ -1090,10 +1116,11 @@ static bool ParseTemplateArgs(State *state) {
// <template-arg> ::= <type>
// ::= <expr-primary>
// ::= I <template-arg>* E # argument pack
+// ::= J <template-arg>* E # argument pack
// ::= X <expression> E
static bool ParseTemplateArg(State *state) {
State copy = *state;
- if (ParseOneCharToken(state, 'I') &&
+ if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
ZeroOrMore(ParseTemplateArg, state) &&
ParseOneCharToken(state, 'E')) {
return true;
@@ -1293,12 +1320,37 @@ static bool ParseTopLevelMangledName(State *state) {
}
return false;
}
+#endif
// The demangler entry point.
bool Demangle(const char *mangled, char *out, int out_size) {
+#if defined(OS_WINDOWS)
+ // When built with incremental linking, the Windows debugger
+ // library provides a more complicated `Symbol->Name` with the
+ // Incremental Linking Table offset, which looks like
+ // `@ILT+1105(?func@Foo@@SAXH@Z)`. However, the demangler expects
+ // only the mangled symbol, `?func@Foo@@SAXH@Z`. Fortunately, the
+ // mangled symbol is guaranteed not to have parentheses,
+ // so we search for `(` and extract up to `)`.
+ //
+ // Since we may be in a signal handler here, we cannot use `std::string`.
+ char buffer[1024]; // Big enough for a sane symbol.
+ const char *lparen = strchr(mangled, '(');
+ if (lparen) {
+ // Extract the string `(?...)`
+ const char *rparen = strchr(lparen, ')');
+ size_t length = rparen - lparen - 1;
+ strncpy(buffer, lparen + 1, length);
+ buffer[length] = '\0';
+ mangled = buffer;
+ } // Else the symbol wasn't inside a set of parentheses
+ // We use the ANSI version to ensure the string type is always `char *`.
+ return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE);
+#else
State state;
InitState(&state, mangled, out, out_size);
return ParseTopLevelMangledName(&state) && !state.overflowed;
+#endif
}
_END_GOOGLE_NAMESPACE_