]> granicus.if.org Git - clang/commitdiff
Use StmtVisitor to handle the decoding of expressions for
authorDouglas Gregor <dgregor@apple.com>
Thu, 12 Mar 2009 18:36:18 +0000 (18:36 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 12 Mar 2009 18:36:18 +0000 (18:36 +0000)
instantiation. This is roughly the structure we want to expression
instantiation.

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

include/clang/AST/Expr.h
lib/Sema/SemaTemplateInstantiate.cpp

index 02a43c2079019414b140827c14a341d8b066d3a2..b6c6996fbcd73781ea31cdc475f9f3d3dc7b3d4d 100644 (file)
@@ -372,6 +372,9 @@ public:
   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 @@ public:
   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; 
   }
index edf7aab926dba94623e29ffdf5f54ef09f5577f2..6ed4d9fb445094d5632897ac7d39239c14338d5c 100644 (file)
@@ -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 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
     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 @@ QualType Sema::InstantiateType(QualType T,
 //===----------------------------------------------------------------------===/
 // 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 
+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 && "Can't handle arbitrary declaration references");
+
+  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) {
-  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(),
-                            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");
-
-  return ExprError();
+  TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);
+  return Instantiator.Visit(E);
 }
 
 /// \brief Instantiate the base class specifiers of the given class