[cfe-commits] r71594 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGenCXX/member-functions.cpp

Chris Lattner sabre at nondot.org
Tue May 12 14:21:09 PDT 2009


Author: lattner
Date: Tue May 12 16:21:08 2009
New Revision: 71594

URL: http://llvm.org/viewvc/llvm-project?rev=71594&view=rev
Log:
push GlobalDecl through enough of the CodeGenModule interfaces
to allow us to support generation of deferred ctors/dtors.
It looks like codegen isn't emitting a call to the dtor in 
member-functions.cpp:test2, but when it does, its body should
get emitted.

Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/test/CodeGenCXX/member-functions.cpp

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue May 12 16:21:08 2009
@@ -109,7 +109,7 @@
   const llvm::Type *Ty = 
     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 
                                    FPT->isVariadic());
-  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
+  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
   
   llvm::Value *This;
   
@@ -204,8 +204,8 @@
     getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
   
   const char *Name = getMangledCXXCtorName(D, Type);
-  
-  return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, D));
+  return cast<llvm::Function>(
+                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
 }
 
 const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, 
@@ -245,7 +245,8 @@
     getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false);
   
   const char *Name = getMangledCXXDtorName(D, Type);
-  return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, D));
+  return cast<llvm::Function>(
+                      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type)));
 }
 
 const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, 

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue May 12 16:21:08 2009
@@ -400,7 +400,7 @@
   if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
     const FunctionDecl *FD = CA->getFunctionDecl();
     
-    llvm::Constant* F = CGM.GetAddrOfFunction(FD);
+    llvm::Constant* F = CGM.GetAddrOfFunction(GlobalDecl(FD));
     assert(F && "Could not find function!");
   
     CleanupScope scope(*this);

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue May 12 16:21:08 2009
@@ -673,7 +673,7 @@
       LV.SetGlobalObjCRef(LV, true);
     return LV;
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
-    return LValue::MakeAddr(CGM.GetAddrOfFunction(FD),
+    return LValue::MakeAddr(CGM.GetAddrOfFunction(GlobalDecl(FD)),
                             E->getType().getCVRQualifiers(),
                             getContext().getObjCGCAttrKind(E->getType()));
   }

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue May 12 16:21:08 2009
@@ -406,7 +406,7 @@
     case Expr::QualifiedDeclRefExprClass: {
       NamedDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
-        return CGM.GetAddrOfFunction(FD);
+        return CGM.GetAddrOfFunction(GlobalDecl(FD));
       if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
         // We can never refer to a variable with local storage.
         if (!VD->hasLocalStorage()) {          

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue May 12 16:21:08 2009
@@ -513,7 +513,7 @@
   return VD->getStorageClass() == VarDecl::Static;
 }
 
-void CodeGenModule::EmitGlobal(const GlobalDecl &GD) {
+void CodeGenModule::EmitGlobal(GlobalDecl GD) {
   const ValueDecl *Global = GD.getDecl();
   
   // If this is an alias definition (which otherwise looks like a declaration)
@@ -561,13 +561,13 @@
   EmitGlobalDefinition(GD);
 }
 
-void CodeGenModule::EmitGlobalDefinition(const GlobalDecl &GD) {
+void CodeGenModule::EmitGlobalDefinition(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 (isa<FunctionDecl>(D))
+    EmitGlobalFunctionDefinition(GD);
   else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
     EmitGlobalVarDefinition(VD);
   else {
@@ -584,7 +584,7 @@
 /// to set the attributes on the function when it is first created.
 llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
                                                        const llvm::Type *Ty,
-                                                       const FunctionDecl *D) {
+                                                       GlobalDecl D) {
   // Lookup the entry, lazily creating it if necessary.
   llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
   if (Entry) {
@@ -606,15 +606,12 @@
     // list, and remove it from DeferredDecls (since we don't need it anymore).
     DeferredDeclsToEmit.push_back(DDI->second);
     DeferredDecls.erase(DDI);
-  } else if (D && D->isThisDeclarationADefinition() && MayDeferGeneration(D)) {
+  } else if (const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl())) {
     // If this the first reference to a C++ inline function in a class, queue up
     // the deferred function body for emission.  These are not seen as
     // top-level declarations.
-    // FIXME: Make this work for ctor/dtors.  We need to pass down a full
-    // GlobalDecl instead of just a FunctionDecl.
-    if (!isa<CXXConstructorDecl>(D) &&
-        !isa<CXXDestructorDecl>(D))
-    DeferredDeclsToEmit.push_back(GlobalDecl(D));
+    if (FD->isThisDeclarationADefinition() && MayDeferGeneration(FD))
+      DeferredDeclsToEmit.push_back(D);
   }
   
   // This function doesn't have a complete type (for example, the return
@@ -630,8 +627,8 @@
                                              llvm::Function::ExternalLinkage,
                                              "", &getModule());
   F->setName(MangledName);
-  if (D && ShouldSetAttributes)
-    SetFunctionAttributes(D, F);
+  if (D.getDecl() && ShouldSetAttributes)
+    SetFunctionAttributes(cast<FunctionDecl>(D.getDecl()), F);
   Entry = F;
   return F;
 }
@@ -639,12 +636,12 @@
 /// GetAddrOfFunction - Return the address of the given function.  If Ty is
 /// non-null, then this function will use the specified type if it has to
 /// create it (this occurs when we see a definition of the function).
-llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D,
+llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
                                                  const llvm::Type *Ty) {
   // If there was no specific requested type, just convert it now.
   if (!Ty)
-    Ty = getTypes().ConvertType(D->getType());
-  return GetOrCreateLLVMFunction(getMangledName(D), Ty, D);
+    Ty = getTypes().ConvertType(GD.getDecl()->getType());
+  return GetOrCreateLLVMFunction(getMangledName(GD.getDecl()), Ty, GD);
 }
 
 /// CreateRuntimeFunction - Create a new runtime function with the specified
@@ -654,7 +651,7 @@
                                      const char *Name) {
   // Convert Name to be a uniqued string from the IdentifierInfo table.
   Name = getContext().Idents.get(Name).getName();
-  return GetOrCreateLLVMFunction(Name, FTy, 0);
+  return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());
 }
 
 /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
@@ -924,9 +921,10 @@
 }
 
 
-void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
+void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
   const llvm::FunctionType *Ty;
-
+  const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
+  
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
     bool isVariadic = D->getType()->getAsFunctionProtoType()->isVariadic();
     
@@ -948,7 +946,7 @@
   }
 
   // Get or create the prototype for the function.
-  llvm::Constant *Entry = GetAddrOfFunction(D, Ty);
+  llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
   
   // Strip off a bitcast if we got one back.
   if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
@@ -973,7 +971,7 @@
     // (e.g. "int f(int x)").  Start by making a new function of the
     // correct type, RAUW, then steal the name.
     GlobalDeclMap.erase(getMangledName(D));
-    llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(D, Ty));
+    llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
     NewFn->takeName(OldFn);
     
     // If this is an implementation of a function without a prototype, try to
@@ -1024,7 +1022,7 @@
   // if a deferred decl.
   llvm::Constant *Aliasee;
   if (isa<llvm::FunctionType>(DeclTy))
-    Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, 0);
+    Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
   else
     Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
                                     llvm::PointerType::getUnqual(DeclTy), 0);
@@ -1105,7 +1103,7 @@
   // Unique the name through the identifier table.
   Name = getContext().Idents.get(Name).getName();
   // FIXME: param attributes for sext/zext etc.
-  return GetOrCreateLLVMFunction(Name, Ty, 0);
+  return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
 }
 
 llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue May 12 16:21:08 2009
@@ -65,6 +65,38 @@
   class CGDebugInfo;
   class CGObjCRuntime;
 
+/// 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());
+  }
+};
+  
 /// CodeGenModule - This class organizes the cross-function state that is used
 /// while generating LLVM code.
 class CodeGenModule : public BlockModule {
@@ -109,38 +141,6 @@
   /// 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
@@ -220,7 +220,7 @@
   /// GetAddrOfFunction - Return the address of the given function.  If Ty is
   /// non-null, then this function will use the specified type if it has to
   /// create it.
-  llvm::Constant *GetAddrOfFunction(const FunctionDecl *D,
+  llvm::Constant *GetAddrOfFunction(GlobalDecl GD,
                                     const llvm::Type *Ty = 0);
 
   /// GetStringForStringLiteral - Return the appropriate bytes for a string
@@ -383,7 +383,7 @@
   
   llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName,
                                           const llvm::Type *Ty,
-                                          const FunctionDecl *D);
+                                          GlobalDecl D);
   llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName,
                                         const llvm::PointerType *PTy,
                                         const VarDecl *D);
@@ -406,11 +406,11 @@
 
   /// EmitGlobal - Emit code for a singal global function or var decl. Forward
   /// declarations are emitted lazily.
-  void EmitGlobal(const GlobalDecl& D);
+  void EmitGlobal(GlobalDecl D);
 
-  void EmitGlobalDefinition(const GlobalDecl& D);
+  void EmitGlobalDefinition(GlobalDecl D);
 
-  void EmitGlobalFunctionDefinition(const FunctionDecl *D);
+  void EmitGlobalFunctionDefinition(GlobalDecl GD);
   void EmitGlobalVarDefinition(const VarDecl *D);
   void EmitAliasDefinition(const ValueDecl *D);
   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
@@ -437,8 +437,8 @@
   void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type);
   
   // FIXME: Hardcoding priority here is gross.
-  void AddGlobalCtor(llvm::Function * Ctor, int Priority=65535);
-  void AddGlobalDtor(llvm::Function * Dtor, int Priority=65535);
+  void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535);
+  void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535);
 
   /// EmitCtorList - Generates a global array of functions and priorities using
   /// the given list and name. This array will have appending linkage and is

Modified: cfe/trunk/test/CodeGenCXX/member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/member-functions.cpp?rev=71594&r1=71593&r2=71594&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/member-functions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/member-functions.cpp Tue May 12 16:21:08 2009
@@ -20,8 +20,10 @@
 
 
 struct S {
-  S() { }
-  ~S() { }
+  // RUN: grep "define linkonce_odr void @_ZN1SC1Ev" %t &&
+  inline S() { }
+  // RUN: grep "define linkonce_odr void @_ZN1SC1Ev" %t &&
+  inline ~S() { }
   
   
   void f_inline1() { }





More information about the cfe-commits mailing list