[cfe-commits] r70962 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CodeGenModule.cpp CodeGenModule.h

Anders Carlsson andersca at mac.com
Mon May 4 21:44:02 PDT 2009


Author: andersca
Date: Mon May  4 23:44:02 2009
New Revision: 70962

URL: http://llvm.org/viewvc/llvm-project?rev=70962&view=rev
Log:
Refactor global decls to hold either a regular Decl or a CXXConstructorDecl + ctor type or a CXXDestructorDecl + dtor type.

Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=70962&r1=70961&r2=70962&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Mon May  4 23:44:02 2009
@@ -176,8 +176,8 @@
     return;
   }
 
-  EmitCXXConstructor(D, Ctor_Complete);
-  EmitCXXConstructor(D, Ctor_Base);
+  EmitGlobal(GlobalDecl(D, Ctor_Complete));
+  EmitGlobal(GlobalDecl(D, Ctor_Base));
 }
 
 void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=70962&r1=70961&r2=70962&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon May  4 23:44:02 2009
@@ -135,6 +135,17 @@
   }
 }
 
+const char *CodeGenModule::getMangledName(const GlobalDecl &GD) {
+  const NamedDecl *ND = GD.getDecl();
+  
+  if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
+    return getMangledCXXCtorName(D, GD.getCtorType());
+  if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
+    return getMangledCXXDtorName(D, GD.getDtorType());
+  
+  return getMangledName(ND);
+}
+
 /// \brief Retrieves the mangled name for the given declaration.
 ///
 /// If the given declaration requires a mangled name, returns an
@@ -411,7 +422,7 @@
   // previously unused static decl may become used during the generation of code
   // for a static function, iterate until no  changes are made.
   while (!DeferredDeclsToEmit.empty()) {
-    const ValueDecl *D = DeferredDeclsToEmit.back();
+    GlobalDecl D = DeferredDeclsToEmit.back();
     DeferredDeclsToEmit.pop_back();
 
     // The mangled name for the decl must have been emitted in GlobalDeclMap.
@@ -502,7 +513,9 @@
   return VD->getStorageClass() == VarDecl::Static;
 }
 
-void CodeGenModule::EmitGlobal(const ValueDecl *Global) {
+void CodeGenModule::EmitGlobal(const GlobalDecl &GD) {
+  const ValueDecl *Global = GD.getDecl();
+  
   // If this is an alias definition (which otherwise looks like a declaration)
   // emit it now.
   if (Global->hasAttr<AliasAttr>())
@@ -532,28 +545,32 @@
   if (MayDeferGeneration(Global)) {
     // If the value has already been used, add it directly to the
     // DeferredDeclsToEmit list.
-    const char *MangledName = getMangledName(Global);
+    const char *MangledName = getMangledName(GD);
     if (GlobalDeclMap.count(MangledName))
-      DeferredDeclsToEmit.push_back(Global);
+      DeferredDeclsToEmit.push_back(GD);
     else {
       // Otherwise, remember that we saw a deferred decl with this name.  The
       // first use of the mangled name will cause it to move into
       // DeferredDeclsToEmit.
-      DeferredDecls[MangledName] = Global;
+      DeferredDecls[MangledName] = GD;
     }
     return;
   }
 
   // Otherwise emit the definition.
-  EmitGlobalDefinition(Global);
+  EmitGlobalDefinition(GD);
 }
 
-void CodeGenModule::EmitGlobalDefinition(const ValueDecl *D) {
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+void CodeGenModule::EmitGlobalDefinition(const GlobalDecl &GD) {
+  const ValueDecl *D = GD.getDecl();
+  
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
+    EmitCXXConstructor(CD, GD.getCtorType());
+  else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     EmitGlobalFunctionDefinition(FD);
-  } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+  else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
     EmitGlobalVarDefinition(VD);
-  } else {
+  else {
     assert(0 && "Invalid argument to EmitGlobalDefinition()");
   }
 }
@@ -582,7 +599,7 @@
   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at the end
   // of the file.
-  llvm::DenseMap<const char*, const ValueDecl*>::iterator DDI = 
+  llvm::DenseMap<const char*, GlobalDecl>::iterator DDI = 
   DeferredDecls.find(MangledName);
   if (DDI != DeferredDecls.end()) {
     // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
@@ -654,7 +671,7 @@
   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at the end
   // of the file.
-  llvm::DenseMap<const char*, const ValueDecl*>::iterator DDI = 
+  llvm::DenseMap<const char*, GlobalDecl>::iterator DDI = 
     DeferredDecls.find(MangledName);
   if (DDI != DeferredDecls.end()) {
     // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
@@ -725,7 +742,7 @@
     // later.
     const char *MangledName = getMangledName(D);
     if (GlobalDeclMap.count(MangledName) == 0) {
-      DeferredDecls[MangledName] = D;
+      DeferredDecls[MangledName] = GlobalDecl(D);
       return;
     }
   }
@@ -1356,7 +1373,7 @@
   case Decl::CXXMethod:
   case Decl::Function:
   case Decl::Var:
-    EmitGlobal(cast<ValueDecl>(D));
+    EmitGlobal(GlobalDecl(cast<ValueDecl>(D)));
     break;
 
   // C++ Decls

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=70962&r1=70961&r2=70962&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon May  4 23:44:02 2009
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/LangOptions.h"
 #include "clang/AST/Attr.h"
+#include "clang/AST/DeclCXX.h"
 #include "CGBlocks.h"
 #include "CGCall.h"
 #include "CGCXX.h"
@@ -108,16 +109,48 @@
   /// has one).
   llvm::StringSet<> MangledNames;
 
+  /// GlobalDecl - represents a global declaration. This can either be a
+  /// CXXConstructorDecl and the constructor type (Base, Complete).
+  /// a CXXDestructorDecl and the destructor type (Base, Complete) or
+  // a regular VarDecl or a FunctionDecl.
+  class GlobalDecl {
+    llvm::PointerIntPair<const ValueDecl*, 2> Value;
+    
+  public:
+    GlobalDecl() {}
+    
+    explicit GlobalDecl(const ValueDecl *VD) : Value(VD, 0) {
+      assert(!isa<CXXConstructorDecl>(VD) && "Use other ctor with ctor decls!");
+      assert(!isa<CXXDestructorDecl>(VD) && "Use other ctor with dtor decls!");
+    }
+    GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) 
+      : Value(D, Type) {}
+    GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
+      : Value(D, Type) {}
+    
+    const ValueDecl *getDecl() const { return Value.getPointer(); }
+    
+    CXXCtorType getCtorType() const {
+      assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
+      return static_cast<CXXCtorType>(Value.getInt());
+    }
+    
+    CXXDtorType getDtorType() const {
+      assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
+      return static_cast<CXXDtorType>(Value.getInt());
+    }
+  };
+  
   /// DeferredDecls - This contains all the decls which have definitions but
   /// which are deferred for emission and therefore should only be output if
   /// they are actually used.  If a decl is in this, then it is known to have
   /// not been referenced yet.  The key to this map is a uniqued mangled name.
-  llvm::DenseMap<const char*, const ValueDecl*> DeferredDecls;
+  llvm::DenseMap<const char*, GlobalDecl> DeferredDecls;
 
   /// DeferredDeclsToEmit - This is a list of deferred decls which we have seen
   /// that *are* actually referenced.  These get code generated when the module
   /// is done.
-  std::vector<const ValueDecl*> DeferredDeclsToEmit;
+  std::vector<GlobalDecl> DeferredDeclsToEmit;
 
   /// LLVMUsed - List of global values which are required to be
   /// present in the object file; bitcast to i8*. This is used for
@@ -326,6 +359,8 @@
                               const Decl *TargetDecl,
                               AttributeListType &PAL);
 
+  const char *getMangledName(const GlobalDecl &D);
+
   const char *getMangledName(const NamedDecl *ND);
   const char *getMangledCXXCtorName(const CXXConstructorDecl *D, 
                                     CXXCtorType Type);
@@ -371,9 +406,9 @@
 
   /// EmitGlobal - Emit code for a singal global function or var decl. Forward
   /// declarations are emitted lazily.
-  void EmitGlobal(const ValueDecl *D);
+  void EmitGlobal(const GlobalDecl& D);
 
-  void EmitGlobalDefinition(const ValueDecl *D);
+  void EmitGlobalDefinition(const GlobalDecl& D);
 
   void EmitGlobalFunctionDefinition(const FunctionDecl *D);
   void EmitGlobalVarDefinition(const VarDecl *D);





More information about the cfe-commits mailing list