[cfe-commits] r66816 - in /cfe/trunk: include/clang/AST/Expr.h lib/Sema/SemaTemplateInstantiate.cpp

Douglas Gregor dgregor at apple.com
Thu Mar 12 11:36:18 PDT 2009


Author: dgregor
Date: Thu Mar 12 13:36:18 2009
New Revision: 66816

URL: http://llvm.org/viewvc/llvm-project?rev=66816&view=rev
Log:
Use StmtVisitor to handle the decoding of expressions for
instantiation. This is roughly the structure we want to expression
instantiation.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Mar 12 13:36:18 2009
@@ -372,6 +372,9 @@
   const llvm::APInt &getValue() const { return Value; }
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
+  /// \brief Retrieve the location of the literal.
+  SourceLocation getLocation() const { return Loc; }
+
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == IntegerLiteralClass; 
   }
@@ -563,6 +566,12 @@
   Expr *getSubExpr() { return cast<Expr>(Val); }
   virtual SourceRange getSourceRange() const { return SourceRange(L, R); }
 
+  /// \brief Get the location of the left parentheses '('.
+  SourceLocation getLParen() const { return L; }
+
+  /// \brief Get the location of the right parentheses ')'.
+  SourceLocation getRParen() const { return R; }
+
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ParenExprClass; 
   }

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Mar 12 13:36:18 2009
@@ -15,6 +15,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/StmtVisitor.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Basic/LangOptions.h"
 #include "llvm/Support/Compiler.h"
@@ -38,6 +39,8 @@
     Inst.Kind = ActiveTemplateInstantiation::TemplateInstantiation;
     Inst.PointOfInstantiation = PointOfInstantiation;
     Inst.Entity = reinterpret_cast<uintptr_t>(Entity);
+    Inst.TemplateArgs = 0;
+    Inst.NumTemplateArgs = 0;
     Inst.InstantiationRange = InstantiationRange;
     SemaRef.ActiveTemplateInstantiations.push_back(Inst);
     Invalid = false;
@@ -553,45 +556,81 @@
 //===----------------------------------------------------------------------===/
 // Template Instantiation for Expressions
 //===----------------------------------------------------------------------===/
+namespace {
+  class VISIBILITY_HIDDEN TemplateExprInstantiator 
+    : public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> {
+    Sema &SemaRef;
+    const TemplateArgument *TemplateArgs;
+    unsigned NumTemplateArgs;
+
+  public:
+    TemplateExprInstantiator(Sema &SemaRef, 
+                             const TemplateArgument *TemplateArgs,
+                             unsigned NumTemplateArgs)
+      : SemaRef(SemaRef), TemplateArgs(TemplateArgs), 
+        NumTemplateArgs(NumTemplateArgs) { }
+
+    // FIXME: Once we get closer to completion, replace these
+    // manually-written declarations with automatically-generated ones
+    // from clang/AST/StmtNodes.def.
+    Sema::OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
+    Sema::OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
+    Sema::OwningExprResult VisitParenExpr(ParenExpr *E);
+
+    // Base case. I'm supposed to ignore this.
+    Sema::OwningExprResult VisitStmt(Stmt *) { return SemaRef.ExprError(); }
+  };
+}
+
 Sema::OwningExprResult 
-Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
-                      unsigned NumTemplateArgs) {
-  if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
-    return Owned(new (Context) IntegerLiteral(IL->getValue(), IL->getType(),
-                                              IL->getSourceRange().getBegin()));
-  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
-    Decl *D = DRE->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 = InstantiateType(T, TemplateArgs, NumTemplateArgs,
-                            E->getSourceRange().getBegin(),
-                            NTTP->getDeclName());
-        if (T.isNull())
-          return ExprError();
-      }
-      return Owned(new (Context) IntegerLiteral(
-                            *TemplateArgs[NTTP->getPosition()].getAsIntegral(),
+TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
+  // FIXME: Can't we just re-use the expression node?
+  return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(E->getValue(), 
+                                                            E->getType(),
+                                                            E->getLocation()));
+}
+
+Sema::OwningExprResult
+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();
+    }
+    return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
+                           *TemplateArgs[NTTP->getPosition()].getAsIntegral(),
                             T, E->getSourceRange().getBegin()));
-    } else
-      assert(false && "Yes, this is lame");
-  } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
-    OwningExprResult SubExpr
-      = InstantiateExpr(PE->getSubExpr(), TemplateArgs,
-                        NumTemplateArgs);
-    if (SubExpr.isInvalid())
-      return ExprError();
-
-    return Owned(new (Context) ParenExpr(E->getSourceRange().getBegin(),
-                                         E->getSourceRange().getEnd(),
-                                         (Expr *)SubExpr.release()));
-  } else 
-    assert(false && "Yes, this is lame");
+  } else
+    assert(false && "Can't handle arbitrary declaration references");
 
-  return ExprError();
+  return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
+  Sema::OwningExprResult SubExpr
+    = SemaRef.InstantiateExpr(E->getSubExpr(), TemplateArgs, NumTemplateArgs);
+  if (SubExpr.isInvalid())
+    return SemaRef.ExprError();
+
+  return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
+                                               E->getLParen(), E->getRParen(), 
+                                               (Expr *)SubExpr.release()));
+}
+
+Sema::OwningExprResult 
+Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs,
+                      unsigned NumTemplateArgs) {
+  TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);
+  return Instantiator.Visit(E);
 }
 
 /// \brief Instantiate the base class specifiers of the given class





More information about the cfe-commits mailing list