r352369 - [AST] Introduce GenericSelectionExpr::Association

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 28 10:10:36 PST 2019


Hi,

This doesn't compile when using GCC 4.8.4:

372/372] Building CXX object
tools/clang/tools/clang-import-test/CMakeFiles/clang-import-test.dir/clang-import-test.cpp.o
FAILED: tools/clang/tools/clang-import-test/CMakeFiles/clang-import-test.dir/clang-import-test.cpp.o
/work/gccprefix/bin/g++  -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-Itools/clang/tools/clang-import-test
-I/work/llvm.monorepo/clang/tools/clang-import-test
-I/work/llvm.monorepo/clang/include -Itools/clang/include
-I/usr/include/libxml2 -Iinclude -I/work/llvm.monorepo/llvm/include
-fPIC -fvisibility-inlines-hidden -std=c++11 -Wall -Wextra
-Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wno-missing-field-initializers -pedantic -Wno-long-long
-Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment
-ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual
-fno-strict-aliasing -O3    -UNDEBUG  -fno-exceptions -fno-rtti -MD
-MT tools/clang/tools/clang-import-test/CMakeFiles/clang-import-test.dir/clang-import-test.cpp.o
-MF tools/clang/tools/clang-import-test/CMakeFiles/clang-import-test.dir/clang-import-test.cpp.o.d
-o tools/clang/tools/clang-import-test/CMakeFiles/clang-import-test.dir/clang-import-test.cpp.o
-c /work/llvm.monorepo/clang/tools/clang-import-test/clang-import-test.cpp
In file included from /work/llvm.monorepo/clang/include/clang/AST/Attr.h:19:0,
                 from /work/llvm.monorepo/clang/include/clang/AST/TypeLoc.h:17,
                 from
/work/llvm.monorepo/clang/include/clang/AST/ASTTypeTraits.h:23,
                 from
/work/llvm.monorepo/clang/include/clang/AST/ASTContext.h:18,
                 from
/work/llvm.monorepo/clang/tools/clang-import-test/clang-import-test.cpp:9:
/work/llvm.monorepo/clang/include/clang/AST/Expr.h:5113:22: error:
invalid use of dependent type
‘clang::GenericSelectionExpr::AssociationIteratorTy<Const>::StmtPtrPtrTy’
     StmtPtrPtrTy E = nullptr;
                      ^
/work/llvm.monorepo/clang/include/clang/AST/Expr.h:5114:23: error:
invalid use of dependent type
‘clang::GenericSelectionExpr::AssociationIteratorTy<Const>::TSIPtrPtrTy’
     TSIPtrPtrTy TSI = nullptr; // Kept in sync with E.
                       ^
ninja: build stopped: subcommand failed.

Something like this makes the compiler happy:

diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index c7b015ab804..45d12401970 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -5110,15 +5110,15 @@ class GenericSelectionExpr final
     using TSIPtrPtrTy =
         typename std::conditional<Const, const TypeSourceInfo *const *,
                                   TypeSourceInfo **>::type;
-    StmtPtrPtrTy E = nullptr;
-    TSIPtrPtrTy TSI = nullptr; // Kept in sync with E.
+    StmtPtrPtrTy E;
+    TSIPtrPtrTy TSI; // Kept in sync with E.
     unsigned Offset = 0, SelectedOffset = 0;
     AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset,
                           unsigned SelectedOffset)
         : E(E), TSI(TSI), Offset(Offset), SelectedOffset(SelectedOffset) {}

   public:
-    AssociationIteratorTy() = default;
+    AssociationIteratorTy() : E(0), TSI(0) {}
     typename BaseTy::reference operator*() const {
       return AssociationTy<Const>(cast<Expr>(*E), *TSI,
                                   Offset == SelectedOffset);


But on our end (Chromium), we're looking at solving it by using Clang
for our build instead.

On Mon, Jan 28, 2019 at 9:18 AM Bruno Ricci via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
>
> Author: brunoricci
> Date: Mon Jan 28 06:18:11 2019
> New Revision: 352369
>
> URL: http://llvm.org/viewvc/llvm-project?rev=352369&view=rev
> Log:
> [AST] Introduce GenericSelectionExpr::Association
>
> Introduce a new class GenericSelectionExpr::Association which bundle together
> an association expression and its TypeSourceInfo.
>
> An iterator GenericSelectionExpr::AssociationIterator is additionally added to
> make it possible to iterate over ranges of Associations. This iterator is a
> kind of proxy iterator which abstract over how exactly the expressions and the
> TypeSourceInfos are stored.
>
> Differential Revision: https://reviews.llvm.org/D57106
>
> Reviewed By: aaron.ballman
>
> Reviewers: aaron.ballman, steveire, dblaikie, mclow.lists
>
>
> Modified:
>     cfe/trunk/include/clang/AST/Expr.h
>     cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>     cfe/trunk/include/clang/AST/StmtDataCollectors.td
>     cfe/trunk/lib/AST/ASTDumper.cpp
>     cfe/trunk/lib/AST/StmtPrinter.cpp
>     cfe/trunk/lib/AST/StmtProfile.cpp
>     cfe/trunk/lib/Sema/SemaExprObjC.cpp
>     cfe/trunk/lib/Sema/SemaPseudoObject.cpp
>     cfe/trunk/lib/Sema/TreeTransform.h
>
> Modified: cfe/trunk/include/clang/AST/Expr.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Expr.h (original)
> +++ cfe/trunk/include/clang/AST/Expr.h Mon Jan 28 06:18:11 2019
> @@ -28,6 +28,8 @@
>  #include "clang/Basic/TypeTraits.h"
>  #include "llvm/ADT/APFloat.h"
>  #include "llvm/ADT/APSInt.h"
> +#include "llvm/ADT/iterator.h"
> +#include "llvm/ADT/iterator_range.h"
>  #include "llvm/ADT/SmallVector.h"
>  #include "llvm/ADT/StringRef.h"
>  #include "llvm/Support/AtomicOrdering.h"
> @@ -5052,6 +5054,86 @@ class GenericSelectionExpr final
>      return getNumAssocs();
>    }
>
> +  template <bool Const> class AssociationIteratorTy;
> +  /// Bundle together an association expression and its TypeSourceInfo.
> +  /// The Const template parameter is for the const and non-const versions
> +  /// of AssociationTy.
> +  template <bool Const> class AssociationTy {
> +    friend class GenericSelectionExpr;
> +    template <bool OtherConst> friend class AssociationIteratorTy;
> +    using ExprPtrTy =
> +        typename std::conditional<Const, const Expr *, Expr *>::type;
> +    using TSIPtrTy = typename std::conditional<Const, const TypeSourceInfo *,
> +                                               TypeSourceInfo *>::type;
> +    ExprPtrTy E;
> +    TSIPtrTy TSI;
> +    bool Selected;
> +    AssociationTy(ExprPtrTy E, TSIPtrTy TSI, bool Selected)
> +        : E(E), TSI(TSI), Selected(Selected) {}
> +
> +  public:
> +    ExprPtrTy getAssociationExpr() const { return E; }
> +    TSIPtrTy getTypeSourceInfo() const { return TSI; }
> +    QualType getType() const { return TSI ? TSI->getType() : QualType(); }
> +    bool isSelected() const { return Selected; }
> +    AssociationTy *operator->() { return this; }
> +    const AssociationTy *operator->() const { return this; }
> +  }; // class AssociationTy
> +
> +  /// Iterator over const and non-const Association objects. The Association
> +  /// objects are created on the fly when the iterator is dereferenced.
> +  /// This abstract over how exactly the association expressions and the
> +  /// corresponding TypeSourceInfo * are stored.
> +  template <bool Const>
> +  class AssociationIteratorTy
> +      : public llvm::iterator_facade_base<
> +            AssociationIteratorTy<Const>, std::input_iterator_tag,
> +            AssociationTy<Const>, std::ptrdiff_t, AssociationTy<Const>,
> +            AssociationTy<Const>> {
> +    friend class GenericSelectionExpr;
> +    // FIXME: This iterator could conceptually be a random access iterator, and
> +    // it would be nice if we could strengthen the iterator category someday.
> +    // However this iterator does not satisfy two requirements of forward
> +    // iterators:
> +    // a) reference = T& or reference = const T&
> +    // b) If It1 and It2 are both dereferenceable, then It1 == It2 if and only
> +    //    if *It1 and *It2 are bound to the same objects.
> +    // An alternative design approach was discussed during review;
> +    // store an Association object inside the iterator, and return a reference
> +    // to it when dereferenced. This idea was discarded beacuse of nasty
> +    // lifetime issues:
> +    //    AssociationIterator It = ...;
> +    //    const Association &Assoc = *It++; // Oops, Assoc is dangling.
> +    using BaseTy = typename AssociationIteratorTy::iterator_facade_base;
> +    using StmtPtrPtrTy =
> +        typename std::conditional<Const, const Stmt *const *, Stmt **>::type;
> +    using TSIPtrPtrTy =
> +        typename std::conditional<Const, const TypeSourceInfo *const *,
> +                                  TypeSourceInfo **>::type;
> +    StmtPtrPtrTy E = nullptr;
> +    TSIPtrPtrTy TSI = nullptr; // Kept in sync with E.
> +    unsigned Offset = 0, SelectedOffset = 0;
> +    AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset,
> +                          unsigned SelectedOffset)
> +        : E(E), TSI(TSI), Offset(Offset), SelectedOffset(SelectedOffset) {}
> +
> +  public:
> +    AssociationIteratorTy() = default;
> +    typename BaseTy::reference operator*() const {
> +      return AssociationTy<Const>(cast<Expr>(*E), *TSI,
> +                                  Offset == SelectedOffset);
> +    }
> +    typename BaseTy::pointer operator->() const { return **this; }
> +    using BaseTy::operator++;
> +    AssociationIteratorTy &operator++() {
> +      ++E;
> +      ++TSI;
> +      ++Offset;
> +      return *this;
> +    }
> +    bool operator==(AssociationIteratorTy Other) const { return E == Other.E; }
> +  }; // class AssociationIterator
> +
>    /// Build a non-result-dependent generic selection expression.
>    GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
>                         Expr *ControllingExpr,
> @@ -5092,6 +5174,14 @@ public:
>    static GenericSelectionExpr *CreateEmpty(const ASTContext &Context,
>                                             unsigned NumAssocs);
>
> +  using Association = AssociationTy<false>;
> +  using ConstAssociation = AssociationTy<true>;
> +  using AssociationIterator = AssociationIteratorTy<false>;
> +  using ConstAssociationIterator = AssociationIteratorTy<true>;
> +  using association_range = llvm::iterator_range<AssociationIterator>;
> +  using const_association_range =
> +      llvm::iterator_range<ConstAssociationIterator>;
> +
>    /// The number of association expressions.
>    unsigned getNumAssocs() const { return NumAssocs; }
>
> @@ -5135,23 +5225,43 @@ public:
>      return {getTrailingObjects<TypeSourceInfo *>(), NumAssocs};
>    }
>
> -  Expr *getAssocExpr(unsigned i) {
> -    return cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + i]);
> -  }
> -  const Expr *getAssocExpr(unsigned i) const {
> -    return cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + i]);
> -  }
> -
> -  TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) {
> -    return getTrailingObjects<TypeSourceInfo *>()[i];
> -  }
> -  const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
> -    return getTrailingObjects<TypeSourceInfo *>()[i];
> -  }
> -
> -  QualType getAssocType(unsigned i) const {
> -    const TypeSourceInfo *TSI = getAssocTypeSourceInfo(i);
> -    return TSI ? TSI->getType() : QualType();
> +  /// Return the Ith association expression with its TypeSourceInfo,
> +  /// bundled together in GenericSelectionExpr::(Const)Association.
> +  Association getAssociation(unsigned I) {
> +    assert(I < getNumAssocs() &&
> +           "Out-of-range index in GenericSelectionExpr::getAssociation!");
> +    return Association(
> +        cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
> +        getTrailingObjects<TypeSourceInfo *>()[I],
> +        !isResultDependent() && (getResultIndex() == I));
> +  }
> +  ConstAssociation getAssociation(unsigned I) const {
> +    assert(I < getNumAssocs() &&
> +           "Out-of-range index in GenericSelectionExpr::getAssociation!");
> +    return ConstAssociation(
> +        cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
> +        getTrailingObjects<TypeSourceInfo *>()[I],
> +        !isResultDependent() && (getResultIndex() == I));
> +  }
> +
> +  association_range associations() {
> +    AssociationIterator Begin(getTrailingObjects<Stmt *>() +
> +                                  AssocExprStartIndex,
> +                              getTrailingObjects<TypeSourceInfo *>(),
> +                              /*Offset=*/0, ResultIndex);
> +    AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
> +                            /*Offset=*/NumAssocs, ResultIndex);
> +    return llvm::make_range(Begin, End);
> +  }
> +
> +  const_association_range associations() const {
> +    ConstAssociationIterator Begin(getTrailingObjects<Stmt *>() +
> +                                       AssocExprStartIndex,
> +                                   getTrailingObjects<TypeSourceInfo *>(),
> +                                   /*Offset=*/0, ResultIndex);
> +    ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
> +                                 /*Offset=*/NumAssocs, ResultIndex);
> +    return llvm::make_range(Begin, End);
>    }
>
>    SourceLocation getGenericLoc() const {
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jan 28 06:18:11 2019
> @@ -2300,10 +2300,10 @@ bool RecursiveASTVisitor<Derived>::Trave
>  // generic associations).
>  DEF_TRAVERSE_STMT(GenericSelectionExpr, {
>    TRY_TO(TraverseStmt(S->getControllingExpr()));
> -  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
> -    if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
> -      TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
> -    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i));
> +  for (const GenericSelectionExpr::Association &Assoc : S->associations()) {
> +    if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
> +      TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
> +    TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
>    }
>    ShouldVisitChildren = false;
>  })
>
> Modified: cfe/trunk/include/clang/AST/StmtDataCollectors.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtDataCollectors.td?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/StmtDataCollectors.td (original)
> +++ cfe/trunk/include/clang/AST/StmtDataCollectors.td Mon Jan 28 06:18:11 2019
> @@ -189,8 +189,8 @@ class CXXFoldExpr {
>  }
>  class GenericSelectionExpr {
>    code Code = [{
> -    for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
> -      addData(S->getAssocType(i));
> +    for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) {
> +      addData(Assoc.getType());
>      }
>    }];
>  }
>
> Modified: cfe/trunk/lib/AST/ASTDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)
> +++ cfe/trunk/lib/AST/ASTDumper.cpp Mon Jan 28 06:18:11 2019
> @@ -1462,21 +1462,21 @@ void ASTDumper::VisitGenericSelectionExp
>    dumpStmt(E->getControllingExpr());
>    dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove
>
> -  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
> +  for (const auto &Assoc : E->associations()) {
>      dumpChild([=] {
> -      if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) {
> +      if (const TypeSourceInfo *TSI = Assoc.getTypeSourceInfo()) {
>          OS << "case ";
>          NodeDumper.dumpType(TSI->getType());
>        } else {
>          OS << "default";
>        }
>
> -      if (!E->isResultDependent() && E->getResultIndex() == I)
> +      if (Assoc.isSelected())
>          OS << " selected";
>
> -      if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I))
> +      if (const TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
>          dumpTypeAsChild(TSI->getType());
> -      dumpStmt(E->getAssocExpr(I));
> +      dumpStmt(Assoc.getAssociationExpr());
>      });
>    }
>  }
>
> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jan 28 06:18:11 2019
> @@ -1261,15 +1261,15 @@ void StmtPrinter::VisitUnaryExprOrTypeTr
>  void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
>    OS << "_Generic(";
>    PrintExpr(Node->getControllingExpr());
> -  for (unsigned i = 0; i != Node->getNumAssocs(); ++i) {
> +  for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
>      OS << ", ";
> -    QualType T = Node->getAssocType(i);
> +    QualType T = Assoc.getType();
>      if (T.isNull())
>        OS << "default";
>      else
>        T.print(OS, Policy);
>      OS << ": ";
> -    PrintExpr(Node->getAssocExpr(i));
> +    PrintExpr(Assoc.getAssociationExpr());
>    }
>    OS << ")";
>  }
>
> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
> +++ cfe/trunk/lib/AST/StmtProfile.cpp Mon Jan 28 06:18:11 2019
> @@ -1259,13 +1259,14 @@ void StmtProfiler::VisitBlockExpr(const
>
>  void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
>    VisitExpr(S);
> -  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
> -    QualType T = S->getAssocType(i);
> +  for (const GenericSelectionExpr::ConstAssociation &Assoc :
> +       S->associations()) {
> +    QualType T = Assoc.getType();
>      if (T.isNull())
>        ID.AddPointer(nullptr);
>      else
>        VisitType(T);
> -    VisitExpr(S->getAssocExpr(i));
> +    VisitExpr(Assoc.getAssociationExpr());
>    }
>  }
>
>
> Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Jan 28 06:18:11 2019
> @@ -4332,14 +4332,16 @@ Expr *Sema::stripARCUnbridgedCast(Expr *
>      assert(!gse->isResultDependent());
>
>      unsigned n = gse->getNumAssocs();
> -    SmallVector<Expr*, 4> subExprs(n);
> -    SmallVector<TypeSourceInfo*, 4> subTypes(n);
> -    for (unsigned i = 0; i != n; ++i) {
> -      subTypes[i] = gse->getAssocTypeSourceInfo(i);
> -      Expr *sub = gse->getAssocExpr(i);
> -      if (i == gse->getResultIndex())
> +    SmallVector<Expr *, 4> subExprs;
> +    SmallVector<TypeSourceInfo *, 4> subTypes;
> +    subExprs.reserve(n);
> +    subTypes.reserve(n);
> +    for (const GenericSelectionExpr::Association &assoc : gse->associations()) {
> +      subTypes.push_back(assoc.getTypeSourceInfo());
> +      Expr *sub = assoc.getAssociationExpr();
> +      if (assoc.isSelected())
>          sub = stripARCUnbridgedCast(sub);
> -      subExprs[i] = sub;
> +      subExprs.push_back(sub);
>      }
>
>      return GenericSelectionExpr::Create(
>
> Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Mon Jan 28 06:18:11 2019
> @@ -140,19 +140,23 @@ namespace {
>          unsigned resultIndex = gse->getResultIndex();
>          unsigned numAssocs = gse->getNumAssocs();
>
> -        SmallVector<Expr*, 8> assocs(numAssocs);
> -        SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
> +        SmallVector<Expr *, 8> assocExprs;
> +        SmallVector<TypeSourceInfo *, 8> assocTypes;
> +        assocExprs.reserve(numAssocs);
> +        assocTypes.reserve(numAssocs);
>
> -        for (unsigned i = 0; i != numAssocs; ++i) {
> -          Expr *assoc = gse->getAssocExpr(i);
> -          if (i == resultIndex) assoc = rebuild(assoc);
> -          assocs[i] = assoc;
> -          assocTypes[i] = gse->getAssocTypeSourceInfo(i);
> +        for (const GenericSelectionExpr::Association &assoc :
> +             gse->associations()) {
> +          Expr *assocExpr = assoc.getAssociationExpr();
> +          if (assoc.isSelected())
> +            assocExpr = rebuild(assocExpr);
> +          assocExprs.push_back(assocExpr);
> +          assocTypes.push_back(assoc.getTypeSourceInfo());
>          }
>
>          return GenericSelectionExpr::Create(
>              S.Context, gse->getGenericLoc(), gse->getControllingExpr(),
> -            assocTypes, assocs, gse->getDefaultLoc(), gse->getRParenLoc(),
> +            assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
>              gse->containsUnexpandedParameterPack(), resultIndex);
>        }
>
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=352369&r1=352368&r2=352369&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jan 28 06:18:11 2019
> @@ -9071,10 +9071,10 @@ TreeTransform<Derived>::TransformGeneric
>
>    SmallVector<Expr *, 4> AssocExprs;
>    SmallVector<TypeSourceInfo *, 4> AssocTypes;
> -  for (unsigned i = 0; i != E->getNumAssocs(); ++i) {
> -    TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i);
> -    if (TS) {
> -      TypeSourceInfo *AssocType = getDerived().TransformType(TS);
> +  for (const GenericSelectionExpr::Association &Assoc : E->associations()) {
> +    TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
> +    if (TSI) {
> +      TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
>        if (!AssocType)
>          return ExprError();
>        AssocTypes.push_back(AssocType);
> @@ -9082,7 +9082,8 @@ TreeTransform<Derived>::TransformGeneric
>        AssocTypes.push_back(nullptr);
>      }
>
> -    ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
> +    ExprResult AssocExpr =
> +        getDerived().TransformExpr(Assoc.getAssociationExpr());
>      if (AssocExpr.isInvalid())
>        return ExprError();
>      AssocExprs.push_back(AssocExpr.get());
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list