]> granicus.if.org Git - clang/commitdiff
A few TemplateArgumentLoc clean-ups. Try to remember the Expr for a declaration.
authorJohn McCall <rjmccall@apple.com>
Thu, 29 Oct 2009 18:45:58 +0000 (18:45 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 29 Oct 2009 18:45:58 +0000 (18:45 +0000)
Provide an API for getting the SourceRange of a TAL and use it judiciously.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85520 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/TemplateBase.h
include/clang/AST/TypeLoc.h
lib/AST/TemplateBase.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/TreeTransform.h

index 912bbdfe0c1ed14d6ce2e5950ca02f707208cfac..19fd56ff52b14b90f3f9662f2192fc998577991a 100644 (file)
@@ -239,7 +239,10 @@ public:
 /// Location information for a TemplateArgument.
 struct TemplateArgumentLocInfo {
 private:
-  void *Union;
+  union {
+    Expr *Expression;
+    DeclaratorInfo *Declarator;
+  };
 
 #ifndef NDEBUG
   enum Kind {
@@ -251,39 +254,33 @@ private:
 
 public:
   TemplateArgumentLocInfo()
-    : Union()
 #ifndef NDEBUG
-      , Kind(K_None) 
+    : Kind(K_None) 
 #endif
     {}
   
   TemplateArgumentLocInfo(DeclaratorInfo *DInfo)
-    : Union(DInfo)
+    : Declarator(DInfo)
 #ifndef NDEBUG
       , Kind(K_DeclaratorInfo) 
 #endif
     {}
   
   TemplateArgumentLocInfo(Expr *E)
-    : Union(E)
+    : Expression(E)
 #ifndef NDEBUG
       , Kind(K_Expression) 
 #endif
     {}
 
-  /// \brief Returns whether this 
-  bool empty() const {
-    return Union == NULL;
-  }
-
   DeclaratorInfo *getAsDeclaratorInfo() const {
     assert(Kind == K_DeclaratorInfo);
-    return reinterpret_cast<DeclaratorInfo*>(Union);
+    return Declarator;
   }
 
   Expr *getAsExpr() const {
     assert(Kind == K_Expression);
-    return reinterpret_cast<Expr*>(Union);
+    return Expression;
   }
 
 #ifndef NDEBUG
@@ -293,9 +290,9 @@ public:
       assert(Kind == K_DeclaratorInfo);
       break;
     case TemplateArgument::Expression:
+    case TemplateArgument::Declaration:
       assert(Kind == K_Expression);
       break;
-    case TemplateArgument::Declaration:
     case TemplateArgument::Integral:
     case TemplateArgument::Pack:
       assert(Kind == K_None);
@@ -313,15 +310,14 @@ class TemplateArgumentLoc {
   TemplateArgument Argument;
   TemplateArgumentLocInfo LocInfo;
 
-  friend class TemplateSpecializationTypeLoc;
+public:
+  TemplateArgumentLoc() {}
+
   TemplateArgumentLoc(const TemplateArgument &Argument,
                       TemplateArgumentLocInfo Opaque)
     : Argument(Argument), LocInfo(Opaque) {
   }
 
-public:
-  TemplateArgumentLoc() {}
-
   TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo)
     : Argument(Argument), LocInfo(DInfo) {
     assert(Argument.getKind() == TemplateArgument::Type);
@@ -332,15 +328,13 @@ public:
     assert(Argument.getKind() == TemplateArgument::Expression);
   }
 
-  /// This is a temporary measure.
-  TemplateArgumentLoc(const TemplateArgument &Argument)
-    : Argument(Argument), LocInfo() {
-    assert(Argument.getKind() != TemplateArgument::Expression &&
-           Argument.getKind() != TemplateArgument::Type);
+  /// \brief - Fetches the start location of the argument.
+  SourceLocation getLocation() const {
+    return getSourceRange().getBegin();
   }
 
-  /// \brief - Fetches the start location of the argument, if possible.
-  SourceLocation getLocation() const;
+  /// \brief - Fetches the full source range of the argument.
+  SourceRange getSourceRange() const;
 
   const TemplateArgument &getArgument() const {
     return Argument;
@@ -352,13 +346,16 @@ public:
 
   DeclaratorInfo *getSourceDeclaratorInfo() const {
     assert(Argument.getKind() == TemplateArgument::Type);
-    if (LocInfo.empty()) return 0;
     return LocInfo.getAsDeclaratorInfo();
   }
 
   Expr *getSourceExpression() const {
     assert(Argument.getKind() == TemplateArgument::Expression);
-    if (LocInfo.empty()) return 0;
+    return LocInfo.getAsExpr();
+  }
+
+  Expr *getSourceDeclExpression() const {
+    assert(Argument.getKind() == TemplateArgument::Declaration);
     return LocInfo.getAsExpr();
   }
 };
index b4e3fc4179cb95911f3fa18b4078302a24dc3b7b..b544bc37e8617fa2d55974b4ec265163c0eb2a04 100644 (file)
@@ -900,8 +900,30 @@ public:
     setRAngleLoc(Loc);
     setTemplateNameLoc(Loc);
 
-    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
-      getArgInfos()[i] = TemplateArgumentLocInfo();
+    for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
+      TemplateArgumentLocInfo Info;
+#ifndef NDEBUG
+      // If asserts are enabled, be sure to initialize the argument
+      // loc with the right kind of pointer.
+      switch (getTypePtr()->getArg(i).getKind()) {
+      case TemplateArgument::Expression:
+      case TemplateArgument::Declaration:
+        Info = TemplateArgumentLocInfo((Expr*) 0);
+        break;
+
+      case TemplateArgument::Type:
+        Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
+        break;
+
+      case TemplateArgument::Integral:
+      case TemplateArgument::Pack:
+      case TemplateArgument::Null:
+        // K_None is fine.
+        break;
+      }
+#endif
+      getArgInfos()[i] = Info;
+    }
   }
 
   unsigned getExtraLocalDataSize() const {
index b136fe0d3823a3d589e29b6f9b225cb1c09816c4..94e1ca1e06e78fe18e21b00c56038c6457a8f9d4 100644 (file)
@@ -78,20 +78,20 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
 // TemplateArgumentLoc Implementation
 //===----------------------------------------------------------------------===//
 
-SourceLocation TemplateArgumentLoc::getLocation() const {
+SourceRange TemplateArgumentLoc::getSourceRange() const {
   switch (Argument.getKind()) {
   case TemplateArgument::Expression:
-    return getSourceExpression()->getExprLoc();
-  case TemplateArgument::Type:
-    return getSourceDeclaratorInfo()->
-      getTypeLoc().getFullSourceRange().getBegin();
+    return getSourceExpression()->getSourceRange();
   case TemplateArgument::Declaration:
+    return getSourceDeclExpression()->getSourceRange();
+  case TemplateArgument::Type:
+    return getSourceDeclaratorInfo()->getTypeLoc().getFullSourceRange();
   case TemplateArgument::Integral:
   case TemplateArgument::Pack:
   case TemplateArgument::Null:
-    return SourceLocation();
+    return SourceRange();
   }
 
   // Silence bonus gcc warning.
-  return SourceLocation();
+  return SourceRange();
 }
index a2883fa9804f9cc45352203354efe5ddce9e82bc..fb5eef276058cd9e7b2b8134e63d99aab39f73d2 100644 (file)
@@ -1425,7 +1425,8 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
 
     // We have a template type parameter but the template argument
     // is not a type.
-    Diag(AL.getLocation(), diag::err_template_arg_must_be_type);
+    SourceRange SR = AL.getSourceRange();
+    Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR;
     Diag(Param->getLocation(), diag::note_template_param_here);
 
     return true;
@@ -1558,8 +1559,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
           break;
 
         // FIXME: Subst default argument
-        // FIXME: preserve source information
-        Arg = TemplateArgumentLoc(TemplateArgument(TempParm->getDefaultArgument()));
+        Arg = TemplateArgumentLoc(TemplateArgument(TempParm->getDefaultArgument()),
+                                  TempParm->getDefaultArgument());
       }
     } else {
       // Retrieve the template argument produced by the user.
@@ -1646,11 +1647,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
         // We warn specifically about this case, since it can be rather
         // confusing for users.
         QualType T = Arg.getArgument().getAsType();
+        SourceRange SR = Arg.getSourceRange();
         if (T->isFunctionType())
-          Diag(Arg.getLocation(), diag::err_template_arg_nontype_ambig)
-            << T;
+          Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig)
+            << SR << T;
         else
-          Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr);
+          Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR;
         Diag((*Param)->getLocation(), diag::note_template_param_here);
         Invalid = true;
         break;
index cb7b69fc95d2d338581a1f0668eef0c0dabb405f..04bec726c01622a885f65032b3259f296b959e92 100644 (file)
@@ -1919,7 +1919,7 @@ void TreeTransform<Derived>::InventTemplateArgumentLoc(
   case TemplateArgument::Declaration:
   case TemplateArgument::Integral:
   case TemplateArgument::Pack:
-    Output = TemplateArgumentLoc(Arg);
+    Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
     break;
   }
 }
@@ -1956,7 +1956,20 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
     Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
     if (!D) return true;
 
-    Output = TemplateArgumentLoc(TemplateArgument(D));
+    Expr *SourceExpr = Input.getSourceDeclExpression();
+    if (SourceExpr) {
+      EnterExpressionEvaluationContext Unevaluated(getSema(),
+                                                   Action::Unevaluated);
+      Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
+      if (E.isInvalid())
+        SourceExpr = NULL;
+      else {
+        SourceExpr = E.takeAs<Expr>();
+        SourceExpr->Retain();
+      }
+    }
+
+    Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
     return false;
   }
 
@@ -1973,6 +1986,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
     if (E.isInvalid()) return true;
 
     Expr *ETaken = E.takeAs<Expr>();
+    ETaken->Retain();
     Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
     return false;
   }
@@ -1987,18 +2001,18 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
       // FIXME: preserve source information here when we start
       // caring about parameter packs.
 
-      TemplateArgumentLoc Input;
-      TemplateArgumentLoc Output;
-      getDerived().InventTemplateArgumentLoc(*A, Input);
-      if (getDerived().TransformTemplateArgument(Input, Output))
+      TemplateArgumentLoc InputArg;
+      TemplateArgumentLoc OutputArg;
+      getDerived().InventTemplateArgumentLoc(*A, InputArg);
+      if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
         return true;
 
-      TransformedArgs.push_back(Output.getArgument());
+      TransformedArgs.push_back(OutputArg.getArgument());
     }
     TemplateArgument Result;
     Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
                            true);
-    Output = TemplateArgumentLoc(Result);
+    Output = TemplateArgumentLoc(Result, Input.getLocInfo());
     return false;
   }
   }
@@ -2764,9 +2778,11 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
   TemplateSpecializationTypeLoc TL
     = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
 
-  TL.setTemplateNameLoc(getDerived().getBaseLocation());
-  TL.setLAngleLoc(SourceLocation());
-  TL.setRAngleLoc(SourceLocation());
+  SourceLocation BaseLoc = getDerived().getBaseLocation();
+
+  TL.setTemplateNameLoc(BaseLoc);
+  TL.setLAngleLoc(BaseLoc);
+  TL.setRAngleLoc(BaseLoc);
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
     const TemplateArgument &TA = TST->getArg(i);
     TemplateArgumentLoc TAL;