[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