[cfe-commits] r104107 - in /cfe/trunk: lib/AST/StmtProfile.cpp test/SemaTemplate/dependent-type-identity.cpp
Douglas Gregor
dgregor at apple.com
Tue May 18 21:13:23 PDT 2010
Author: dgregor
Date: Tue May 18 23:13:23 2010
New Revision: 104107
URL: http://llvm.org/viewvc/llvm-project?rev=104107&view=rev
Log:
Profile type-dependent uses of overloaded operators in C++ the same
way regardless of whether some overloaded operator functions were
found by name lookup within the template. Fixes PR6851.
Modified:
cfe/trunk/lib/AST/StmtProfile.cpp
cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp
Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=104107&r1=104106&r2=104107&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue May 18 23:13:23 2010
@@ -430,7 +430,215 @@
ID.AddBoolean(S->isConstQualAdded());
}
+static Stmt::StmtClass DecodeOperatorCall(CXXOperatorCallExpr *S,
+ UnaryOperator::Opcode &UnaryOp,
+ BinaryOperator::Opcode &BinaryOp) {
+ switch (S->getOperator()) {
+ case OO_None:
+ case OO_New:
+ case OO_Delete:
+ case OO_Array_New:
+ case OO_Array_Delete:
+ case OO_Arrow:
+ case OO_Call:
+ case OO_Conditional:
+ case NUM_OVERLOADED_OPERATORS:
+ llvm_unreachable("Invalid operator call kind");
+ return Stmt::ArraySubscriptExprClass;
+
+ case OO_Plus:
+ if (S->getNumArgs() == 1) {
+ UnaryOp = UnaryOperator::Plus;
+ return Stmt::UnaryOperatorClass;
+ }
+
+ BinaryOp = BinaryOperator::Add;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Minus:
+ if (S->getNumArgs() == 1) {
+ UnaryOp = UnaryOperator::Minus;
+ return Stmt::UnaryOperatorClass;
+ }
+
+ BinaryOp = BinaryOperator::Sub;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Star:
+ if (S->getNumArgs() == 1) {
+ UnaryOp = UnaryOperator::Minus;
+ return Stmt::UnaryOperatorClass;
+ }
+
+ BinaryOp = BinaryOperator::Sub;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Slash:
+ BinaryOp = BinaryOperator::Div;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Percent:
+ BinaryOp = BinaryOperator::Rem;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Caret:
+ BinaryOp = BinaryOperator::Xor;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Amp:
+ if (S->getNumArgs() == 1) {
+ UnaryOp = UnaryOperator::AddrOf;
+ return Stmt::UnaryOperatorClass;
+ }
+
+ BinaryOp = BinaryOperator::And;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Pipe:
+ BinaryOp = BinaryOperator::Or;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Tilde:
+ UnaryOp = UnaryOperator::Not;
+ return Stmt::UnaryOperatorClass;
+
+ case OO_Exclaim:
+ UnaryOp = UnaryOperator::LNot;
+ return Stmt::UnaryOperatorClass;
+
+ case OO_Equal:
+ BinaryOp = BinaryOperator::Assign;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Less:
+ BinaryOp = BinaryOperator::LT;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Greater:
+ BinaryOp = BinaryOperator::GT;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_PlusEqual:
+ BinaryOp = BinaryOperator::AddAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_MinusEqual:
+ BinaryOp = BinaryOperator::SubAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_StarEqual:
+ BinaryOp = BinaryOperator::MulAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_SlashEqual:
+ BinaryOp = BinaryOperator::DivAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_PercentEqual:
+ BinaryOp = BinaryOperator::RemAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_CaretEqual:
+ BinaryOp = BinaryOperator::XorAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_AmpEqual:
+ BinaryOp = BinaryOperator::AndAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_PipeEqual:
+ BinaryOp = BinaryOperator::OrAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_LessLess:
+ BinaryOp = BinaryOperator::Shl;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_GreaterGreater:
+ BinaryOp = BinaryOperator::Shr;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_LessLessEqual:
+ BinaryOp = BinaryOperator::ShlAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_GreaterGreaterEqual:
+ BinaryOp = BinaryOperator::ShrAssign;
+ return Stmt::CompoundAssignOperatorClass;
+
+ case OO_EqualEqual:
+ BinaryOp = BinaryOperator::EQ;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_ExclaimEqual:
+ BinaryOp = BinaryOperator::NE;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_LessEqual:
+ BinaryOp = BinaryOperator::LE;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_GreaterEqual:
+ BinaryOp = BinaryOperator::GE;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_AmpAmp:
+ BinaryOp = BinaryOperator::LAnd;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_PipePipe:
+ BinaryOp = BinaryOperator::LOr;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_PlusPlus:
+ UnaryOp = S->getNumArgs() == 1? UnaryOperator::PreInc
+ : UnaryOperator::PostInc;
+ return Stmt::UnaryOperatorClass;
+
+ case OO_MinusMinus:
+ UnaryOp = S->getNumArgs() == 1? UnaryOperator::PreDec
+ : UnaryOperator::PostDec;
+ return Stmt::UnaryOperatorClass;
+
+ case OO_Comma:
+ BinaryOp = BinaryOperator::Comma;
+ return Stmt::BinaryOperatorClass;
+
+
+ case OO_ArrowStar:
+ BinaryOp = BinaryOperator::PtrMemI;
+ return Stmt::BinaryOperatorClass;
+
+ case OO_Subscript:
+ return Stmt::ArraySubscriptExprClass;
+ }
+
+ llvm_unreachable("Invalid overloaded operator expression");
+}
+
+
void StmtProfiler::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
+ if (S->isTypeDependent()) {
+ // Type-dependent operator calls are profiled like their underlying
+ // syntactic operator.
+ UnaryOperator::Opcode UnaryOp;
+ BinaryOperator::Opcode BinaryOp;
+ Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
+
+ ID.AddInteger(SC);
+ for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+ Visit(S->getArg(I));
+ if (SC == Stmt::UnaryOperatorClass)
+ ID.AddInteger(UnaryOp);
+ else if (SC == Stmt::BinaryOperatorClass ||
+ SC == Stmt::CompoundAssignOperatorClass)
+ ID.AddInteger(BinaryOp);
+ else
+ assert(SC == Stmt::ArraySubscriptExprClass);
+
+ return;
+ }
+
VisitCallExpr(S);
ID.AddInteger(S->getOperator());
}
Modified: cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp?rev=104107&r1=104106&r2=104107&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-type-identity.cpp Tue May 18 23:13:23 2010
@@ -70,3 +70,19 @@
void f8(typename N::X2<U>::template apply<T> *);
void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
};
+
+namespace PR6851 {
+ template <bool v>
+ struct S;
+
+ struct N {
+ template <bool w>
+ S< S<w>::cond && 1 > foo();
+ };
+
+ struct Alien;
+ bool operator&&(const Alien&, const Alien&);
+
+ template <bool w>
+ S< S<w>::cond && 1 > N::foo() { }
+}
More information about the cfe-commits
mailing list