From 030854b95f7bfd86aaa8afd9ae1aff9768a37e9a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 9 May 2010 06:40:08 +0000 Subject: [PATCH] pch'ify default argument definitions and uses. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103376 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 20 ++++++++++++++++++-- include/clang/Frontend/PCHBitCodes.h | 3 ++- lib/Frontend/PCHReaderStmt.cpp | 17 ++++++++++++++++- lib/Frontend/PCHWriterDecl.cpp | 6 +++--- lib/Frontend/PCHWriterStmt.cpp | 15 +++++++++++++++ test/PCH/cxx_exprs.h | 11 +++++++---- 6 files changed, 61 insertions(+), 11 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 7e47c16f0d..1ae16c3eb8 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -351,6 +351,11 @@ public: return static_cast(Operand.get()); } + void setExprOperand(Expr *E) { + assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); + Operand = E; + } + virtual SourceRange getSourceRange() const { return Range; } void setSourceRange(SourceRange R) { Range = R; } @@ -471,8 +476,7 @@ protected: CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, Expr *SubExpr) - : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) - { + : Expr(SC, SubExpr->getType(), false, false), Param(param, true), Loc(Loc) { *reinterpret_cast(this + 1) = SubExpr; } @@ -480,6 +484,9 @@ protected: virtual void DoDestroy(ASTContext &C); public: + CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} + + // Param is the parameter whose default argument is used by this // expression. static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc, @@ -498,6 +505,9 @@ public: const ParmVarDecl *getParam() const { return Param.getPointer(); } ParmVarDecl *getParam() { return Param.getPointer(); } + /// isExprStored - Return true if this expression owns the expression. + bool isExprStored() const { return Param.getInt(); } + // Retrieve the actual argument to the function call. const Expr *getExpr() const { if (Param.getInt()) @@ -509,10 +519,16 @@ public: return *reinterpret_cast (this + 1); return getParam()->getDefaultArg(); } + + void setExpr(Expr *E) { + Param.setInt(true); + Param.setPointer((ParmVarDecl*)E); + } /// \brief Retrieve the location where this default argument was actually /// used. SourceLocation getUsedLocation() const { return Loc; } + void setUsedLocation(SourceLocation L) { Loc = L; } virtual SourceRange getSourceRange() const { // Default argument expressions have no representation in the diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 21bad01835..c217a75a3b 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -750,7 +750,8 @@ namespace clang { EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). EXPR_CXX_THIS, // CXXThisExpr - EXPR_CXX_THROW // CXXThrowExpr + EXPR_CXX_THROW, // CXXThrowExpr + EXPR_CXX_DEFAULT_ARG // CXXDefaultArgExpr }; /// \brief The kinds of designators that can occur in a diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index c3cc504a1a..3392c04d55 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -129,6 +129,7 @@ namespace { unsigned VisitCXXTypeidExpr(CXXTypeidExpr *E); unsigned VisitCXXThisExpr(CXXThisExpr *E); unsigned VisitCXXThrowExpr(CXXThrowExpr *E); + unsigned VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); }; } @@ -532,7 +533,6 @@ unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); E->setSubExpr(cast(StmtStack.back())); E->setCastKind((CastExpr::CastKind)Record[Idx++]); - return 1; } @@ -1004,6 +1004,7 @@ unsigned PCHStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) { } // typeid(42+2) + E->setExprOperand(cast(StmtStack.back())); return 1; } @@ -1017,9 +1018,20 @@ unsigned PCHStmtReader::VisitCXXThisExpr(CXXThisExpr *E) { unsigned PCHStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) { VisitExpr(E); E->setThrowLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + E->setSubExpr(cast(StmtStack.back())); return 1; } +unsigned PCHStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { + VisitExpr(E); + E->setUsedLocation(SourceLocation::getFromRawEncoding(Record[Idx++])); + bool HasStoredExpr = Record[Idx++]; + if (!HasStoredExpr) return 0; + E->setExpr(cast(StmtStack.back())); + return 1; // Read it. +} + + // Within the bitstream, expressions are stored in Reverse Polish // Notation, with each of the subexpressions preceding the // expression they are stored in. To evaluate expressions, we @@ -1381,6 +1393,9 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) { case pch::EXPR_CXX_THROW: S = new (Context) CXXThrowExpr(Empty); break; + case pch::EXPR_CXX_DEFAULT_ARG: + S = new (Context) CXXDefaultArgExpr(Empty); + break; } // We hit a STMT_STOP, so we're done with this expression. diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index a898c705e2..28a10ad6b0 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -416,7 +416,7 @@ void PCHDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->isDeclaredInCondition()); Record.push_back(D->isExceptionVariable()); Writer.AddDeclRef(D->getPreviousDeclaration(), Record); - Record.push_back(D->getInit()? 1 : 0); + Record.push_back(D->getInit() ? 1 : 0); if (D->getInit()) Writer.AddStmt(D->getInit()); Code = pch::DECL_VAR; @@ -445,7 +445,8 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { D->getStorageClass() == 0 && !D->hasCXXDirectInitializer() && // Can params have this ever? D->getObjCDeclQualifier() == 0 && - !D->hasInheritedDefaultArg()) + !D->hasInheritedDefaultArg() && + D->getInit() == 0) // No default expr. AbbrevToUse = Writer.getParmVarDeclAbbrev(); // Check things we know are true of *every* PARM_VAR_DECL, which is more than @@ -456,7 +457,6 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { assert(!D->isDeclaredInCondition() && "PARM_VAR_DECL can't be in condition"); assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var"); assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl"); - assert(D->getInit() == 0 && "PARM_VAR_DECL never has init"); } void PCHDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index e042e77c6b..e64ebbe8a3 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -125,6 +125,7 @@ namespace { void VisitCXXTypeidExpr(CXXTypeidExpr *E); void VisitCXXThisExpr(CXXThisExpr *E); void VisitCXXThrowExpr(CXXThrowExpr *E); + void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); }; } @@ -934,11 +935,25 @@ void PCHStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) { } void PCHStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) { + VisitExpr(E); Writer.AddSourceLocation(E->getThrowLoc(), Record); Writer.WriteSubStmt(E->getSubExpr()); Code = pch::EXPR_CXX_THROW; } +void PCHStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { + VisitExpr(E); + Writer.AddSourceLocation(E->getUsedLocation(), Record); + if (E->isExprStored()) { + Record.push_back(1); + Writer.WriteSubStmt(E->getExpr()); + } else { + Record.push_back(0); + } + + Code = pch::EXPR_CXX_DEFAULT_ARG; +} + //===----------------------------------------------------------------------===// // PCHWriter Implementation diff --git a/test/PCH/cxx_exprs.h b/test/PCH/cxx_exprs.h index bda23613ad..60ac263715 100644 --- a/test/PCH/cxx_exprs.h +++ b/test/PCH/cxx_exprs.h @@ -5,7 +5,7 @@ typedef __typeof__(static_cast(0)) static_cast_result; // CXXDynamicCastExpr -struct Base { virtual void f(); }; +struct Base { virtual void f(int x = 492); }; struct Derived : Base { void g(); }; Base *base_ptr; typedef __typeof__(dynamic_cast(base_ptr)) dynamic_cast_result; @@ -31,7 +31,7 @@ typedef __typeof__(nullptr) cxx_null_ptr_result; void foo(Derived *P) { // CXXMemberCallExpr - P->f(); + P->f(12); } @@ -46,10 +46,13 @@ typedef __typeof__(typeid(2))* typeid_result2; void Derived::g() { // CXXThisExpr - f(); // Implicit - this->f(); // Explicit + f(2); // Implicit + this->f(1); // Explicit // CXXThrowExpr throw; throw 42; + + // CXXDefaultArgExpr + f(); } \ No newline at end of file -- 2.40.0