From a135fb43eb94524a6529768596a4533eed9aa70d Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 15 Mar 2009 18:34:13 +0000 Subject: [PATCH] Add the ability to clone integer and string literals. Use it when instantiating template expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67030 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 8 ++++++-- lib/AST/Expr.cpp | 11 ++++++++++- lib/Sema/Sema.h | 8 ++++++++ lib/Sema/SemaTemplateInstantiate.cpp | 8 +++----- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index ed571fd6c4..cd13b84972 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -377,6 +377,9 @@ public: : Expr(IntegerLiteralClass, type), Value(V), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); } + + IntegerLiteral* Clone(ASTContext &C) const; + const llvm::APInt &getValue() const { return Value; } virtual SourceRange getSourceRange() const { return SourceRange(Loc); } @@ -515,7 +518,7 @@ public: /// strings formed from multiple concatenated tokens. static StringLiteral *Create(ASTContext &C, const char *StrData, unsigned ByteLength, bool Wide, QualType Ty, - SourceLocation *Loc, unsigned NumStrs); + const SourceLocation *Loc, unsigned NumStrs); /// Simple constructor for string literals made from one token. static StringLiteral *Create(ASTContext &C, const char *StrData, @@ -523,7 +526,8 @@ public: bool Wide, QualType Ty, SourceLocation Loc) { return Create(C, StrData, ByteLength, Wide, Ty, &Loc, 1); } - + + StringLiteral* Clone(ASTContext &C) const; void Destroy(ASTContext &C); const char *getStrData() const { return StrData; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index e34412e190..669f5c8225 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -26,6 +26,10 @@ using namespace clang; // Primary Expressions. //===----------------------------------------------------------------------===// +IntegerLiteral* IntegerLiteral::Clone(ASTContext &C) const { + return new (C) IntegerLiteral(Value, getType(), Loc); +} + /// getValueAsApproximateDouble - This returns the value as an inaccurate /// double. Note that this may cause loss of precision, but is useful for /// debugging dumps, etc. @@ -40,7 +44,8 @@ double FloatingLiteral::getValueAsApproximateDouble() const { StringLiteral *StringLiteral::Create(ASTContext &C, const char *StrData, unsigned ByteLength, bool Wide, QualType Ty, - SourceLocation *Loc, unsigned NumStrs) { + const SourceLocation *Loc, + unsigned NumStrs) { // Allocate enough space for the StringLiteral plus an array of locations for // any concatenated string tokens. void *Mem = C.Allocate(sizeof(StringLiteral)+ @@ -62,6 +67,10 @@ StringLiteral *StringLiteral::Create(ASTContext &C, const char *StrData, return SL; } +StringLiteral* StringLiteral::Clone(ASTContext &C) const { + return Create(C, StrData, ByteLength, IsWide, getType(), + TokLocs, NumConcatenated); +} void StringLiteral::Destroy(ASTContext &C) { C.Deallocate(const_cast(StrData)); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 6647945364..a357ae7621 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1867,6 +1867,14 @@ public: ClassTemplateSpecializationDecl *ClassTemplateSpec, bool ExplicitInstantiation); + // Simple function for cloning expressions. + template + OwningExprResult Clone(T *E) { + assert(!E->isValueDependent() && !E->isTypeDependent() && + "expression is value or type dependent!"); + return Owned(E->Clone(Context)); + } + // Objective-C declarations. virtual DeclTy *ActOnStartClassInterface(SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 9126d2a262..7b2d24b5bf 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -591,7 +591,8 @@ namespace { OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); // Base case. I'm supposed to ignore this. - Sema::OwningExprResult VisitStmt(Stmt *) { + Sema::OwningExprResult VisitStmt(Stmt *S) { + S->dump(); assert(false && "Cannot instantiate this kind of expression"); return SemaRef.ExprError(); } @@ -600,10 +601,7 @@ namespace { 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())); + return SemaRef.Clone(E); } Sema::OwningExprResult