On Mon, Oct 24, 2011 at 7:30 AM, Douglas Gregor <[email protected]> wrote:

>
> On Oct 20, 2011, at 5:36 PM, Chandler Carruth wrote:
>
> On Thu, Oct 20, 2011 at 5:12 PM, Richard Trieu <[email protected]> wrote:
>
>> Should Clang be printing suffixes that are accepted only with certain
>> flags?
>>
>
> I think this is an interesting policy decision. I'd love to hear Doug's
> thoughts on it.
>
> It seems fine to me for Clang, when running with -fms-extensions, to
> suggest fixes even if only valid for -fms-extensions. Clearly if there is a
> generic suggestion that could be made, that would be a preferred
> alternative. For example, '__asm__' should be suggested before 'asm'.
>
>
> I think it's fine for Clang to print suffixes that are only accepted with
> certain flags. Presumably, you should never get an IntegerLiteral of type
> __int128_t unless you're in a dialect that supports parsing it.
>
> … except that we cheat when we're building template arguments, because it
> was convenient. That cheating could be eliminated by encoding integer
> literal values directly within SubstNonTypeTemplateParmExpr.
>
> - Doug
>
>
New patch.  Changes as follows:
Add int128 and uint128 suffixes (i128 and Ui128) to StmtPrinter.  short and
unsigned short will get to llvm_unreachable
Add assert to IntergerLiteral to prevent creation with type short or
unsigned short
Fix comment in IntegerLiteral to say that int128 and uint128 are acceptable
types
Change BuildExpressFromIntegralTemplateArgument to give a proper Expr.  For
negative numbers, use UnaryOperator of IntegerLiteral.  For short and
unsigned short, ImplicitCastExpr from int.

Basically, protect IntegerLiteral being shorts, fix the only case of short
IntegerLiterals, and add support for printing int128 IntegerLiterals.

PR:
http://llvm.org/bugs/show_bug.cgi?id=11179

Patch also located at:
http://codereview.appspot.com/5309045/
Index: test/Misc/integer-literal-printing.cpp
===================================================================
--- test/Misc/integer-literal-printing.cpp	(revision 0)
+++ test/Misc/integer-literal-printing.cpp	(revision 0)
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// PR11179
+template <short T> class Type1 {};
+template <short T> void Function1(Type1<T>& x) {} // expected-note{{candidate function [with T = -42] not viable: no known conversion from 'Type1<-42>' to 'Type1<-42> &' for 1st argument;}}
+
+template <unsigned short T> class Type2 {};
+template <unsigned short T> void Function2(Type2<T>& x) {} // expected-note{{candidate function [with T = 42] not viable: no known conversion from 'Type2<42>' to 'Type2<42> &' for 1st argument;}}
+
+template <__int128_t T> class Type3 {};
+template <__int128_t T> void Function3(Type3<T>& x) {} // expected-note{{candidate function [with T = -42] not viable: no known conversion from 'Type3<-42>' to 'Type3<-42i128> &' for 1st argument;}}
+
+template <__uint128_t T> class Type4 {};
+template <__uint128_t T> void Function4(Type4<T>& x) {} // expected-note{{candidate function [with T = 42] not viable: no known conversion from 'Type4<42>' to 'Type4<42Ui128> &' for 1st argument;}}
+
+void Function() {
+  Function1(Type1<-42>()); // expected-error{{no matching function for call to 'Function1'}}
+  Function2(Type2<42>()); // expected-error{{no matching function for call to 'Function2'}}
+  Function3(Type3<-42>()); // expected-error{{no matching function for call to 'Function3'}}
+  Function4(Type4<42>()); // expected-error{{no matching function for call to 'Function4'}}
+}
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h	(revision 142606)
+++ include/clang/AST/Expr.h	(working copy)
@@ -1072,8 +1072,8 @@
     : Expr(IntegerLiteralClass, Empty) { }
 
 public:
-  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
-  // or UnsignedLongLongTy
+  // type should be IntTy, LongTy, LongLongTy, Int128Ty, UnsignedIntTy,
+  // UnsignedLongTy, UnsignedLongLongTy, or UnsignedInt128Ty.
   IntegerLiteral(ASTContext &C, const llvm::APInt &V,
                  QualType type, SourceLocation l)
     : Expr(IntegerLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
@@ -1082,6 +1082,9 @@
     assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
     assert(V.getBitWidth() == C.getIntWidth(type) &&
            "Integer type is not the correct size for constant.");
+    assert(!type->isSpecificBuiltinType(BuiltinType::Short) &&
+           !type->isSpecificBuiltinType(BuiltinType::UShort) &&
+           "Interger type cannot be short or unsigned short");
     setValue(C, V);
   }
 
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp	(revision 142606)
+++ lib/Sema/SemaTemplate.cpp	(working copy)
@@ -4199,7 +4199,18 @@
 
   if (T->isNullPtrType())
     return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
-  
+
+  llvm::APInt Value = *Arg.getAsIntegral();
+  bool IsNegative = Value.isNegative();
+  if (IsNegative)
+    Value = Value.abs();
+  bool IsShort = T->isSpecificBuiltinType(BuiltinType::Short);
+  bool IsUShort = T->isSpecificBuiltinType(BuiltinType::UShort);
+  if (IsShort || IsUShort) {
+    T = Context.IntTy;
+    Value = Value.zext(Context.getIntWidth(T));
+  }
+ 
   // If this is an enum type that we're instantiating, we need to use an integer
   // type the same size as the enumerator.  We don't want to build an
   // IntegerLiteral with enum type.
@@ -4209,7 +4220,17 @@
   else
     BT = T;
 
-  Expr *E = IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc);
+  Expr *E = IntegerLiteral::Create(Context, Value, BT, Loc);
+  if (IsNegative)
+    E = new (Context) UnaryOperator(E, UO_Minus, T, VK_RValue, OK_Ordinary,
+                                    Loc);
+
+  if (IsShort || IsUShort) {
+    E = ImplicitCastExpr::Create(Context, IsShort ? Context.ShortTy
+                                                  : Context.UnsignedShortTy,
+                                 CK_IntegralCast, E, 0, VK_RValue);
+  }
+
   if (T->isEnumeralType()) {
     // FIXME: This is a hack. We need a better way to handle substituted
     // non-type template parameters.
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp	(revision 142606)
+++ lib/AST/StmtPrinter.cpp	(working copy)
@@ -665,6 +665,8 @@
   case BuiltinType::ULong:     OS << "UL"; break;
   case BuiltinType::LongLong:  OS << "LL"; break;
   case BuiltinType::ULongLong: OS << "ULL"; break;
+  case BuiltinType::Int128:    OS << "i128"; break;
+  case BuiltinType::UInt128:   OS << "Ui128"; break;
   }
 }
 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to