diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-02-13 00:15:56 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-02-13 00:15:56 +0000 |
commit | 8b15f1f272d0815f33ba28b553f5bc9e48c75d55 (patch) | |
tree | de36907e26d3ae442fd87c3c6e5a7fca0ff29f85 /libcxxabi/src | |
parent | 8d2aca06975f196a833e3c4cb8dd5270e5de6cbf (diff) | |
download | bcm5719-llvm-8b15f1f272d0815f33ba28b553f5bc9e48c75d55.tar.gz bcm5719-llvm-8b15f1f272d0815f33ba28b553f5bc9e48c75d55.zip |
[demangler] Support for initializer lists and designated initializers.
llvm-svn: 324970
Diffstat (limited to 'libcxxabi/src')
-rw-r--r-- | libcxxabi/src/cxa_demangle.cpp | 144 |
1 files changed, 142 insertions, 2 deletions
diff --git a/libcxxabi/src/cxa_demangle.cpp b/libcxxabi/src/cxa_demangle.cpp index 5faf0ae263b..1cadff4321e 100644 --- a/libcxxabi/src/cxa_demangle.cpp +++ b/libcxxabi/src/cxa_demangle.cpp @@ -198,6 +198,8 @@ public: KUnnamedTypeName, KLambdaTypeName, KExpr, + KBracedExpr, + KBracedRangeExpr, }; static constexpr unsigned NoParameterPack = @@ -1322,7 +1324,7 @@ public: // -- Expression Nodes -- struct Expr : public Node { - Expr() : Node(KExpr) {} + Expr(Kind K = KExpr) : Node(K) {} }; class BinaryExpr : public Expr { @@ -1623,6 +1625,70 @@ public: } }; +class InitListExpr : public Expr { + Node *Ty; + NodeArray Inits; +public: + InitListExpr(Node *Ty_, NodeArray Inits_) + : Ty(Ty_), Inits(Inits_) { + if (Ty) + ParameterPackSize = Ty->ParameterPackSize; + for (Node *I : Inits) + ParameterPackSize = std::min(I->ParameterPackSize, ParameterPackSize); + } + + void printLeft(OutputStream &S) const override { + if (Ty) + Ty->print(S); + S += '{'; + Inits.printWithComma(S); + S += '}'; + } +}; + +class BracedExpr : public Expr { + Node *Elem; + Node *Init; + bool IsArray; +public: + BracedExpr(Node *Elem_, Node *Init_, bool IsArray_) + : Expr(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {} + + void printLeft(OutputStream &S) const override { + if (IsArray) { + S += '['; + Elem->print(S); + S += ']'; + } else { + S += '.'; + Elem->print(S); + } + if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) + S += " = "; + Init->print(S); + } +}; + +class BracedRangeExpr : public Expr { + Node *First; + Node *Last; + Node *Init; +public: + BracedRangeExpr(Node *First_, Node *Last_, Node *Init_) + : Expr(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {} + + void printLeft(OutputStream &S) const override { + S += '['; + First->print(S); + S += " ... "; + Last->print(S); + S += ']'; + if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) + S += " = "; + Init->print(S); + } +}; + class ThrowExpr : public Expr { const Node *Op; @@ -1985,6 +2051,7 @@ struct Db { Node *parseFunctionParam(); Node *parseNewExpr(); Node *parseConversionExpr(); + Node *parseBracedExpr(); /// Parse the <type> production. Node *parseType(); @@ -2070,6 +2137,7 @@ const char *parse_name(const char *first, const char *last, Db &db, const char *parse_template_args(const char *first, const char *last, Db &db); const char *parse_template_param(const char *, const char *, Db &); const char *parse_operator_name(const char *first, const char *last, Db &db); +const char *parse_source_name(const char *, const char *, Db &); const char *parse_unqualified_name(const char *first, const char *last, Db &db); const char *parse_decltype(const char *first, const char *last, Db &db); const char *parse_unresolved_name(const char *, const char *, Db &); @@ -2870,6 +2938,51 @@ Node *Db::parseExprPrimary() { } } +// <braced-expression> ::= <expression> +// ::= di <field source-name> <braced-expression> # .name = expr +// ::= dx <index expression> <braced-expression> # [expr] = expr +// ::= dX <range begin expression> <range end expression> <braced-expression> +Node *Db::parseBracedExpr() { + if (look() == 'd') { + switch (look(1)) { + case 'i': { + First += 2; + Node *Field = legacyParse<parse_source_name>(); + if (Field == nullptr) + return nullptr; + Node *Init = parseBracedExpr(); + if (Init == nullptr) + return nullptr; + return make<BracedExpr>(Field, Init, /*isArray=*/false); + } + case 'x': { + First += 2; + Node *Index = parseExpr(); + if (Index == nullptr) + return nullptr; + Node *Init = parseBracedExpr(); + if (Init == nullptr) + return nullptr; + return make<BracedExpr>(Index, Init, /*isArray=*/true); + } + case 'X': { + First += 2; + Node *RangeBegin = parseExpr(); + if (RangeBegin == nullptr) + return nullptr; + Node *RangeEnd = parseExpr(); + if (RangeEnd == nullptr) + return nullptr; + Node *Init = parseBracedExpr(); + if (Init == nullptr) + return nullptr; + return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init); + } + } + } + return parseExpr(); +} + // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> // ::= <ternary operator-name> <expression> <expression> <expression> @@ -3079,7 +3192,8 @@ Node *Db::parseExpr() { } return nullptr; case 'i': - if (First[1] == 'x') { + switch (First[1]) { + case 'x': { First += 2; Node *Base = parseExpr(); if (Base == nullptr) @@ -3089,6 +3203,18 @@ Node *Db::parseExpr() { return Index; return make<ArraySubscriptExpr>(Base, Index); } + case 'l': { + First += 2; + size_t InitsBegin = Names.size(); + while (!consumeIf('E')) { + Node *E = parseBracedExpr(); + if (E == nullptr) + return nullptr; + Names.push_back(E); + } + return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin)); + } + } return nullptr; case 'l': switch (First[1]) { @@ -3310,6 +3436,20 @@ Node *Db::parseExpr() { return Ty; return make<EnclosingExpr>("typeid (", Ty, ")"); } + case 'l': { + First += 2; + Node *Ty = parseType(); + if (Ty == nullptr) + return nullptr; + size_t InitsBegin = Names.size(); + while (!consumeIf('E')) { + Node *E = parseBracedExpr(); + if (E == nullptr) + return nullptr; + Names.push_back(E); + } + return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin)); + } case 'r': First += 2; return make<NameType>("throw"); |