aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-04-08 04:40:51 +0000
committerChris Lattner <sabre@nondot.org>2008-04-08 04:40:51 +0000
commit04421087832a031c90bd58f128c7c0e741db8dd2 (patch)
treec80c38dcc7ecb4d31cf5c10faa49e00fc373ea81 /lib/AST
parent5db17c9b5edb43e12196e565389b73e91a4fcb65 (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.cpp4
-rw-r--r--lib/AST/DeclSerialization.cpp5
-rw-r--r--lib/AST/Expr.cpp15
-rw-r--r--lib/AST/ExprCXX.cpp8
-rw-r--r--lib/AST/StmtPrinter.cpp9
-rw-r--r--lib/AST/StmtSerialization.cpp21
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);
+}