]> granicus.if.org Git - clang/commitdiff
Make sure that the canonical representation of integral template arguments uses the...
authorDouglas Gregor <dgregor@apple.com>
Sat, 14 Mar 2009 00:03:48 +0000 (00:03 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 14 Mar 2009 00:03:48 +0000 (00:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66990 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclTemplate.h
lib/Sema/SemaTemplate.cpp

index 17e5ad0b67563a9fb4856f6d50bc833ac488693b..68d93ccc7fe628d8f13aa75dfcc4ea7fd2b9a41b 100644 (file)
@@ -15,7 +15,7 @@
 #define LLVM_CLANG_AST_DECLTEMPLATE_H
 
 #include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/FoldingSet.h"
 
 namespace clang {
@@ -407,7 +407,7 @@ class TemplateArgument {
   union {
     uintptr_t TypeOrValue;
     struct {
-      char Value[sizeof(llvm::APInt)];
+      char Value[sizeof(llvm::APSInt)];
       void *Type;
     } Integer;
   };
@@ -423,7 +423,7 @@ public:
     Type = 0,
     /// The template argument is a declaration
     Declaration = 1,
-    /// The template argument is an integral value stored in an llvm::APInt.
+    /// The template argument is an integral value stored in an llvm::APSInt.
     Integral = 2,
     /// The template argument is a value- or type-dependent expression
     /// stored in an Expr*.
@@ -449,10 +449,10 @@ public:
   }
 
   /// \brief Construct an integral constant template argument.
-  TemplateArgument(SourceLocation Loc, const llvm::APInt &Value,
+  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
                    QualType Type)
     : Kind(Integral) {
-    new (Integer.Value) llvm::APInt(Value);
+    new (Integer.Value) llvm::APSInt(Value);
     Integer.Type = Type.getAsOpaquePtr();
     StartLoc = Loc;
   }
@@ -467,7 +467,7 @@ public:
   /// \brief Copy constructor for a template argument.
   TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
     if (Kind == Integral) {
-      new (Integer.Value) llvm::APInt(*Other.getAsIntegral());
+      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
       Integer.Type = Other.Integer.Type;
     }
     else
@@ -478,7 +478,7 @@ public:
   TemplateArgument& operator=(const TemplateArgument& Other) {
     // FIXME: Does not provide the strong guarantee for exception
     // safety.
-    using llvm::APInt;
+    using llvm::APSInt;
 
     if (Kind == Other.Kind && Kind == Integral) {
       // Copy integral values.
@@ -487,12 +487,12 @@ public:
     } else {
       // Destroy the current integral value, if that's what we're holding.
       if (Kind == Integral)
-        getAsIntegral()->~APInt();
+        getAsIntegral()->~APSInt();
       
       Kind = Other.Kind;
       
       if (Other.Kind == Integral) {
-        new (Integer.Value) llvm::APInt(*Other.getAsIntegral());
+        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
         Integer.Type = Other.Integer.Type;
       } else
         TypeOrValue = Other.TypeOrValue;
@@ -503,10 +503,10 @@ public:
   }
 
   ~TemplateArgument() {
-    using llvm::APInt;
+    using llvm::APSInt;
 
     if (Kind == Integral)
-      getAsIntegral()->~APInt();
+      getAsIntegral()->~APSInt();
   }
 
   /// \brief Return the kind of stored template argument.
@@ -529,13 +529,13 @@ public:
   }
 
   /// \brief Retrieve the template argument as an integral value.
-  llvm::APInt *getAsIntegral() {
+  llvm::APSInt *getAsIntegral() {
     if (Kind != Integral)
       return 0;
-    return reinterpret_cast<llvm::APInt*>(&Integer.Value[0]);
+    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
   }
 
-  const llvm::APInt *getAsIntegral() const {
+  const llvm::APSInt *getAsIntegral() const {
     return const_cast<TemplateArgument*>(this)->getAsIntegral();
   }
 
index 3780259d43b02b7dadc35692780f1012ab5274a3..142cc453f363579efdab92ce3c4e6549e612e07e 100644 (file)
@@ -1283,11 +1283,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
         return false;
       } 
 
-      llvm::APInt CanonicalArg(Context.getTypeSize(IntegerType), 0, 
-                               IntegerType->isSignedIntegerType());
-      CanonicalArg = Value;
+      unsigned ExpectedBits = Context.getTypeSize(IntegerType);
+      if (Value.getBitWidth() != ExpectedBits)
+        Value.extOrTrunc(ExpectedBits);
+      Value.setIsSigned(IntegerType->isSignedIntegerType());
 
-      Converted->push_back(TemplateArgument(StartLoc, CanonicalArg,
+      Converted->push_back(TemplateArgument(StartLoc, Value,
                                    Context.getCanonicalType(IntegerType)));
     }