[cfe-commits] r74563 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/AST/StmtNodes.def include/clang/Parse/Action.h lib/AST/ExprCXX.cpp lib/AST/StmtPrinter.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp

Douglas Gregor dgregor at apple.com
Tue Jun 30 15:34:41 PDT 2009


Author: dgregor
Date: Tue Jun 30 17:34:41 2009
New Revision: 74563

URL: http://llvm.org/viewvc/llvm-project?rev=74563&view=rev
Log:
Preliminary parsing and ASTs for template-ids that refer to function
templates, such as make<int&>. These template-ids are only barely
functional for function calls; much more to come.


Added:
    cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp
Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Jun 30 17:34:41 2009
@@ -1017,6 +1017,100 @@
   virtual StmtIterator child_end();
 };
 
+/// \brief An expression that refers to a C++ template-id, such as 
+/// @c isa<FunctionDecl>. 
+class TemplateIdRefExpr : public Expr {
+  /// \brief If this template-id was qualified-id, e.g., @c std::sort<int>,
+  /// this nested name specifier contains the @c std::.
+  NestedNameSpecifier *Qualifier;
+  
+  /// \brief If this template-id was a qualified-id, e.g., @c std::sort<int>,
+  /// this covers the source code range of the @c std::.
+  SourceRange QualifierRange;
+  
+  /// \brief The actual template to which this template-id refers.
+  TemplateName Template;
+  
+  /// \brief The source location of the template name.
+  SourceLocation TemplateNameLoc;
+
+  /// \brief The source location of the left angle bracket ('<');
+  SourceLocation LAngleLoc;
+  
+  /// \brief The source location of the right angle bracket ('>');
+  SourceLocation RAngleLoc;
+  
+  /// \brief The number of template arguments in TemplateArgs.
+  unsigned NumTemplateArgs;
+  
+  TemplateIdRefExpr(QualType T,
+                    NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+                    TemplateName Template, SourceLocation TemplateNameLoc,
+                    SourceLocation LAngleLoc, 
+                    const TemplateArgument *TemplateArgs,
+                    unsigned NumTemplateArgs,
+                    SourceLocation RAngleLoc);
+  
+public:
+  static TemplateIdRefExpr *
+  Create(ASTContext &Context, QualType T,
+         NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
+         TemplateName Template, SourceLocation TemplateNameLoc,
+         SourceLocation LAngleLoc, const TemplateArgument *TemplateArgs,
+         unsigned NumTemplateArgs, SourceLocation RAngleLoc);
+  
+  void Destroy(ASTContext &Context);
+  
+  /// \brief Retrieve the nested name specifier used to qualify the name of
+  /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL
+  /// if this template-id was an unqualified-id.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+  
+  /// \brief Retrieve the source range describing the nested name specifier
+  /// used to qualified the name of this template-id, if the name was qualified.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+  
+  /// \brief Retrieve the name of the template referenced, e.g., "sort" in
+  /// @c std::sort<int>;
+  TemplateName getTemplateName() const { return Template; }
+  
+  /// \brief Retrieve the location of the name of the template referenced, e.g.,
+  /// the location of "sort" in @c std::sort<int>.
+  SourceLocation getTemplateNameLoc() const { return TemplateNameLoc; }
+  
+  /// \brief Retrieve the location of the left angle bracket following the 
+  /// template name ('<').
+  SourceLocation getLAngleLoc() const { return LAngleLoc; }
+  
+  /// \brief Retrieve the template arguments provided as part of this
+  /// template-id.
+  const TemplateArgument *getTemplateArgs() const { 
+    return reinterpret_cast<const TemplateArgument *>(this + 1);
+  }
+  
+  /// \brief Retrieve the number of template arguments provided as part of this
+  /// template-id.
+  unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
+    
+  /// \brief Retrieve the location of the right angle bracket following the 
+  /// template arguments ('>').
+  SourceLocation getRAngleLoc() const { return RAngleLoc; }
+  
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(Qualifier? QualifierRange.getBegin() : TemplateNameLoc,
+                       RAngleLoc);
+  }
+  
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+  
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == TemplateIdRefExprClass;
+  }
+  static bool classof(const TemplateIdRefExpr *) { return true; }
+};
+  
 class CXXExprWithTemporaries : public Expr {
   Stmt *SubExpr;
     

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Tue Jun 30 17:34:41 2009
@@ -9,7 +9,7 @@
 //
 //  This file defines the AST Node info database.
 //
-//===----------------------------------------------------------------------===//
+//===---------------------------------------------------------------------===//
 
 #ifndef FIRST_STMT
 #define FIRST_STMT(CLASS)
@@ -123,6 +123,7 @@
 EXPR(UnaryTypeTraitExpr     , Expr)
 EXPR(QualifiedDeclRefExpr   , DeclRefExpr)
 EXPR(UnresolvedDeclRefExpr  , Expr)
+EXPR(TemplateIdRefExpr      , Expr)
 EXPR(CXXConstructExpr       , Expr)
 EXPR(CXXBindTemporaryExpr   , Expr)
 EXPR(CXXExprWithTemporaries , Expr)

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jun 30 17:34:41 2009
@@ -1379,6 +1379,24 @@
     return TypeResult();
   };
 
+  /// \brief Form a reference to a template-id (that will refer to a function)
+  /// from a template and a list of template arguments.
+  ///
+  /// This action forms an expression that references the given template-id,
+  /// possibly checking well-formedness of the template arguments. It does not
+  /// imply the declaration of any entity.
+  ///
+  /// \param Template  A template whose specialization results in a
+  /// function or a dependent template.
+  virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+                                               SourceLocation TemplateNameLoc,
+                                               SourceLocation LAngleLoc,
+                                               ASTTemplateArgsPtr TemplateArgs,
+                                               SourceLocation *TemplateArgLocs,
+                                               SourceLocation RAngleLoc) {
+    return ExprError();
+  }
+  
   /// \brief Form a dependent template name.
   ///
   /// This action forms a dependent template name given the template

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Jun 30 17:34:41 2009
@@ -13,6 +13,7 @@
 
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 using namespace clang;
 
@@ -153,6 +154,65 @@
   return child_iterator();
 }
 
+TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
+                                     NestedNameSpecifier *Qualifier, 
+                                     SourceRange QualifierRange,
+                                     TemplateName Template, 
+                                     SourceLocation TemplateNameLoc,
+                                     SourceLocation LAngleLoc, 
+                                     const TemplateArgument *TemplateArgs,
+                                     unsigned NumTemplateArgs,
+                                     SourceLocation RAngleLoc)
+  : Expr(TemplateIdRefExprClass, T,
+         (Template.isDependent() || 
+          TemplateSpecializationType::anyDependentTemplateArguments(
+                                              TemplateArgs, NumTemplateArgs)),
+         (Template.isDependent() ||
+          TemplateSpecializationType::anyDependentTemplateArguments(
+                                              TemplateArgs, NumTemplateArgs))),
+    Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
+    TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
+    RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs)
+    
+{ 
+  TemplateArgument *StoredTemplateArgs 
+    = reinterpret_cast<TemplateArgument *> (this+1);
+  for (unsigned I = 0; I != NumTemplateArgs; ++I)
+    new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+}
+
+TemplateIdRefExpr *
+TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
+                          NestedNameSpecifier *Qualifier, 
+                          SourceRange QualifierRange,
+                          TemplateName Template, SourceLocation TemplateNameLoc,
+                          SourceLocation LAngleLoc, 
+                          const TemplateArgument *TemplateArgs,
+                          unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
+  void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
+                               sizeof(TemplateArgument) * NumTemplateArgs);
+  return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
+                                     TemplateNameLoc, LAngleLoc, TemplateArgs,
+                                     NumTemplateArgs, RAngleLoc);
+}
+
+void TemplateIdRefExpr::Destroy(ASTContext &Context) {
+  const TemplateArgument *TemplateArgs = getTemplateArgs();
+  for (unsigned I = 0; I != NumTemplateArgs; ++I)
+    if (Expr *E = TemplateArgs[I].getAsExpr())
+      E->Destroy(Context);
+}
+
+Stmt::child_iterator TemplateIdRefExpr::child_begin() {
+  // FIXME: Walk the expressions in the template arguments (?)
+  return Stmt::child_iterator();
+}
+
+Stmt::child_iterator TemplateIdRefExpr::child_end() {
+  // FIXME: Walk the expressions in the template arguments (?)
+  return Stmt::child_iterator();
+}
+
 bool UnaryTypeTraitExpr::EvaluateTrait() const {
   switch(UTT) {
   default: assert(false && "Unknown type trait or not implemented");

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Jun 30 17:34:41 2009
@@ -490,6 +490,18 @@
   OS << Node->getDeclName().getAsString();
 }
 
+void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
+  if (Node->getQualifier())
+    Node->getQualifier()->print(OS, Policy);
+  Node->getTemplateName().print(OS, Policy, true);
+  OS << '<';
+  OS << TemplateSpecializationType::PrintTemplateArgumentList(
+                                                      Node->getTemplateArgs(),
+                                                   Node->getNumTemplateArgs(),
+                                                              Policy);
+  OS << '>';
+}
+
 void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
   if (Node->getBase()) {
     PrintExpr(Node->getBase());

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Jun 30 17:34:41 2009
@@ -777,7 +777,7 @@
 
   case tok::annot_cxxscope: // [C++] id-expression: qualified-id
   case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
-                         //                      template-id
+  case tok::annot_template_id: // [C++]          template-id
     Res = ParseCXXIdExpression(isAddressOfOperand);
     return ParsePostfixExpressionSuffix(move(Res));
 

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=74563&r1=74562&r2=74563&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Jun 30 17:34:41 2009
@@ -207,13 +207,13 @@
 ///         operator-function-id
 ///         conversion-function-id                [TODO]
 ///         '~' class-name                        [TODO]
-///         template-id                           [TODO]
+///         template-id
 ///
 ///       qualified-id:
 ///         '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
 ///         '::' identifier
 ///         '::' operator-function-id
-///         '::' template-id                      [TODO]
+///         '::' template-id
 ///
 ///       nested-name-specifier:
 ///         type-name '::'
@@ -264,7 +264,7 @@
   //   operator-function-id
   //   conversion-function-id
   //   '~' class-name                        [TODO]
-  //   template-id                           [TODO]
+  //   template-id
   //
   switch (Tok.getKind()) {
   default:
@@ -294,6 +294,29 @@
     return ExprError();
   }
 
+  case tok::annot_template_id: {
+    TemplateIdAnnotation *TemplateId 
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    assert((TemplateId->Kind == TNK_Function_template ||
+            TemplateId->Kind == TNK_Dependent_template_name) &&
+           "A template type name is not an ID expression");
+
+    ASTTemplateArgsPtr TemplateArgsPtr(Actions, 
+                                       TemplateId->getTemplateArgs(),
+                                       TemplateId->getTemplateArgIsType(),
+                                       TemplateId->NumArgs);
+    
+    OwningExprResult Result
+      = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template),
+                                    TemplateId->TemplateNameLoc,
+                                    TemplateId->LAngleLoc,
+                                    TemplateArgsPtr,
+                                    TemplateId->getTemplateArgLocations(),
+                                    TemplateId->RAngleLoc);
+    ConsumeToken(); // Consume the template-id token
+    return move(Result);
+  }
+
   } // switch.
 
   assert(0 && "The switch was supposed to take care everything.");

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jun 30 17:34:41 2009
@@ -2075,6 +2075,20 @@
                       SourceLocation *TemplateArgLocs,
                       SourceLocation RAngleLoc);
   
+  OwningExprResult BuildTemplateIdExpr(TemplateName Template,
+                                       SourceLocation TemplateNameLoc,
+                                       SourceLocation LAngleLoc,
+                                       const TemplateArgument *TemplateArgs,
+                                       unsigned NumTemplateArgs,
+                                       SourceLocation RAngleLoc);
+  
+  virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+                                               SourceLocation TemplateNameLoc,
+                                               SourceLocation LAngleLoc,
+                                               ASTTemplateArgsPtr TemplateArgs,
+                                               SourceLocation *TemplateArgLocs,
+                                               SourceLocation RAngleLoc);
+    
   virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
                                                 const IdentifierInfo &Name,
                                                 SourceLocation NameLoc,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 30 17:34:41 2009
@@ -2635,7 +2635,6 @@
   }
 
   // If we're directly calling a function, get the appropriate declaration.
-  DeclRefExpr *DRExpr = NULL;
   Expr *FnExpr = Fn;
   bool ADL = true;
   while (true) {
@@ -2650,14 +2649,19 @@
                cast<UnaryOperator>(FnExpr)->getOpcode()
                  == UnaryOperator::AddrOf) {
       FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
-    } else if ((DRExpr = dyn_cast<DeclRefExpr>(FnExpr))) {
+    } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
       // Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
       ADL &= !isa<QualifiedDeclRefExpr>(DRExpr);
+      NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
       break;
     } else if (UnresolvedFunctionNameExpr *DepName
                  = dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
       UnqualifiedName = DepName->getName();
       break;
+    } else if (TemplateIdRefExpr *TemplateIdRef 
+                 = dyn_cast<TemplateIdRefExpr>(FnExpr)) {
+      NDecl = TemplateIdRef->getTemplateName().getAsTemplateDecl();
+      break;
     } else {
       // Any kind of name that does not refer to a declaration (or
       // set of declarations) disables ADL (C++0x [basic.lookup.argdep]p3).
@@ -2668,14 +2672,13 @@
 
   OverloadedFunctionDecl *Ovl = 0;
   FunctionTemplateDecl *FunctionTemplate = 0;
-  if (DRExpr) {
-    FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
-    if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DRExpr->getDecl())))
+  if (NDecl) {
+    FDecl = dyn_cast<FunctionDecl>(NDecl);
+    if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl)))
       FDecl = FunctionTemplate->getTemplatedDecl();
     else
-      FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
-    Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
-    NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
+      FDecl = dyn_cast<FunctionDecl>(NDecl);
+    Ovl = dyn_cast<OverloadedFunctionDecl>(NDecl);
   }
 
   if (Ovl || FunctionTemplate || 
@@ -2689,16 +2692,15 @@
       ADL = false;
 
     if (Ovl || FunctionTemplate || ADL) {
-      FDecl = ResolveOverloadedCallFn(Fn, DRExpr? DRExpr->getDecl() : 0,
-                                      UnqualifiedName, LParenLoc, Args,
-                                      NumArgs, CommaLocs, RParenLoc, ADL);
+      FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName, LParenLoc, 
+                                      Args, NumArgs, CommaLocs, RParenLoc, ADL);
       if (!FDecl)
         return ExprError();
 
       // Update Fn to refer to the actual function selected.
       Expr *NewFn = 0;
       if (QualifiedDeclRefExpr *QDRExpr
-            = dyn_cast_or_null<QualifiedDeclRefExpr>(DRExpr))
+            = dyn_cast<QualifiedDeclRefExpr>(FnExpr))
         NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(),
                                                    QDRExpr->getLocation(),
                                                    false, false,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jun 30 17:34:41 2009
@@ -933,6 +933,42 @@
   return Result.getAsOpaquePtr();
 }
 
+Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template,
+                                                 SourceLocation TemplateNameLoc,
+                                                 SourceLocation LAngleLoc,
+                                           const TemplateArgument *TemplateArgs,
+                                                 unsigned NumTemplateArgs,
+                                                 SourceLocation RAngleLoc) {
+  // FIXME: Can we do any checking at this point? I guess we could check the
+  // template arguments that we have against the template name, if the template
+  // name refers to a single template. That's not a terribly common case, 
+  // though.
+  return Owned(TemplateIdRefExpr::Create(Context, 
+                                         /*FIXME: New type?*/Context.OverloadTy,
+                                         /*FIXME: Necessary?*/0,
+                                         /*FIXME: Necessary?*/SourceRange(),
+                                         Template, TemplateNameLoc, LAngleLoc,
+                                         TemplateArgs, 
+                                         NumTemplateArgs, RAngleLoc));
+}
+
+Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD,
+                                                 SourceLocation TemplateNameLoc,
+                                                 SourceLocation LAngleLoc,
+                                              ASTTemplateArgsPtr TemplateArgsIn,
+                                                SourceLocation *TemplateArgLocs,
+                                                 SourceLocation RAngleLoc) {
+  TemplateName Template = TemplateD.getAsVal<TemplateName>();
+  
+  // Translate the parser's template argument list in our AST format.
+  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+  
+  return BuildTemplateIdExpr(Template, TemplateNameLoc, LAngleLoc,
+                             TemplateArgs.data(), TemplateArgs.size(),
+                             RAngleLoc);
+}
+
 /// \brief Form a dependent template name.
 ///
 /// This action forms a dependent template name given the template

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Tue Jun 30 17:34:41 2009
@@ -107,6 +107,34 @@
 }
 
 Sema::OwningExprResult
+TemplateExprInstantiator::VisitTemplateIdRefExpr(TemplateIdRefExpr *E) {
+  TemplateName Template 
+    = SemaRef.InstantiateTemplateName(E->getTemplateName(), E->getTemplateNameLoc(),
+                                      TemplateArgs);
+  // FIXME: Can InstantiateTemplateName report an error?
+  
+  llvm::SmallVector<TemplateArgument, 4> InstantiatedArgs;
+  for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+    TemplateArgument InstArg = SemaRef.Instantiate(E->getTemplateArgs()[I],
+                                                   TemplateArgs);
+    if (InstArg.isNull())
+      return SemaRef.ExprError();
+    
+    InstantiatedArgs.push_back(InstArg);
+  }
+  
+  // FIXME: It's possible that we'll find out now that the template name 
+  // actually refers to a type, in which case this is a functional cast. 
+  // Implement this!
+  
+  return SemaRef.BuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
+                                     E->getLAngleLoc(),
+                                     InstantiatedArgs.data(),
+                                     InstantiatedArgs.size(),
+                                     E->getRAngleLoc());
+}
+
+Sema::OwningExprResult
 TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
   NamedDecl *D = E->getDecl();
   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {

Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp?rev=74563&view=auto

==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp Tue Jun 30 17:34:41 2009
@@ -0,0 +1,11 @@
+// RUN: clang-cc -fsyntax-only %s
+
+template<typename T> struct A { };
+
+template<typename T> T make(A<T>);
+
+void test_make() {
+  int& ir0 = make<int&>(A<int&>());
+  A<int> a0 = make< A<int> >(A<A<int> >());
+}
+





More information about the cfe-commits mailing list