[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