[cfe-commits] r65573 - in /cfe/trunk/lib/CodeGen: CGDebugInfo.cpp CGDebugInfo.h

Devang Patel dpatel at apple.com
Thu Feb 26 13:10:26 PST 2009


Author: dpatel
Date: Thu Feb 26 15:10:26 2009
New Revision: 65573

URL: http://llvm.org/viewvc/llvm-project?rev=65573&view=rev
Log:
Add support to emit debug info for objective-c interfaces.
(This is not yet used.)

Modified:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.h

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Feb 26 15:10:26 2009
@@ -14,7 +14,7 @@
 #include "CGDebugInfo.h"
 #include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/SourceManager.h"
@@ -290,6 +290,91 @@
   return RealDecl;
 }
 
+/// CreateType - get objective-c interface type.
+llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
+                                     llvm::DICompileUnit Unit) {
+  ObjCInterfaceDecl *Decl = Ty->getDecl();
+  
+  unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
+  SourceManager &SM = M->getContext().getSourceManager();
+
+  // Get overall information about the record type for the debug info.
+  std::string Name = Decl->getNameAsString();
+
+  llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation());
+  unsigned Line = SM.getInstantiationLineNumber(Decl->getLocation());
+  
+  
+  // To handle recursive interface, we
+  // first generate a debug descriptor for the struct as a forward declaration.
+  // Then (if it is a definition) we go through and get debug info for all of
+  // its members.  Finally, we create a descriptor for the complete type (which
+  // may refer to the forward decl if the struct is recursive) and replace all
+  // uses of the forward declaration with the final definition.
+  llvm::DIType FwdDecl =
+    DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, 0, 0, 0, 0,
+                                     llvm::DIType(), llvm::DIArray());
+  
+  // If this is just a forward declaration, return it.
+  if (Decl->isForwardDecl())
+    return FwdDecl;
+
+  // Otherwise, insert it into the TypeCache so that recursive uses will find
+  // it.
+  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
+
+  // Convert all the elements.
+  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
+
+  const ASTRecordLayout &RL = M->getContext().getASTObjCInterfaceLayout(Decl);
+
+  unsigned FieldNo = 0;
+  for (ObjCInterfaceDecl::ivar_iterator I = Decl->ivar_begin(),
+         E = Decl->ivar_end();  I != E; ++I, ++FieldNo) {
+    ObjCIvarDecl *Field = *I;
+    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+
+    std::string FieldName = Field->getNameAsString();
+
+    // Get the location for the field.
+    SourceLocation FieldDefLoc = Field->getLocation();
+    llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
+    unsigned FieldLine = SM.getInstantiationLineNumber(FieldDefLoc);
+    
+    // Bit size, align and offset of the type.
+    uint64_t FieldSize = M->getContext().getTypeSize(Ty);
+    unsigned FieldAlign = M->getContext().getTypeAlign(Ty);
+    uint64_t FieldOffset = RL.getFieldOffset(FieldNo);    
+    
+    // Create a DW_TAG_member node to remember the offset of this field in the
+    // struct.  FIXME: This is an absolutely insane way to capture this
+    // information.  When we gut debug info, this should be fixed.
+    FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
+                                             FieldName, FieldDefUnit,
+                                             FieldLine, FieldSize, FieldAlign,
+                                             FieldOffset, 0, FieldTy);
+    EltTys.push_back(FieldTy);
+  }
+  
+  llvm::DIArray Elements =
+    DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size());
+
+  // Bit size, align and offset of the type.
+  uint64_t Size = M->getContext().getTypeSize(Ty);
+  uint64_t Align = M->getContext().getTypeAlign(Ty);
+  
+  llvm::DIType RealDecl =
+    DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size,
+                                     Align, 0, 0, llvm::DIType(), Elements);
+
+  // Now that we have a real decl for the struct, replace anything using the
+  // old decl with the new one.  This will recursively update the debug info.
+  FwdDecl.getGV()->replaceAllUsesWith(RealDecl.getGV());
+  FwdDecl.getGV()->eraseFromParent();
+  
+  return RealDecl;
+}
+
 llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
                                      llvm::DICompileUnit Unit) {
   EnumDecl *Decl = Ty->getDecl();
@@ -559,3 +644,32 @@
                                     true/*definition*/, Var);
 }
 
+/// EmitGlobalVariable - Emit information about an objective-c interface.
+void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, 
+                                     ObjCInterfaceDecl *Decl) {
+  // Create global variable debug descriptor.
+  llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
+  SourceManager &SM = M->getContext().getSourceManager();
+  unsigned LineNo = SM.getInstantiationLineNumber(Decl->getLocation());
+
+  std::string Name = Decl->getNameAsString();
+
+  QualType T = M->getContext().buildObjCInterfaceType(Decl);
+  if (T->isIncompleteArrayType()) {
+    
+    // CodeGen turns int[] into int[1] so we'll do the same here.
+    llvm::APSInt ConstVal(32);
+    
+    ConstVal = 1;
+    QualType ET = M->getContext().getAsArrayType(T)->getElementType();
+    
+    T = M->getContext().getConstantArrayType(ET, ConstVal, 
+                                           ArrayType::Normal, 0);
+  }
+
+  DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo,
+                                    getOrCreateType(T, Unit),
+                                    Var->hasInternalLinkage(),
+                                    true/*definition*/, Var);
+}
+

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Thu Feb 26 15:10:26 2009
@@ -24,6 +24,7 @@
 
 namespace clang {
   class VarDecl;
+  class ObjCInterfaceDecl;
 
 namespace CodeGen {
   class CodeGenModule;
@@ -54,6 +55,7 @@
   llvm::DIType CreateType(const FunctionType *Ty, llvm::DICompileUnit U);
   llvm::DIType CreateType(const TagType *Ty, llvm::DICompileUnit U);
   llvm::DIType CreateType(const RecordType *Ty, llvm::DICompileUnit U);
+  llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DICompileUnit U);
   llvm::DIType CreateType(const EnumType *Ty, llvm::DICompileUnit U);
   llvm::DIType CreateType(const ArrayType *Ty, llvm::DICompileUnit U);
 
@@ -94,8 +96,10 @@
   
   /// EmitGlobalVariable - Emit information about a global variable.
   void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
- 
-  
+
+  /// EmitGlobalVariable - Emit information about an objective-c interface.
+  void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);
+   
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,





More information about the cfe-commits mailing list