[cfe-commits] r76487 - in /cfe/trunk: include/clang/AST/Decl.h lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp

Douglas Gregor dgregor at apple.com
Mon Jul 20 15:03:28 PDT 2009


Author: dgregor
Date: Mon Jul 20 17:03:28 2009
New Revision: 76487

URL: http://llvm.org/viewvc/llvm-project?rev=76487&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=76487&r1=76486&r2=76487&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon Jul 20 17:03:28 2009
@@ -237,8 +237,17 @@
   /// 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 @@
       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 @@
       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 @@
 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 @@
   /// 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 @@
     
   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 @@
   ///   }; // 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 @@
   /// 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;
   

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=76487&r1=76486&r2=76487&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Mon Jul 20 17:03:28 2009
@@ -358,7 +358,6 @@
 void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
   VisitVarDecl(PD);
   PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
-  // FIXME: default argument (C++ only)
 }
 
 void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) {

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=76487&r1=76486&r2=76487&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Mon Jul 20 17:03:28 2009
@@ -354,9 +354,6 @@
 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;
   
   





More information about the cfe-commits mailing list