diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-20 22:03:28 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-20 22:03:28 +0000 |
commit | 75f1af02091235a21180cf22ac9f7dd0025577f6 (patch) | |
tree | f9231349050dc8691da1bc4f0aea1b2ed88ba98c | |
parent | ba02486ef05786847f0f465162d9bb461e142e48 (diff) |
Reuse VarDecl::Init to store the default argument of a ParmVarDecl,
reducing the size of ParmVarDecl by one pointer. Also means that we'll
properly (de-)serialize default arguments in C++ PCH files.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76487 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Decl.h | 67 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 3 |
3 files changed, 45 insertions, 26 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 55f141c0b6..ed1a231316 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -237,8 +237,17 @@ public: /// It is illegal to call this function with SC == None. static const char *getStorageClassSpecifierString(StorageClass SC); +protected: + /// \brief Placeholder type used in Init to denote an unparsed C++ default + /// argument. + struct UnparsedDefaultArgument; + + /// \brief The initializer for this variable or, for a ParmVarDecl, the + /// C++ default argument. + mutable llvm::PointerUnion3<Stmt *, EvaluatedStmt *, UnparsedDefaultArgument*> + Init; + private: - mutable llvm::PointerUnion<Stmt *, EvaluatedStmt *> Init; // FIXME: This can be packed into the bitfields in Decl. unsigned SClass : 3; bool ThreadSpecified : 1; @@ -295,9 +304,10 @@ public: return 0; const Stmt *S = Init.dyn_cast<Stmt *>(); - if (!S) - S = Init.get<EvaluatedStmt *>()->Value; - + if (!S) { + if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) + S = ES->Value; + } return (const Expr*) S; } Expr *getInit() { @@ -305,17 +315,19 @@ public: return 0; Stmt *S = Init.dyn_cast<Stmt *>(); - if (!S) - S = Init.get<EvaluatedStmt *>()->Value; + if (!S) { + if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) + S = ES->Value; + } return (Expr*) S; } /// \brief Retrieve the address of the initializer expression. Stmt **getInitAddress() { - if (Init.is<Stmt *>()) - return reinterpret_cast<Stmt **>(&Init); // FIXME: ugly hack - return &Init.get<EvaluatedStmt *>()->Value; + if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) + return &ES->Value; + return reinterpret_cast<Stmt **>(&Init); // FIXME: ugly hack } void setInit(ASTContext &C, Expr *I); @@ -495,12 +507,12 @@ public: class ImplicitParamDecl : public VarDecl { protected: ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType Tw) + IdentifierInfo *Id, QualType Tw) : VarDecl(DK, DC, L, Id, Tw, VarDecl::None) {} public: static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - QualType T); + SourceLocation L, IdentifierInfo *Id, + QualType T); // Implement isa/cast/dyncast/etc. static bool classof(const ImplicitParamDecl *D) { return true; } static bool classof(const Decl *D) { return D->getKind() == ImplicitParam; } @@ -513,14 +525,21 @@ class ParmVarDecl : public VarDecl { /// in, inout, etc. unsigned objcDeclQualifier : 6; - /// Default argument, if any. [C++ Only] - Expr *DefaultArg; + /// \brief Retrieves the fake "value" of an unparsed + static Expr *getUnparsedDefaultArgValue() { + uintptr_t Value = (uintptr_t)-1; + // Mask off the low bits + Value &= ~(uintptr_t)0x07; + return reinterpret_cast<Expr*> (Value); + } + protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, Expr *DefArg) - : VarDecl(DK, DC, L, Id, T, S), - objcDeclQualifier(OBJC_TQ_None), DefaultArg(DefArg) {} + : VarDecl(DK, DC, L, Id, T, S), objcDeclQualifier(OBJC_TQ_None) { + setDefaultArg(DefArg); + } public: static ParmVarDecl *Create(ASTContext &C, DeclContext *DC, @@ -536,18 +555,20 @@ public: const Expr *getDefaultArg() const { assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); - return DefaultArg; + return getInit(); } Expr *getDefaultArg() { assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); - return DefaultArg; + return getInit(); + } + void setDefaultArg(Expr *defarg) { + Init = reinterpret_cast<Stmt *>(defarg); } - void setDefaultArg(Expr *defarg) { DefaultArg = defarg; } /// hasDefaultArg - Determines whether this parameter has a default argument, /// either parsed or not. bool hasDefaultArg() const { - return DefaultArg != 0; + return getInit() || hasUnparsedDefaultArg(); } /// hasUnparsedDefaultArg - Determines whether this parameter has a @@ -561,7 +582,7 @@ public: /// }; // x has a regular default argument now /// @endcode bool hasUnparsedDefaultArg() const { - return DefaultArg == reinterpret_cast<Expr *>(-1); + return Init.is<UnparsedDefaultArgument*>(); } /// setUnparsedDefaultArg - Specify that this parameter has an @@ -569,7 +590,9 @@ public: /// real default argument via setDefaultArg when the class /// definition enclosing the function declaration that owns this /// default argument is completed. - void setUnparsedDefaultArg() { DefaultArg = reinterpret_cast<Expr *>(-1); } + void setUnparsedDefaultArg() { + Init = (UnparsedDefaultArgument *)0; + } QualType getOriginalType() const; diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 8df245a4b2..f2b7bdd70e 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -358,7 +358,6 @@ void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { VisitVarDecl(PD); PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]); - // FIXME: default argument (C++ only) } void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) { diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index ff5c576159..b2c6fd2618 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -354,9 +354,6 @@ void PCHDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) { void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { VisitVarDecl(D); Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding - // FIXME: emit default argument (C++) - // FIXME: why isn't the "default argument" just stored as the initializer - // in VarDecl? Code = pch::DECL_PARM_VAR; |