diff options
author | Chris Lattner <sabre@nondot.org> | 2008-04-08 04:40:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-04-08 04:40:51 +0000 |
commit | 04421087832a031c90bd58f128c7c0e741db8dd2 (patch) | |
tree | c80c38dcc7ecb4d31cf5c10faa49e00fc373ea81 /lib/AST | |
parent | 5db17c9b5edb43e12196e565389b73e91a4fcb65 (diff) |
Add support for C++ default arguments, and rework Parse-Sema
interaction for function parameters, fixing PR2046.
Patch by Doug Gregor!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49369 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/Decl.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclSerialization.cpp | 5 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 15 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 8 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 9 | ||||
-rw-r--r-- | lib/AST/StmtSerialization.cpp | 21 |
6 files changed, 58 insertions, 4 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e27015b7ef..8228eceebf 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -224,9 +224,9 @@ FileVarDecl *FileVarDecl::Create(ASTContext &C, DeclContext *CD, ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *CD, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, - ScopedDecl *PrevDecl) { + Expr *DefArg, ScopedDecl *PrevDecl) { void *Mem = C.getAllocator().Allocate<ParmVarDecl>(); - return new (Mem) ParmVarDecl(CD, L, Id, T, S, PrevDecl); + return new (Mem) ParmVarDecl(CD, L, Id, T, S, DefArg, PrevDecl); } FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *CD, diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index bc5310c414..14666d6f00 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -226,15 +226,16 @@ FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D, ASTContext& C) { void ParmVarDecl::EmitImpl(llvm::Serializer& S) const { VarDecl::EmitImpl(S); S.EmitInt(getObjCDeclQualifier()); // From ParmVarDecl. + S.EmitOwnedPtr(getDefaultArg()); // From ParmVarDecl. } ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) { ParmVarDecl* decl = - new ParmVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL); + new ParmVarDecl(0, SourceLocation(), NULL, QualType(), None, NULL, NULL); decl->VarDecl::ReadImpl(D, C); decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt()); - + decl->DefaultArg = D.ReadOwnedPtr<Expr>(C); return decl; } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 5205702f29..0287aa0831 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -337,6 +337,9 @@ bool Expr::hasLocalSideEffect() const { if (getType()->isVoidType()) return cast<CastExpr>(this)->getSubExpr()->hasLocalSideEffect(); return false; + + case CXXDefaultArgExprClass: + return cast<CXXDefaultArgExpr>(this)->getExpr()->hasLocalSideEffect(); } } @@ -401,6 +404,8 @@ Expr::isLvalueResult Expr::isLvalue() const { return LV_Valid; case PreDefinedExprClass: return LV_Valid; + case CXXDefaultArgExprClass: + return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(); default: break; } @@ -465,6 +470,8 @@ bool Expr::hasGlobalStorage() const { return cast<ArraySubscriptExpr>(this)->getBase()->hasGlobalStorage(); case PreDefinedExprClass: return true; + case CXXDefaultArgExprClass: + return cast<CXXDefaultArgExpr>(this)->getExpr()->hasGlobalStorage(); } } @@ -636,6 +643,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { } return true; } + case CXXDefaultArgExprClass: + return cast<CXXDefaultArgExpr>(this)->getExpr()->isConstantExpr(Ctx, Loc); } } @@ -981,6 +990,9 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, return false; break; } + case CXXDefaultArgExprClass: + return cast<CXXDefaultArgExpr>(this) + ->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated); } // Cases that are valid constant exprs fall through to here. @@ -1009,6 +1021,9 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const { // Accept ((void*)0) as a null pointer constant, as many other // implementations do. return PE->getSubExpr()->isNullPointerConstant(Ctx); + } else if (const CXXDefaultArgExpr *DefaultArg = dyn_cast<CXXDefaultArgExpr>(this)) { + // See through default argument expressions + return DefaultArg->getExpr()->isNullPointerConstant(Ctx); } // This expression must be an integer type. diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 3bc32e75d8..03faf8b8b5 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -45,3 +45,11 @@ Stmt::child_iterator CXXThrowExpr::child_end() { return reinterpret_cast<Stmt**>(&Op)+0; return reinterpret_cast<Stmt**>(&Op)+1; } + +// CXXDefaultArgExpr +Stmt::child_iterator CXXDefaultArgExpr::child_begin() { + return reinterpret_cast<Stmt**>(Param->getDefaultArg()); +} +Stmt::child_iterator CXXDefaultArgExpr::child_end() { + return reinterpret_cast<Stmt**>(Param->getDefaultArg())+1; +} diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index ba82b7fcff..a76fd1f9b5 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -658,6 +658,11 @@ void StmtPrinter::VisitCallExpr(CallExpr *Call) { PrintExpr(Call->getCallee()); OS << "("; for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { + if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { + // Don't print any defaulted arguments + break; + } + if (i) OS << ", "; PrintExpr(Call->getArg(i)); } @@ -789,6 +794,10 @@ void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { } } +void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { + // Nothing to print: we picked up the default argument +} + // Obj-C void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index 41569df8f2..7058c0ce2f 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "llvm/Bitcode/Serialize.h" #include "llvm/Bitcode/Deserialize.h" @@ -185,6 +186,13 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { case ObjCStringLiteralClass: return ObjCStringLiteral::CreateImpl(D, C); + + //==--------------------------------------==// + // C++ + //==--------------------------------------==// + case CXXDefaultArgExprClass: + return CXXDefaultArgExpr::CreateImpl(D, C); + } } @@ -1002,3 +1010,16 @@ ObjCStringLiteral* ObjCStringLiteral::CreateImpl(Deserializer& D, ASTContext& C) StringLiteral* String = cast<StringLiteral>(D.ReadOwnedPtr<Stmt>(C)); return new ObjCStringLiteral(String,T,L); } + +//===----------------------------------------------------------------------===// +// C++ Serialization +//===----------------------------------------------------------------------===// +void CXXDefaultArgExpr::EmitImpl(Serializer& S) const { + S.EmitPtr(Param); +} + +CXXDefaultArgExpr *CXXDefaultArgExpr::CreateImpl(Deserializer& D, ASTContext& C) { + ParmVarDecl* Param = 0; + D.ReadPtr(Param, false); + return new CXXDefaultArgExpr(Param); +} |