[cfe-commits] r66835 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/instantiate-expr-1.cpp

Douglas Gregor dgregor at apple.com
Thu Mar 12 15:46:12 PDT 2009


Author: dgregor
Date: Thu Mar 12 17:46:12 2009
New Revision: 66835

URL: http://llvm.org/viewvc/llvm-project?rev=66835&view=rev
Log:
Implement template instantiation for builtin binary operators

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=66835&r1=66834&r2=66835&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Thu Mar 12 17:46:12 2009
@@ -770,7 +770,7 @@
 DIAG(err_implicit_empty_initializer, ERROR,
      "initializer for aggregate with no elements requires explicit braces")
 DIAG(err_bitfield_has_negative_width, ERROR,
-     "bit-field %0 has negative width")
+     "bit-field %0 has negative width (%1)")
 DIAG(err_bitfield_has_zero_width, ERROR,
      "bit-field %0 has zero width")
 DIAG(err_bitfield_width_exceeds_type_size, ERROR,

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=66835&r1=66834&r2=66835&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Mar 12 17:46:12 2009
@@ -2121,33 +2121,33 @@
   /// or a null QualType (indicating an error diagnostic was issued).
 
   /// type checking binary operators (subroutines of CreateBuiltinBinOp).
-  inline QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
   QualType CheckPointerToMemberOperands( // C++ 5.5
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect);
-  inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
+  QualType CheckMultiplyDivideOperands( // C99 6.5.5
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  inline QualType CheckRemainderOperands( // C99 6.5.5
+  QualType CheckRemainderOperands( // C99 6.5.5
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  inline QualType CheckAdditionOperands( // C99 6.5.6
+  QualType CheckAdditionOperands( // C99 6.5.6
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  inline QualType CheckSubtractionOperands( // C99 6.5.6
+  QualType CheckSubtractionOperands( // C99 6.5.6
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  inline QualType CheckShiftOperands( // C99 6.5.7
+  QualType CheckShiftOperands( // C99 6.5.7
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  inline QualType CheckCompareOperands( // C99 6.5.8/9
+  QualType CheckCompareOperands( // C99 6.5.8/9
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isRelational);
-  inline QualType CheckBitwiseOperands( // C99 6.5.[10...12]
+  QualType CheckBitwiseOperands( // C99 6.5.[10...12]
     Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  inline QualType CheckLogicalOperands( // C99 6.5.[13,14]
+  QualType CheckLogicalOperands( // C99 6.5.[13,14]
     Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   // CheckAssignmentOperands is used for both simple and compound assignment.
   // For simple assignment, pass both expressions and a null converted type.
   // For compound assignment, pass both expressions and the converted type.
-  inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
+  QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
     Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
-  inline QualType CheckCommaOperands( // C99 6.5.17
+  QualType CheckCommaOperands( // C99 6.5.17
     Expr *lex, Expr *&rex, SourceLocation OpLoc);
-  inline QualType CheckConditionalOperands( // C99 6.5.15
+  QualType CheckConditionalOperands( // C99 6.5.15
     Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
 
   /// type checking for vector binary operators.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=66835&r1=66834&r2=66835&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 12 17:46:12 2009
@@ -3379,7 +3379,8 @@
     return Diag(FieldLoc, diag::err_bitfield_has_zero_width) << FieldName;
   
   if (Value.isNegative())
-    return Diag(FieldLoc, diag::err_bitfield_has_negative_width) << FieldName;
+    return Diag(FieldLoc, diag::err_bitfield_has_negative_width) 
+             << FieldName << Value.toString(10);
 
   if (!FieldTy->isDependentType()) {
     uint64_t TypeSize = Context.getTypeSize(FieldTy);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=66835&r1=66834&r2=66835&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Mar 12 17:46:12 2009
@@ -576,9 +576,13 @@
     Sema::OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
     Sema::OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
     Sema::OwningExprResult VisitParenExpr(ParenExpr *E);
+    Sema::OwningExprResult VisitBinaryOperator(BinaryOperator *E);
 
     // Base case. I'm supposed to ignore this.
-    Sema::OwningExprResult VisitStmt(Stmt *) { return SemaRef.ExprError(); }
+    Sema::OwningExprResult VisitStmt(Stmt *) { 
+      assert(false && "Cannot instantiate this kind of expression");
+      return SemaRef.ExprError(); 
+    }
   };
 }
 
@@ -619,6 +623,29 @@
 }
 
 Sema::OwningExprResult 
+TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
+  Sema::OwningExprResult LHS = Visit(E->getLHS());
+  if (LHS.isInvalid())
+    return SemaRef.ExprError();
+
+  Sema::OwningExprResult RHS = Visit(E->getRHS());
+  if (RHS.isInvalid())
+    return SemaRef.ExprError();
+
+  Sema::OwningExprResult Result
+    = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), 
+                                 E->getOpcode(),
+                                 (Expr *)LHS.get(),
+                                 (Expr *)RHS.get());
+  if (Result.isInvalid())
+    return SemaRef.ExprError();
+
+  LHS.release();
+  RHS.release();
+  return move(Result);
+}
+
+Sema::OwningExprResult 
 Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
                       unsigned NumTemplateArgs) {
   TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);

Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp?rev=66835&r1=66834&r2=66835&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp Thu Mar 12 17:46:12 2009
@@ -10,3 +10,36 @@
   (void)sizeof(Bitfields<10, 5>);
   (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'struct Bitfields<0, 1>' requested here}}
 }
+
+template<int I, int J>
+struct BitfieldPlus {
+  int bitfield : I + J; // expected-error{{bit-field 'bitfield' has zero width}}
+};
+
+void test_BitfieldPlus() {
+  (void)sizeof(BitfieldPlus<0, 1>);
+  (void)sizeof(BitfieldPlus<-5, 5>); // expected-note{{in instantiation of template class 'struct BitfieldPlus<-5, 5>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldMinus {
+  int bitfield : I - J; // expected-error{{bit-field 'bitfield' has negative width (-1)}} \
+  // expected-error{{bit-field 'bitfield' has zero width}}
+};
+
+void test_BitfieldMinus() {
+  (void)sizeof(BitfieldMinus<5, 1>);
+  (void)sizeof(BitfieldMinus<0, 1>); // expected-note{{in instantiation of template class 'struct BitfieldMinus<0, 1>' requested here}}
+  (void)sizeof(BitfieldMinus<5, 5>); // expected-note{{in instantiation of template class 'struct BitfieldMinus<5, 5>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldDivide {
+  int bitfield : I / J; // expected-error{{expression is not an integer constant expression}} \
+                        // expected-note{{division by zero}}
+};
+
+void test_BitfieldDivide() {
+  (void)sizeof(BitfieldDivide<5, 1>);
+  (void)sizeof(BitfieldDivide<5, 0>); // expected-note{{in instantiation of template class 'struct BitfieldDivide<5, 0>' requested here}}
+}





More information about the cfe-commits mailing list