Type parseType() { const auto next = stream_.peek(); if (next == '{') { // Struct type. return parseStructType(); } else if (next == '<') { // Vector type. return parseVectorType(); } else if (next == '[') { // Array type. return parseArrayType(); } else if (next >= 'a' && next <= 'z') { // Named type. return parseNamedType(); } else { throw std::runtime_error("Invalid type string."); } }
/* <type> ::= <CV-qualifiers> <type> ::= P <type> ::= R <type> ::= <builtin-type> ::= <function-type> ::= <name> # class-enum-type ::= <array-type> ::= <pointer-to-member-type> ::= <template-param> ::= <template-template-param> <template-args> ::= <substitution> */ static int parseType(LargeStaticString &src, LargeStaticString &dest, demangle_t &data) { START("Type"); // CV-qualifiers? if (src[0] == 'r' || src[0] == 'V' || src[0] == 'K') { LargeStaticString tmp; if (parseCvQualifiers(src, tmp, data) == FAIL) END_FAIL("Type"); if (parseType(src, tmp, data) == FAIL) END_FAIL("Type"); dest += tmp; addSubstitution(tmp, data); END_SUCCESS("Type"); } // Pointer? else if (src[0] == 'P') { src.stripFirst(1); LargeStaticString tmp; if (parseType(src, tmp, data) == FAIL) END_FAIL("Type"); dest += tmp; tmp += "*"; dest += "*"; addSubstitution(tmp, data); END_SUCCESS("Type"); } // Reference? else if (src[0] == 'R') { src.stripFirst(1); LargeStaticString tmp; if (parseType(src, tmp, data) == FAIL) END_FAIL("Type"); dest += tmp; tmp += "&"; dest += "&"; addSubstitution(tmp, data); END_SUCCESS("Type"); } // Function-type? else if (src[0] == 'F') { if (parseFunctionType(src, dest, data) == FAIL) END_FAIL("Type"); END_SUCCESS("Type"); } // Array type? else if (src[0] == 'A') { if (parseArrayType(src, dest, data) == FAIL) END_FAIL("Type"); END_SUCCESS("Type"); } // Pointer-to-member type? else if (src[0] == 'M') { if (parsePointerToMemberType(src, dest, data) == FAIL) END_FAIL("Type"); END_SUCCESS("Type"); } // Template parameter type? else if (src[0] == 'T') { // Try the template-template-type first, if it fails fall back. LargeStaticString origsrc = src; LargeStaticString origdest = dest; if (parseTemplateTemplateParam(src, dest, data) == SUCCESS && parseTemplateArgs(src, dest, data) == SUCCESS) END_SUCCESS("Type"); src = origsrc; dest = origdest; if (parseTemplateParam(src, dest, data) == FAIL) END_FAIL("Type"); END_SUCCESS("Type"); } else { // OK then, try a builtin-type. LargeStaticString origsrc = src; LargeStaticString origdest = dest; if (parseBuiltinType(src, dest, data) == SUCCESS) END_SUCCESS("Type"); src = origsrc; dest = origdest; LargeStaticString tmp; if (parseName(src, tmp, data) == SUCCESS) { dest += tmp; addSubstitution(tmp, data); END_SUCCESS("Type"); } if (src[0] == 'S') { src = origsrc; dest = origdest; if (parseSubstitution(src, dest, data) == FAIL) END_FAIL("Type"); END_SUCCESS("Type"); } END_FAIL("Type"); } }