[libcxxabi] r326797 - [demangler] Modernize the rest of the demangler.

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 6 20:32:52 PST 2018


No, that was a mistake, fixed in r326871. Thanks for pointing this out!
Erik

On 2018-03-06 11:10 PM, Nico Weber wrote:
> Hi Erik,
>
> before this change, ___Z10blocksNRVOv_block_invoke demangled to 
> 'invocation function for block in blocksNRVO()', now it's no longer 
> demangled. Was that an intentional change?
>
> On Tue, Mar 6, 2018 at 9:21 AM, Erik Pilkington via cfe-commits 
> <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
>
>     Author: epilk
>     Date: Tue Mar  6 06:21:10 2018
>     New Revision: 326797
>
>     URL: http://llvm.org/viewvc/llvm-project?rev=326797&view=rev
>     <http://llvm.org/viewvc/llvm-project?rev=326797&view=rev>
>     Log:
>     [demangler] Modernize the rest of the demangler.
>
>     Modified:
>         libcxxabi/trunk/src/cxa_demangle.cpp
>         libcxxabi/trunk/test/test_demangle.pass.cpp
>
>     Modified: libcxxabi/trunk/src/cxa_demangle.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=326797&r1=326796&r2=326797&view=diff
>     <http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=326797&r1=326796&r2=326797&view=diff>
>     ==============================================================================
>     --- libcxxabi/trunk/src/cxa_demangle.cpp (original)
>     +++ libcxxabi/trunk/src/cxa_demangle.cpp Tue Mar  6 06:21:10 2018
>     @@ -2002,6 +2002,8 @@ struct Db {
>
>        BumpPointerAllocator ASTAllocator;
>
>     +  Db(const char *First_, const char *Last_) : First(First_),
>     Last(Last_) {}
>     +
>        template <class T, class... Args> T *make(Args &&... args) {
>          return new (ASTAllocator.allocate(sizeof(T)))
>              T(std::forward<Args>(args)...);
>     @@ -2054,6 +2056,12 @@ struct Db {
>        bool parsePositiveInteger(size_t *Out);
>        StringView parseBareSourceName();
>
>     +  bool parseSeqId(size_t *Out);
>     +  Node *parseSubstitution();
>     +  Node *parseTemplateParam();
>     +  Node *parseTemplateArgs();
>     +  Node *parseTemplateArg();
>     +
>        /// Parse the <expr> production.
>        Node *parseExpr();
>        Node *parsePrefixExpr(StringView Kind);
>     @@ -2109,66 +2117,11 @@ struct Db {
>        Node *parseUnresolvedType();
>        Node *parseDestructorName();
>
>     -  // FIXME: remove this when all the parse_* functions have been
>     rewritten.
>     -  template <const char *(*parse_fn)(const char *, const char *,
>     Db &)>
>     -  Node *legacyParse() {
>     -    size_t BeforeType = Names.size();
>     -    const char *OrigFirst = First;
>     -    const char *T = parse_fn(First, Last, *this);
>     -    if (T == OrigFirst || BeforeType + 1 != Names.size())
>     -      return nullptr;
>     -    First = T;
>     -    Node *R = Names.back();
>     -    Names.pop_back();
>     -    return R;
>     -  }
>     +  /// Top-level entry point into the parser.
>     +  Node *parse();
>      };
>
>     -const char *parse_expression(const char *first, const char *last,
>     Db &db) {
>     -  db.First = first;
>     -  db.Last = last;
>     -  Node *R = db.parseExpr();
>     -  if (R == nullptr)
>     -    return first;
>     -  db.Names.push_back(R);
>     -  return db.First;
>     -}
>     -
>     -const char *parse_expr_primary(const char *first, const char
>     *last, Db &db) {
>     -  db.First = first;
>     -  db.Last = last;
>     -  Node *R = db.parseExprPrimary();
>     -  if (R == nullptr)
>     -    return first;
>     -  db.Names.push_back(R);
>     -  return db.First;
>     -}
>     -
>     -const char *parse_type(const char *first, const char *last, Db &db) {
>     -  db.First = first;
>     -  db.Last = last;
>     -  Node *R = db.parseType();
>     -  if (R == nullptr)
>     -    return first;
>     -  db.Names.push_back(R);
>     -  return db.First;
>     -}
>     -
>     -const char *parse_encoding(const char *first, const char *last,
>     Db &db) {
>     -  db.First = first;
>     -  db.Last = last;
>     -  Node *R = db.parseEncoding();
>     -  if (R == nullptr)
>     -    return first;
>     -  db.Names.push_back(R);
>     -  return db.First;
>     -}
>     -
>      const char* parse_discriminator(const char* first, const char* last);
>     -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_substitution(const char *, const char *, Db &);
>     -
>
>      // <name> ::= <nested-name> // N
>      //        ::= <local-name> # See Scope Encoding below  // Z
>     @@ -2187,10 +2140,12 @@ Node *Db::parseName(NameState *State) {
>
>        //        ::= <unscoped-template-name> <template-args>
>        if (look() == 'S' && look(1) != 't') {
>     -    Node *S = legacyParse<parse_substitution>();
>     +    Node *S = parseSubstitution();
>     +    if (S == nullptr)
>     +      return nullptr;
>          if (look() != 'I')
>            return nullptr;
>     -    Node *TA = legacyParse<parse_template_args>();
>     +    Node *TA = parseTemplateArgs();
>          if (TA == nullptr)
>            return nullptr;
>          if (State) State->EndsWithTemplateArgs = true;
>     @@ -2203,7 +2158,7 @@ Node *Db::parseName(NameState *State) {
>        //        ::= <unscoped-template-name> <template-args>
>        if (look() == 'I') {
>          Subs.push_back(N);
>     -    Node *TA = legacyParse<parse_template_args>();
>     +    Node *TA = parseTemplateArgs();
>          if (TA == nullptr)
>            return nullptr;
>          if (State) State->EndsWithTemplateArgs = true;
>     @@ -2693,7 +2648,7 @@ Node *Db::parseNestedName(NameState *Sta
>
>          //          ::= <template-param>
>          if (look() == 'T') {
>     -      Node *TP = legacyParse<parse_template_param>();
>     +      Node *TP = parseTemplateParam();
>            if (TP == nullptr)
>              return nullptr;
>            PushComponent(TP);
>     @@ -2703,7 +2658,7 @@ Node *Db::parseNestedName(NameState *Sta
>
>          //          ::= <template-prefix> <template-args>
>          if (look() == 'I') {
>     -      Node *TA = legacyParse<parse_template_args>();
>     +      Node *TA = parseTemplateArgs();
>            if (TA == nullptr || SoFar == nullptr)
>              return nullptr;
>            SoFar = make<NameWithTemplateArgs>(SoFar, TA);
>     @@ -2724,7 +2679,7 @@ Node *Db::parseNestedName(NameState *Sta
>
>          //          ::= <substitution>
>          if (look() == 'S' && look(1) != 't') {
>     -      Node *S = legacyParse<parse_substitution>();
>     +      Node *S = parseSubstitution();
>            if (S == nullptr)
>              return nullptr;
>            PushComponent(S);
>     @@ -2769,7 +2724,7 @@ Node *Db::parseSimpleId() {
>        if (SN == nullptr)
>          return nullptr;
>        if (look() == 'I') {
>     -    Node *TA = legacyParse<parse_template_args>();
>     +    Node *TA = parseTemplateArgs();
>          if (TA == nullptr)
>            return nullptr;
>          return make<NameWithTemplateArgs>(SN, TA);
>     @@ -2795,7 +2750,7 @@ Node *Db::parseDestructorName() {
>      //                   ::= <substitution>
>      Node *Db::parseUnresolvedType() {
>        if (look() == 'T') {
>     -    Node *TP = legacyParse<parse_template_param>();
>     +    Node *TP = parseTemplateParam();
>          if (TP == nullptr)
>            return nullptr;
>          Subs.push_back(TP);
>     @@ -2808,7 +2763,7 @@ Node *Db::parseUnresolvedType() {
>          Subs.push_back(DT);
>          return DT;
>        }
>     -  return legacyParse<parse_substitution>();
>     +  return parseSubstitution();
>      }
>
>      // <base-unresolved-name> ::= <simple-id>                        
>       # unresolved name
>     @@ -2831,7 +2786,7 @@ Node *Db::parseBaseUnresolvedName() {
>        if (Oper == nullptr)
>          return nullptr;
>        if (look() == 'I') {
>     -    Node *TA = legacyParse<parse_template_args>();
>     +    Node *TA = parseTemplateArgs();
>          if (TA == nullptr)
>            return nullptr;
>          return make<NameWithTemplateArgs>(Oper, TA);
>     @@ -2861,7 +2816,7 @@ Node *Db::parseUnresolvedName() {
>            return nullptr;
>
>          if (look() == 'I') {
>     -      Node *TA = legacyParse<parse_template_args>();
>     +      Node *TA = parseTemplateArgs();
>            if (TA == nullptr)
>              return nullptr;
>            SoFar = make<NameWithTemplateArgs>(SoFar, TA);
>     @@ -2914,7 +2869,7 @@ Node *Db::parseUnresolvedName() {
>            return nullptr;
>
>          if (look() == 'I') {
>     -      Node *TA = legacyParse<parse_template_args>();
>     +      Node *TA = parseTemplateArgs();
>            if (TA == nullptr)
>              return nullptr;
>            SoFar = make<NameWithTemplateArgs>(SoFar, TA);
>     @@ -3436,7 +3391,7 @@ Node *Db::parseType() {
>            break;
>          }
>
>     -    Result = legacyParse<parse_template_param>();
>     +    Result = parseTemplateParam();
>          if (Result == nullptr)
>            return nullptr;
>
>     @@ -3451,7 +3406,7 @@ Node *Db::parseType() {
>          // parse them, take the second production.
>
>          if (TryToParseTemplateArgs && look() == 'I') {
>     -      Node *TA = legacyParse<parse_template_args>();
>     +      Node *TA = parseTemplateArgs();
>            if (TA == nullptr)
>              return nullptr;
>            Result = make<NameWithTemplateArgs>(Result, TA);
>     @@ -3506,7 +3461,7 @@ Node *Db::parseType() {
>        //             ::= <substitution>  # See Compression below
>        case 'S': {
>          if (look(1) && look(1) != 't') {
>     -      Node *Sub = legacyParse<parse_substitution>();
>     +      Node *Sub = parseSubstitution();
>            if (Sub == nullptr)
>              return nullptr;
>
>     @@ -3521,7 +3476,7 @@ Node *Db::parseType() {
>            // parse them, take the second production.
>
>            if (TryToParseTemplateArgs && look() == 'I') {
>     -        Node *TA = legacyParse<parse_template_args>();
>     +        Node *TA = parseTemplateArgs();
>              if (TA == nullptr)
>                return nullptr;
>              Result = make<NameWithTemplateArgs>(Sub, TA);
>     @@ -3872,7 +3827,7 @@ Node *Db::parseExpr() {
>        case 'L':
>          return parseExprPrimary();
>        case 'T':
>     -    return legacyParse<parse_template_param>();
>     +    return parseTemplateParam();
>        case 'f':
>          return parseFunctionParam();
>        case 'a':
>     @@ -4244,7 +4199,7 @@ Node *Db::parseExpr() {
>          case 'Z':
>            First += 2;
>            if (look() == 'T') {
>     -        Node *R = legacyParse<parse_template_param>();
>     +        Node *R = parseTemplateParam();
>              if (R == nullptr)
>                return nullptr;
>              return make<SizeofParamPackExpr>(R);
>     @@ -4572,6 +4527,28 @@ template <class Float> Node *Db::parseFl
>        return make<FloatExpr<Float>>(Data);
>      }
>
>     +// <seq-id> ::= <0-9A-Z>+
>     +bool Db::parseSeqId(size_t *Out) {
>     +  if (!(look() >= '0' && look() <= '9') &&
>     +      !(look() >= 'A' && look() <= 'Z'))
>     +    return true;
>     +
>     +  size_t Id = 0;
>     +  while (true) {
>     +    if (look() >= '0' && look() <= '9') {
>     +      Id *= 36;
>     +      Id += static_cast<size_t>(look() - '0');
>     +    } else if (look() >= 'A' && look() <= 'Z') {
>     +      Id *= 36;
>     +      Id += static_cast<size_t>(look() - 'A') + 10;
>     +    } else {
>     +      *Out = Id;
>     +      return false;
>     +    }
>     +    ++First;
>     +  }
>     +}
>     +
>      // <substitution> ::= S <seq-id> _
>      //                ::= S_
>      // <substitution> ::= Sa # ::std::allocator
>     @@ -4582,243 +4559,172 @@ template <class Float> Node *Db::parseFl
>      // <substitution> ::= Si # ::std::basic_istream<char, 
>     std::char_traits<char> >
>      // <substitution> ::= So # ::std::basic_ostream<char, 
>     std::char_traits<char> >
>      // <substitution> ::= Sd # ::std::basic_iostream<char,
>     std::char_traits<char> >
>     +Node *Db::parseSubstitution() {
>     +  if (!consumeIf('S'))
>     +    return nullptr;
>
>     -const char*
>     -parse_substitution(const char* first, const char* last, Db& db)
>     -{
>     -    if (last - first >= 2)
>     -    {
>     -        if (*first == 'S')
>     -        {
>     -            switch (first[1])
>     -            {
>     -            case 'a':
>     -                db.Names.push_back(
>     -                    db.make<SpecialSubstitution>(
>     -                        SpecialSubKind::allocator));
>     -                first += 2;
>     -                break;
>     -            case 'b':
>     -                db.Names.push_back(
>     -                   
>     db.make<SpecialSubstitution>(SpecialSubKind::basic_string));
>     -                first += 2;
>     -                break;
>     -            case 's':
>     -                db.Names.push_back(
>     -                    db.make<SpecialSubstitution>(
>     -                        SpecialSubKind::string));
>     -                first += 2;
>     -                break;
>     -            case 'i':
>     -               
>     db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::istream));
>     -                first += 2;
>     -                break;
>     -            case 'o':
>     -               
>     db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::ostream));
>     -                first += 2;
>     -                break;
>     -            case 'd':
>     -               
>     db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::iostream));
>     -                first += 2;
>     -                break;
>     -            case '_':
>     -                if (!db.Subs.empty())
>     -                {
>     -                    db.Names.push_back(db.Subs[0]);
>     -                    first += 2;
>     -                }
>     -                break;
>     -            default:
>     -                if (std::isdigit(first[1]) || std::isupper(first[1]))
>     -                {
>     -                    size_t sub = 0;
>     -                    const char* t = first+1;
>     -                    if (std::isdigit(*t))
>     -                        sub = static_cast<size_t>(*t - '0');
>     -                    else
>     -                        sub = static_cast<size_t>(*t - 'A') + 10;
>     -                    for (++t; t != last && (std::isdigit(*t) ||
>     std::isupper(*t)); ++t)
>     -                    {
>     -                        sub *= 36;
>     -                        if (std::isdigit(*t))
>     -                            sub += static_cast<size_t>(*t - '0');
>     -                        else
>     -                            sub += static_cast<size_t>(*t - 'A')
>     + 10;
>     -                    }
>     -                    if (t == last || *t != '_')
>     -                        return first;
>     -                    ++sub;
>     -                    if (sub < db.Subs.size())
>     -                    {
>     -                        db.Names.push_back(db.Subs[sub]);
>     -                        first = t+1;
>     -                    }
>     -                }
>     -                break;
>     -            }
>     -        }
>     +  if (std::islower(look())) {
>     +    Node *SpecialSub;
>     +    switch (look()) {
>     +    case 'a':
>     +      ++First;
>     +      SpecialSub =
>     make<SpecialSubstitution>(SpecialSubKind::allocator);
>     +      break;
>     +    case 'b':
>     +      ++First;
>     +      SpecialSub =
>     make<SpecialSubstitution>(SpecialSubKind::basic_string);
>     +      break;
>     +    case 's':
>     +      ++First;
>     +      SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
>     +      break;
>     +    case 'i':
>     +      ++First;
>     +      SpecialSub =
>     make<SpecialSubstitution>(SpecialSubKind::istream);
>     +      break;
>     +    case 'o':
>     +      ++First;
>     +      SpecialSub =
>     make<SpecialSubstitution>(SpecialSubKind::ostream);
>     +      break;
>     +    case 'd':
>     +      ++First;
>     +      SpecialSub =
>     make<SpecialSubstitution>(SpecialSubKind::iostream);
>     +      break;
>     +    default:
>     +      return nullptr;
>          }
>     -    return first;
>     +    // Itanium C++ ABI 5.1.2: If a name that would use a built-in
>     <substitution>
>     +    // has ABI tags, the tags are appended to the substitution;
>     the result is a
>     +    // substitutable component.
>     +    Node *WithTags = parseAbiTags(SpecialSub);
>     +    if (WithTags != SpecialSub) {
>     +      Subs.push_back(WithTags);
>     +      SpecialSub = WithTags;
>     +    }
>     +    return SpecialSub;
>     +  }
>     +
>     +  //                ::= S_
>     +  if (consumeIf('_')) {
>     +    if (Subs.empty())
>     +      return nullptr;
>     +    return Subs[0];
>     +  }
>     +
>     +  //                ::= S <seq-id> _
>     +  size_t Index = 0;
>     +  if (parseSeqId(&Index))
>     +    return nullptr;
>     +  ++Index;
>     +  if (!consumeIf('_') || Index >= Subs.size())
>     +    return nullptr;
>     +  return Subs[Index];
>      }
>
>      // <template-param> ::= T_    # first template parameter
>      //                  ::= T <parameter-2 non-negative number> _
>     +Node *Db::parseTemplateParam() {
>     +  if (!consumeIf('T'))
>     +    return nullptr;
>
>     -const char*
>     -parse_template_param(const char* first, const char* last, Db& db)
>     -{
>     -    if (last - first >= 2)
>     -    {
>     -        if (*first == 'T')
>     -        {
>     -            if (first[1] == '_')
>     -            {
>     -                if (!db.TemplateParams.empty())
>     -                {
>     -                    db.Names.push_back(db.TemplateParams[0]);
>     -                    first += 2;
>     -                }
>     -                else
>     -                {
>     -                    db.Names.push_back(db.make<NameType>("T_"));
>     -                    first += 2;
>     -                    db.FixForwardReferences = true;
>     -                }
>     -            }
>     -            else if (isdigit(first[1]))
>     -            {
>     -                const char* t = first+1;
>     -                size_t sub = static_cast<size_t>(*t - '0');
>     -                for (++t; t != last && isdigit(*t); ++t)
>     -                {
>     -                    sub *= 10;
>     -                    sub += static_cast<size_t>(*t - '0');
>     -                }
>     -                if (t == last || *t != '_')
>     -                    return first;
>     -                ++sub;
>     -                if (sub < db.TemplateParams.size())
>     -                {
>     -                    db.Names.push_back(db.TemplateParams[sub]);
>     -                    first = t+1;
>     -                }
>     -                else
>     -                {
>     -                    db.Names.push_back(
>     -                        db.make<NameType>(StringView(first, t + 1)));
>     -                    first = t+1;
>     -                    db.FixForwardReferences = true;
>     -                }
>     -            }
>     -        }
>     +  if (consumeIf('_')) {
>     +    if (TemplateParams.empty()) {
>     +      FixForwardReferences = true;
>     +      return make<NameType>("FORWARD_REFERENCE");
>          }
>     -    return first;
>     +    return TemplateParams[0];
>     +  }
>     +
>     +  size_t Index;
>     +  if (parsePositiveInteger(&Index))
>     +    return nullptr;
>     +  ++Index;
>     +  if (!consumeIf('_'))
>     +    return nullptr;
>     +  if (Index >= TemplateParams.size()) {
>     +    FixForwardReferences = true;
>     +    return make<NameType>("FORWARD_REFERENCE");
>     +  }
>     +  return TemplateParams[Index];
>      }
>
>     -// <template-arg> ::= <type>                          # type or
>     template
>     -//                ::= X <expression> E                    #
>     expression
>     -//                ::= <expr-primary>                    # simple
>     expressions
>     -//                ::= J <template-arg>* E                     #
>     argument pack
>     -//                ::= LZ <encoding> E                     # extension
>     -const char*
>     -parse_template_arg(const char* first, const char* last, Db& db)
>     -{
>     -    if (first != last)
>     -    {
>     -        const char* t;
>     -        switch (*first)
>     -        {
>     -        case 'X':
>     -            t = parse_expression(first+1, last, db);
>     -            if (t != first+1)
>     -            {
>     -                if (t != last && *t == 'E')
>     -                    first = t+1;
>     -            }
>     -            break;
>     -        case 'J': {
>     -            t = first+1;
>     -            if (t == last)
>     -                return first;
>     -            size_t ArgsBegin = db.Names.size();
>     -            while (*t != 'E')
>     -            {
>     -                const char* t1 = parse_template_arg(t, last, db);
>     -                if (t1 == t)
>     -                    return first;
>     -                t = t1;
>     -            }
>     -            NodeArray Args = db.popTrailingNodeArray(ArgsBegin);
>     -            db.Names.push_back(db.make<TemplateArgumentPack>(Args));
>     -            first = t+1;
>     -            break;
>     -        }
>     -        case 'L':
>     -            // <expr-primary> or LZ <encoding> E
>     -            if (first+1 != last && first[1] == 'Z')
>     -            {
>     -                t = parse_encoding(first+2, last, db);
>     -                if (t != first+2 && t != last && *t == 'E')
>     -                    first = t+1;
>     -            }
>     -            else
>     -                first = parse_expr_primary(first, last, db);
>     -            break;
>     -        default:
>     -            // <type>
>     -            first = parse_type(first, last, db);
>     -            break;
>     -        }
>     +// <template-arg> ::= <type> # type or template
>     +//                ::= X <expression> E          # expression
>     +//                ::= <expr-primary>            # simple expressions
>     +//                ::= J <template-arg>* E       # argument pack
>     +//                ::= LZ <encoding> E           # extension
>     +Node *Db::parseTemplateArg() {
>     +  switch (look()) {
>     +  case 'X': {
>     +    ++First;
>     +    Node *Arg = parseExpr();
>     +    if (Arg == nullptr || !consumeIf('E'))
>     +      return nullptr;
>     +    return Arg;
>     +  }
>     +  case 'J': {
>     +    ++First;
>     +    size_t ArgsBegin = Names.size();
>     +    while (!consumeIf('E')) {
>     +      Node *Arg = parseTemplateArg();
>     +      if (Arg == nullptr)
>     +        return nullptr;
>     +      Names.push_back(Arg);
>          }
>     -    return first;
>     +    NodeArray Args = popTrailingNodeArray(ArgsBegin);
>     +    return make<TemplateArgumentPack>(Args);
>     +  }
>     +  case 'L': {
>     +    //                ::= LZ <encoding> E           # extension
>     +    if (look(1) == 'Z') {
>     +      First += 2;
>     +      Node *Arg = parseEncoding();
>     +      if (Arg == nullptr || !consumeIf('E'))
>     +        return nullptr;
>     +      return Arg;
>     +    }
>     +    //                ::= <expr-primary>            # simple
>     expressions
>     +    return parseExprPrimary();
>     +  }
>     +  default:
>     +    return parseType();
>     +  }
>      }
>
>      // <template-args> ::= I <template-arg>* E
>      //     extension, the abi says <template-arg>+
>     -const char*
>     -parse_template_args(const char* first, const char* last, Db& db)
>     -{
>     -    if (last - first >= 2 && *first == 'I')
>     -    {
>     -        if (db.TagTemplates)
>     -            db.TemplateParams.clear();
>     -        const char* t = first+1;
>     -        size_t begin_idx = db.Names.size();
>     -        while (*t != 'E')
>     -        {
>     -            if (db.TagTemplates)
>     -            {
>     -                auto TmpParams = std::move(db.TemplateParams);
>     -                size_t k0 = db.Names.size();
>     -                const char* t1 = parse_template_arg(t, last, db);
>     -                size_t k1 = db.Names.size();
>     -                db.TemplateParams = std::move(TmpParams);
>     -                if (t1 == t || t1 == last || k0 + 1 != k1)
>     -                    return first;
>     -                Node *TableEntry = db.Names.back();
>     -                if (TableEntry->getKind() ==
>     Node::KTemplateArgumentPack)
>     -                  TableEntry = db.make<ParameterPack>(
>     -                      static_cast<TemplateArgumentPack*>(TableEntry)
>     -                          ->getElements());
>     -                db.TemplateParams.push_back(TableEntry);
>     -                t = t1;
>     -                continue;
>     -            }
>     -            size_t k0 = db.Names.size();
>     -            const char* t1 = parse_template_arg(t, last, db);
>     -            size_t k1 = db.Names.size();
>     -            if (t1 == t || t1 == last || k0 > k1)
>     -              return first;
>     -            t = t1;
>     -        }
>     -        if (begin_idx > db.Names.size())
>     -            return first;
>     -        first = t + 1;
>     -        auto *tp = db.make<TemplateArgs>(
>     -            db.popTrailingNodeArray(begin_idx));
>     -        db.Names.push_back(tp);
>     +Node *Db::parseTemplateArgs() {
>     +  if (!consumeIf('I'))
>     +    return nullptr;
>     +
>     +  // <template-params> refer to the innermost <template-args>.
>     Clear out any
>     +  // outer args that we may have inserted into TemplateParams.
>     +  if (TagTemplates)
>     +    TemplateParams.clear();
>     +
>     +  size_t ArgsBegin = Names.size();
>     +  while (!consumeIf('E')) {
>     +    if (TagTemplates) {
>     +      auto OldParams = std::move(TemplateParams);
>     +      Node *Arg = parseTemplateArg();
>     +      TemplateParams = std::move(OldParams);
>     +      if (Arg == nullptr)
>     +        return nullptr;
>     +      Names.push_back(Arg);
>     +      Node *TableEntry = Arg;
>     +      if (Arg->getKind() == Node::KTemplateArgumentPack) {
>     +        TableEntry = make<ParameterPack>(
>     +           
>     static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
>     +      }
>     +      TemplateParams.push_back(TableEntry);
>     +    } else {
>     +      Node *Arg = parseTemplateArg();
>     +      if (Arg == nullptr)
>     +        return nullptr;
>     +      Names.push_back(Arg);
>          }
>     -    return first;
>     +  }
>     +  return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin));
>      }
>
>      // <discriminator> := _ <non-negative number>     # when number < 10
>     @@ -4859,183 +4765,106 @@ parse_discriminator(const char* first, c
>          return first;
>      }
>
>     -// _block_invoke
>     -// _block_invoke<decimal-digit>+
>     -// _block_invoke_<decimal-digit>+
>     -
>     -const char*
>     -parse_block_invoke(const char* first, const char* last, Db& db)
>     -{
>     -    if (last - first >= 13)
>     -    {
>     -        // FIXME: strcmp?
>     -        const char test[] = "_block_invoke";
>     -        const char* t = first;
>     -        for (int i = 0; i < 13; ++i, ++t)
>     -        {
>     -            if (*t != test[i])
>     -                return first;
>     -        }
>     -        if (t != last)
>     -        {
>     -            if (*t == '_')
>     -            {
>     -                // must have at least 1 decimal digit
>     -                if (++t == last || !std::isdigit(*t))
>     -                    return first;
>     -                ++t;
>     -            }
>     -            // parse zero or more digits
>     -            while (t != last && isdigit(*t))
>     -                ++t;
>     -        }
>     -        if (db.Names.empty())
>     -            return first;
>     -        db.Names.back() =
>     -            db.make<SpecialName>("invocation function for block in ",
>     -                                  db.Names.back());
>     -        first = t;
>     +// <mangled-name> ::= _Z <encoding>
>     +//                ::= <type>
>     +// extension      ::= ___Z <encoding> _block_invoke
>     +// extension      ::= ___Z <encoding> _block_invoke<decimal-digit>+
>     +// extension      ::= ___Z <encoding> _block_invoke_<decimal-digit>+
>     +Node *Db::parse() {
>     +  if (consumeIf("_Z")) {
>     +    Node *Encoding = parseEncoding();
>     +    if (Encoding == nullptr)
>     +      return nullptr;
>     +    if (look() == '.') {
>     +      Encoding = make<DotSuffix>(Encoding, StringView(First, Last));
>     +      First = Last;
>          }
>     -    return first;
>     -}
>     +    if (numLeft() != 0)
>     +      return nullptr;
>     +    return Encoding;
>     +  }
>
>     -// extension
>     -// <dot-suffix> := .<anything and everything>
>     +  if (consumeIf("___Z")) {
>     +    Node *Encoding = parseEncoding();
>     +    if (Encoding == nullptr || !consumeIf("_block_invoke"))
>     +      return nullptr;
>     +    consumeIf('_');
>     +    if (parseNumber().empty())
>     +      return nullptr;
>     +    if (numLeft() != 0)
>     +      return nullptr;
>     +    return make<SpecialName>("invocation function for block in ",
>     Encoding);
>     +  }
>
>     -const char*
>     -parse_dot_suffix(const char* first, const char* last, Db& db)
>     -{
>     -    if (first != last && *first == '.')
>     -    {
>     -        if (db.Names.empty())
>     -            return first;
>     -        db.Names.back() =
>     -            db.make<DotSuffix>(db.Names.back(), StringView(first,
>     last));
>     -        first = last;
>     -    }
>     -    return first;
>     +  Node *Ty = parseType();
>     +  if (numLeft() != 0)
>     +    return nullptr;
>     +  return Ty;
>      }
>     +}  // unnamed namespace
>
>      enum {
>     -    unknown_error = -4,
>     -    invalid_args = -3,
>     -    invalid_mangled_name,
>     -    memory_alloc_failure,
>     -    success
>     +  unknown_error = -4,
>     +  invalid_args = -3,
>     +  invalid_mangled_name = -2,
>     +  memory_alloc_failure = -1,
>     +  success = 0,
>      };
>
>     -// <block-involcaton-function> ___Z<encoding>_block_invoke
>     -// <block-involcaton-function>
>     ___Z<encoding>_block_invoke<decimal-digit>+
>     -// <block-involcaton-function>
>     ___Z<encoding>_block_invoke_<decimal-digit>+
>     -// <mangled-name> ::= _Z<encoding>
>     -//                ::= <type>
>     -void
>     -demangle(const char* first, const char* last, Db& db, int& status)
>     -{
>     -    if (first >= last)
>     -    {
>     -        status = invalid_mangled_name;
>     -        return;
>     -    }
>     -    if (*first == '_')
>     -    {
>     -        if (last - first >= 4)
>     -        {
>     -            if (first[1] == 'Z')
>     -            {
>     -                const char* t = parse_encoding(first+2, last, db);
>     -                if (t != first+2 && t != last && *t == '.')
>     -                    t = parse_dot_suffix(t, last, db);
>     -                if (t != last)
>     -                    status = invalid_mangled_name;
>     -            }
>     -            else if (first[1] == '_' && first[2] == '_' &&
>     first[3] == 'Z')
>     -            {
>     -                const char* t = parse_encoding(first+4, last, db);
>     -                if (t != first+4 && t != last)
>     -                {
>     -                    const char* t1 = parse_block_invoke(t, last, db);
>     -                    if (t1 != last)
>     -                        status = invalid_mangled_name;
>     -                }
>     -                else
>     -                    status = invalid_mangled_name;
>     -            }
>     -            else
>     -                status = invalid_mangled_name;
>     -        }
>     -        else
>     -            status = invalid_mangled_name;
>     -    }
>     -    else
>     -    {
>     -        const char* t = parse_type(first, last, db);
>     -        if (t != last)
>     -            status = invalid_mangled_name;
>     -    }
>     -    if (status == success && db.Names.empty())
>     -        status = invalid_mangled_name;
>     -}
>     -
>     -}  // unnamed namespace
>     -
>     -
>      namespace __cxxabiv1 {
>      extern "C" _LIBCXXABI_FUNC_VIS char *
>     -__cxa_demangle(const char *mangled_name, char *buf, size_t *n,
>     int *status) {
>     -    if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
>     -    {
>     -        if (status)
>     -            *status = invalid_args;
>     -        return nullptr;
>     -    }
>     -
>     -    size_t internal_size = buf != nullptr ? *n : 0;
>     -    Db db;
>     -    int internal_status = success;
>     -    size_t len = std::strlen(mangled_name);
>     -    demangle(mangled_name, mangled_name + len, db,
>     -             internal_status);
>     -
>     -    if (internal_status == success && db.FixForwardReferences &&
>     -        !db.TemplateParams.empty())
>     -    {
>     -        db.FixForwardReferences = false;
>     -        db.TagTemplates = false;
>     -        db.Names.clear();
>     -        db.Subs.clear();
>     -        demangle(mangled_name, mangled_name + len, db,
>     internal_status);
>     -        if (db.FixForwardReferences)
>     -            internal_status = invalid_mangled_name;
>     -    }
>     -
>     -    if (internal_status == success &&
>     -        db.Names.back()->containsUnexpandedParameterPack())
>     -        internal_status = invalid_mangled_name;
>     -
>     -    if (internal_status == success)
>     -    {
>     -        if (!buf)
>     -        {
>     -            internal_size = 1024;
>     -            buf = static_cast<char*>(std::malloc(internal_size));
>     -        }
>     +__cxa_demangle(const char *MangledName, char *Buf, size_t *N, int
>     *Status) {
>     +  if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
>     +    if (Status)
>     +      *Status = invalid_args;
>     +    return nullptr;
>     +  }
>
>     -        if (buf)
>     -        {
>     -            OutputStream s(buf, internal_size);
>     -            db.Names.back()->print(s);
>     -            s += '\0';
>     -            if (n) *n = s.getCurrentPosition();
>     -            buf = s.getBuffer();
>     -        }
>     -        else
>     -            internal_status = memory_alloc_failure;
>     -    }
>     -    else
>     -        buf = nullptr;
>     -    if (status)
>     -        *status = internal_status;
>     -    return buf;
>     +  size_t BufSize = Buf != nullptr ? *N : 0;
>     +  int InternalStatus = success;
>     +  size_t MangledNameLength = std::strlen(MangledName);
>     +
>     +  Db Parser(MangledName, MangledName + MangledNameLength);
>     +  Node *AST = Parser.parse();
>     +
>     +  if (AST == nullptr)
>     +    InternalStatus = invalid_mangled_name;
>     +
>     +  if (InternalStatus == success && Parser.FixForwardReferences &&
>     +      !Parser.TemplateParams.empty()) {
>     +    Parser.FixForwardReferences = false;
>     +    Parser.TagTemplates = false;
>     +    Parser.Names.clear();
>     +    Parser.Subs.clear();
>     +    Parser.First = MangledName;
>     +    Parser.Last = MangledName + MangledNameLength;
>     +    AST = Parser.parse();
>     +    if (AST == nullptr || Parser.FixForwardReferences)
>     +      InternalStatus = invalid_mangled_name;
>     +  }
>     +
>     +  if (InternalStatus == success &&
>     AST->containsUnexpandedParameterPack())
>     +    InternalStatus = invalid_mangled_name;
>     +
>     +  if (InternalStatus == success) {
>     +    if (Buf == nullptr) {
>     +      BufSize = 1024;
>     +      Buf = static_cast<char*>(std::malloc(BufSize));
>     +    }
>     +
>     +    if (Buf) {
>     +      OutputStream Stream(Buf, BufSize);
>     +      AST->print(Stream);
>     +      Stream += '\0';
>     +      if (N != nullptr)
>     +        *N = Stream.getCurrentPosition();
>     +      Buf = Stream.getBuffer();
>     +    } else
>     +      InternalStatus = memory_alloc_failure;
>     +  }
>     +
>     +  if (Status)
>     +    *Status = InternalStatus;
>     +  return InternalStatus == success ? Buf : nullptr;
>      }
>      }  // __cxxabiv1
>
>     Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
>     URL:
>     http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=326797&r1=326796&r2=326797&view=diff
>     <http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=326797&r1=326796&r2=326797&view=diff>
>     ==============================================================================
>     --- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
>     +++ libcxxabi/trunk/test/test_demangle.pass.cpp Tue Mar  6
>     06:21:10 2018
>     @@ -29713,6 +29713,9 @@ const char* cases[][2] =
>
>          {"_ZNKR4llvm8OptionalINS_11MCFixupKindEEdeEv",
>     "llvm::Optional<llvm::MCFixupKind>::operator*() const &"},
>        
>      {"_ZZL23isValidCoroutineContextRN5clang4SemaENS_14SourceLocationEN4llvm9StringRefEENK3$_4clEZL23isValidCoroutineContextS1_S2_S4_E15InvalidFuncDiag",
>     "isValidCoroutineContext(clang::Sema&, clang::SourceLocation,
>     llvm::StringRef)::$_4::operator()(isValidCoroutineContext(clang::Sema&,
>     clang::SourceLocation, llvm::StringRef)::InvalidFuncDiag) const"},
>     +
>     +    // ABI tags can apply to built-in substitutions.
>     +    {"_Z1fSsB1XS_", "f(std::string[abi:X], std::string[abi:X])"},
>      };
>
>      const unsigned N = sizeof(cases) / sizeof(cases[0]);
>
>
>     _______________________________________________
>     cfe-commits mailing list
>     cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
>     http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180306/7054e3a4/attachment-0001.html>


More information about the cfe-commits mailing list