From 586d949b9c554d5e5b7b445a49c122ce3d0e5c53 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Mon, 28 Jan 2019 18:40:26 +0000 Subject: [PATCH] Revert "[AST] Introduce GenericSelectionExpr::Association" This breaks GCC 4.8.4. Reported by email by Hans Wennborg. llvm-svn: 352403 --- clang/include/clang/AST/Expr.h | 144 +++----------------------- clang/include/clang/AST/RecursiveASTVisitor.h | 8 +- clang/include/clang/AST/StmtDataCollectors.td | 4 +- clang/lib/AST/ASTDumper.cpp | 10 +- clang/lib/AST/StmtPrinter.cpp | 6 +- clang/lib/AST/StmtProfile.cpp | 7 +- clang/lib/Sema/SemaExprObjC.cpp | 16 ++- clang/lib/Sema/SemaPseudoObject.cpp | 22 ++-- clang/lib/Sema/TreeTransform.h | 11 +- 9 files changed, 55 insertions(+), 173 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index c7b015a..f770cf3 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -28,8 +28,6 @@ #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" @@ -5054,86 +5052,6 @@ class GenericSelectionExpr final return getNumAssocs(); } - template 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 class AssociationTy { - friend class GenericSelectionExpr; - template friend class AssociationIteratorTy; - using ExprPtrTy = - typename std::conditional::type; - using TSIPtrTy = typename std::conditional::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 - class AssociationIteratorTy - : public llvm::iterator_facade_base< - AssociationIteratorTy, std::input_iterator_tag, - AssociationTy, std::ptrdiff_t, AssociationTy, - AssociationTy> { - 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::type; - using TSIPtrPtrTy = - typename std::conditional::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(cast(*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, @@ -5174,14 +5092,6 @@ public: static GenericSelectionExpr *CreateEmpty(const ASTContext &Context, unsigned NumAssocs); - using Association = AssociationTy; - using ConstAssociation = AssociationTy; - using AssociationIterator = AssociationIteratorTy; - using ConstAssociationIterator = AssociationIteratorTy; - using association_range = llvm::iterator_range; - using const_association_range = - llvm::iterator_range; - /// The number of association expressions. unsigned getNumAssocs() const { return NumAssocs; } @@ -5225,43 +5135,23 @@ public: return {getTrailingObjects(), NumAssocs}; } - /// 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(getTrailingObjects()[AssocExprStartIndex + I]), - getTrailingObjects()[I], - !isResultDependent() && (getResultIndex() == I)); - } - ConstAssociation getAssociation(unsigned I) const { - assert(I < getNumAssocs() && - "Out-of-range index in GenericSelectionExpr::getAssociation!"); - return ConstAssociation( - cast(getTrailingObjects()[AssocExprStartIndex + I]), - getTrailingObjects()[I], - !isResultDependent() && (getResultIndex() == I)); - } - - association_range associations() { - AssociationIterator Begin(getTrailingObjects() + - AssocExprStartIndex, - getTrailingObjects(), - /*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() + - AssocExprStartIndex, - getTrailingObjects(), - /*Offset=*/0, ResultIndex); - ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs, - /*Offset=*/NumAssocs, ResultIndex); - return llvm::make_range(Begin, End); + Expr *getAssocExpr(unsigned i) { + return cast(getTrailingObjects()[AssocExprStartIndex + i]); + } + const Expr *getAssocExpr(unsigned i) const { + return cast(getTrailingObjects()[AssocExprStartIndex + i]); + } + + TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { + return getTrailingObjects()[i]; + } + const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const { + return getTrailingObjects()[i]; + } + + QualType getAssocType(unsigned i) const { + const TypeSourceInfo *TSI = getAssocTypeSourceInfo(i); + return TSI ? TSI->getType() : QualType(); } SourceLocation getGenericLoc() const { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 51050e8..96f7887 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2301,10 +2301,10 @@ bool RecursiveASTVisitor::TraverseInitListExpr( // generic associations). DEF_TRAVERSE_STMT(GenericSelectionExpr, { TRY_TO(TraverseStmt(S->getControllingExpr())); - 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()); + 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)); } ShouldVisitChildren = false; }) diff --git a/clang/include/clang/AST/StmtDataCollectors.td b/clang/include/clang/AST/StmtDataCollectors.td index a46d271..90ca080 100644 --- a/clang/include/clang/AST/StmtDataCollectors.td +++ b/clang/include/clang/AST/StmtDataCollectors.td @@ -189,8 +189,8 @@ class CXXFoldExpr { } class GenericSelectionExpr { code Code = [{ - for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) { - addData(Assoc.getType()); + for (unsigned i = 0; i < S->getNumAssocs(); ++i) { + addData(S->getAssocType(i)); } }]; } diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 5c99dab..b91dab5 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -1462,21 +1462,21 @@ void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { dumpStmt(E->getControllingExpr()); dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove - for (const auto &Assoc : E->associations()) { + for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) { dumpChild([=] { - if (const TypeSourceInfo *TSI = Assoc.getTypeSourceInfo()) { + if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) { OS << "case "; NodeDumper.dumpType(TSI->getType()); } else { OS << "default"; } - if (Assoc.isSelected()) + if (!E->isResultDependent() && E->getResultIndex() == I) OS << " selected"; - if (const TypeSourceInfo *TSI = Assoc.getTypeSourceInfo()) + if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) dumpTypeAsChild(TSI->getType()); - dumpStmt(Assoc.getAssociationExpr()); + dumpStmt(E->getAssocExpr(I)); }); } } diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index acf19aa..221d134 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1261,15 +1261,15 @@ void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { OS << "_Generic("; PrintExpr(Node->getControllingExpr()); - for (const GenericSelectionExpr::Association &Assoc : Node->associations()) { + for (unsigned i = 0; i != Node->getNumAssocs(); ++i) { OS << ", "; - QualType T = Assoc.getType(); + QualType T = Node->getAssocType(i); if (T.isNull()) OS << "default"; else T.print(OS, Policy); OS << ": "; - PrintExpr(Assoc.getAssociationExpr()); + PrintExpr(Node->getAssocExpr(i)); } OS << ")"; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index e302b05..805056f 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1260,14 +1260,13 @@ void StmtProfiler::VisitBlockExpr(const BlockExpr *S) { void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) { VisitExpr(S); - for (const GenericSelectionExpr::ConstAssociation &Assoc : - S->associations()) { - QualType T = Assoc.getType(); + for (unsigned i = 0; i != S->getNumAssocs(); ++i) { + QualType T = S->getAssocType(i); if (T.isNull()) ID.AddPointer(nullptr); else VisitType(T); - VisitExpr(Assoc.getAssociationExpr()); + VisitExpr(S->getAssocExpr(i)); } } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index fdb5987..4ca3b85 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -4332,16 +4332,14 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { assert(!gse->isResultDependent()); unsigned n = gse->getNumAssocs(); - SmallVector subExprs; - SmallVector 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()) + SmallVector subExprs(n); + SmallVector subTypes(n); + for (unsigned i = 0; i != n; ++i) { + subTypes[i] = gse->getAssocTypeSourceInfo(i); + Expr *sub = gse->getAssocExpr(i); + if (i == gse->getResultIndex()) sub = stripARCUnbridgedCast(sub); - subExprs.push_back(sub); + subExprs[i] = sub; } return GenericSelectionExpr::Create( diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index 28a4d62..37dd7b1 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -140,23 +140,19 @@ namespace { unsigned resultIndex = gse->getResultIndex(); unsigned numAssocs = gse->getNumAssocs(); - SmallVector assocExprs; - SmallVector assocTypes; - assocExprs.reserve(numAssocs); - assocTypes.reserve(numAssocs); - - 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()); + SmallVector assocs(numAssocs); + SmallVector assocTypes(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); } return GenericSelectionExpr::Create( S.Context, gse->getGenericLoc(), gse->getControllingExpr(), - assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(), + assocTypes, assocs, gse->getDefaultLoc(), gse->getRParenLoc(), gse->containsUnexpandedParameterPack(), resultIndex); } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index e411a2a..1631ce8 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9073,10 +9073,10 @@ TreeTransform::TransformGenericSelectionExpr(GenericSelectionExpr *E) { SmallVector AssocExprs; SmallVector AssocTypes; - for (const GenericSelectionExpr::Association &Assoc : E->associations()) { - TypeSourceInfo *TSI = Assoc.getTypeSourceInfo(); - if (TSI) { - TypeSourceInfo *AssocType = getDerived().TransformType(TSI); + for (unsigned i = 0; i != E->getNumAssocs(); ++i) { + TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i); + if (TS) { + TypeSourceInfo *AssocType = getDerived().TransformType(TS); if (!AssocType) return ExprError(); AssocTypes.push_back(AssocType); @@ -9084,8 +9084,7 @@ TreeTransform::TransformGenericSelectionExpr(GenericSelectionExpr *E) { AssocTypes.push_back(nullptr); } - ExprResult AssocExpr = - getDerived().TransformExpr(Assoc.getAssociationExpr()); + ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i)); if (AssocExpr.isInvalid()) return ExprError(); AssocExprs.push_back(AssocExpr.get()); -- 2.7.4