]> granicus.if.org Git - clang/commitdiff
Store the type of the integral value within a TemplateArgument, so that we can more...
authorDouglas Gregor <dgregor@apple.com>
Thu, 12 Mar 2009 22:20:26 +0000 (22:20 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 12 Mar 2009 22:20:26 +0000 (22:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66833 91177308-0d34-0410-b5e6-96231b3b80d8

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

index cc309b4ea5fe94f08c5c83293f312e2fa0d61b94..17e5ad0b67563a9fb4856f6d50bc833ac488693b 100644 (file)
@@ -406,7 +406,10 @@ protected:
 class TemplateArgument {
   union {
     uintptr_t TypeOrValue;
-    char IntegralValue[sizeof(llvm::APInt)];
+    struct {
+      char Value[sizeof(llvm::APInt)];
+      void *Type;
+    } Integer;
   };
 
   /// \brief Location of the beginning of this template argument.
@@ -446,9 +449,11 @@ public:
   }
 
   /// \brief Construct an integral constant template argument.
-  TemplateArgument(SourceLocation Loc, const llvm::APInt &Value)
+  TemplateArgument(SourceLocation Loc, const llvm::APInt &Value,
+                   QualType Type)
     : Kind(Integral) {
-    new (IntegralValue) llvm::APInt(Value);
+    new (Integer.Value) llvm::APInt(Value);
+    Integer.Type = Type.getAsOpaquePtr();
     StartLoc = Loc;
   }
 
@@ -461,8 +466,10 @@ public:
 
   /// \brief Copy constructor for a template argument.
   TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
-    if (Kind == Integral)
-      new (IntegralValue) llvm::APInt(*Other.getAsIntegral());
+    if (Kind == Integral) {
+      new (Integer.Value) llvm::APInt(*Other.getAsIntegral());
+      Integer.Type = Other.Integer.Type;
+    }
     else
       TypeOrValue = Other.TypeOrValue;
     StartLoc = Other.StartLoc;
@@ -476,6 +483,7 @@ public:
     if (Kind == Other.Kind && Kind == Integral) {
       // Copy integral values.
       *this->getAsIntegral() = *Other.getAsIntegral();
+      Integer.Type = Other.Integer.Type; 
     } else {
       // Destroy the current integral value, if that's what we're holding.
       if (Kind == Integral)
@@ -483,9 +491,10 @@ public:
       
       Kind = Other.Kind;
       
-      if (Other.Kind == Integral)
-        new (IntegralValue) llvm::APInt(*Other.getAsIntegral());
-      else
+      if (Other.Kind == Integral) {
+        new (Integer.Value) llvm::APInt(*Other.getAsIntegral());
+        Integer.Type = Other.Integer.Type;
+      } else
         TypeOrValue = Other.TypeOrValue;
     }
     StartLoc = Other.StartLoc;
@@ -523,13 +532,21 @@ public:
   llvm::APInt *getAsIntegral() {
     if (Kind != Integral)
       return 0;
-    return reinterpret_cast<llvm::APInt*>(&IntegralValue[0]);
+    return reinterpret_cast<llvm::APInt*>(&Integer.Value[0]);
   }
 
   const llvm::APInt *getAsIntegral() const {
     return const_cast<TemplateArgument*>(this)->getAsIntegral();
   }
 
+  /// \brief Retrieve the type of the integral value.
+  QualType getIntegralType() const {
+    if (Kind != Integral)
+      return QualType();
+
+    return QualType::getFromOpaquePtr(Integer.Type);
+  }
+
   /// \brief Retrieve the template argument as an expression.
   Expr *getAsExpr() const {
     if (Kind != Expression)
@@ -555,6 +572,7 @@ public:
 
     case Integral:
       getAsIntegral()->Profile(ID);
+      getIntegralType().Profile(ID);
       break;
 
     case Expression:
index ea91a3836a5e63f471e1a89fcfffaa1b10a4ea7b..6fc4515571773fd4b1871b6068b6805ba29dbc31 100644 (file)
@@ -1280,7 +1280,8 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
                                IntegerType->isSignedIntegerType());
       CanonicalArg = Value;
 
-      Converted->push_back(TemplateArgument(StartLoc, CanonicalArg));
+      Converted->push_back(TemplateArgument(StartLoc, CanonicalArg,
+                                   Context.getCanonicalType(IntegerType)));
     }
 
     return false;
index 6ed4d9fb445094d5632897ac7d39239c14338d5c..6252e29e56824d5f1898ab80255b0b46600d51bf 100644 (file)
@@ -595,19 +595,11 @@ TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
   Decl *D = E->getDecl();
   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
     assert(NTTP->getDepth() == 0 && "No nested templates yet");
-    QualType T = NTTP->getType();
-    if (T->isDependentType()) {
-      // FIXME: We'll be doing this instantiation a lot. Should we
-      // cache this information in the TemplateArgument itself?
-      T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
-                                  E->getSourceRange().getBegin(),
-                                  NTTP->getDeclName());
-      if (T.isNull())
-        return SemaRef.ExprError();
-    }
+    const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()]; 
     return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
-                           *TemplateArgs[NTTP->getPosition()].getAsIntegral(),
-                            T, E->getSourceRange().getBegin()));
+                                                 *Arg.getAsIntegral(),
+                                                 Arg.getIntegralType(), 
+                                       E->getSourceRange().getBegin()));
   } else
     assert(false && "Can't handle arbitrary declaration references");