r189906 - Revert "DebugInfo: Remove explicit declaration-emissiong handling now that we have a more principled approach (the 'requires complete type' callback)"

David Blaikie dblaikie at gmail.com
Tue Sep 3 19:12:12 PDT 2013


Author: dblaikie
Date: Tue Sep  3 21:12:12 2013
New Revision: 189906

URL: http://llvm.org/viewvc/llvm-project?rev=189906&view=rev
Log:
Revert "DebugInfo: Remove explicit declaration-emissiong handling now that we have a more principled approach (the 'requires complete type' callback)"

This reverts commit r189013.

This is causing a segfault crash in a test case I have. Reverting while
I investigate the issue.

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=189906&r1=189905&r2=189906&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Sep  3 21:12:12 2013
@@ -543,7 +543,8 @@ llvm::DIType CGDebugInfo::CreateType(con
 
 /// CreateCVRType - Get the qualified type from the cache or create
 /// a new one if necessary.
-llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
+llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit,
+                                              bool Declaration) {
   QualifierCollector Qc;
   const Type *T = Qc.strip(Ty);
 
@@ -569,7 +570,8 @@ llvm::DIType CGDebugInfo::CreateQualifie
     return getOrCreateType(QualType(T, 0), Unit);
   }
 
-  llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
+  llvm::DIType FromTy =
+      getOrCreateType(Qc.apply(CGM.getContext(), T), Unit, Declaration);
 
   // No need to fill in the Name, Line, Size, Alignment, Offset in case of
   // CVR derived types.
@@ -682,7 +684,8 @@ llvm::DIType CGDebugInfo::CreatePointerL
                                                 llvm::DIFile Unit) {
   if (Tag == llvm::dwarf::DW_TAG_reference_type ||
       Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
-    return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit));
+    return DBuilder.createReferenceType(
+        Tag, getOrCreateType(PointeeTy, Unit, true));
 
   // Bit size, align and offset of the type.
   // Size is always the size of a pointer. We can't use getTypeSize here
@@ -691,8 +694,8 @@ llvm::DIType CGDebugInfo::CreatePointerL
   uint64_t Size = CGM.getTarget().getPointerWidth(AS);
   uint64_t Align = CGM.getContext().getTypeAlign(Ty);
 
-  return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
-                                    Align);
+  return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit, true),
+                                    Size, Align);
 }
 
 llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
@@ -768,10 +771,12 @@ llvm::DIType CGDebugInfo::CreateType(con
   return BlockLiteralGeneric;
 }
 
-llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {
+llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit,
+                                     bool Declaration) {
   // Typedefs are derived from some other type.  If we have a typedef of a
   // typedef, make sure to emit the whole chain.
-  llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
+  llvm::DIType Src =
+      getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, Declaration);
   if (!Src)
     return llvm::DIType();
   // We don't set size information, but do specify where the typedef was
@@ -791,7 +796,7 @@ llvm::DIType CGDebugInfo::CreateType(con
   SmallVector<llvm::Value *, 16> EltTys;
 
   // Add the result type at least.
-  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
+  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit, true));
 
   // Set up remainder of arguments if there is a prototype.
   // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
@@ -799,7 +804,7 @@ llvm::DIType CGDebugInfo::CreateType(con
     EltTys.push_back(DBuilder.createUnspecifiedParameter());
   else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
     for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
-      EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
+      EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit, true));
   }
 
   llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -1196,7 +1201,7 @@ CollectCXXFriends(const CXXRecordDecl *R
       continue;
     if (TypeSourceInfo *TInfo = (*BI)->getFriendType())
       EltTys.push_back(DBuilder.createFriend(
-          RecordTy, getOrCreateType(TInfo->getType(), Unit)));
+          RecordTy, getOrCreateType(TInfo->getType(), Unit, true)));
   }
 }
 
@@ -1498,16 +1503,12 @@ void CGDebugInfo::completeClassData(cons
 }
 
 /// CreateType - get structure or union type.
-llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
+llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) {
   RecordDecl *RD = Ty->getDecl();
   const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
-  // Always emit declarations for types that aren't required to be complete when
-  // in limit-debug-info mode. If the type is later found to be required to be
-  // complete this declaration will be upgraded to a definition by
-  // `completeRequiredType`.
-  // If the type is dynamic, only emit the definition in TUs that require class
-  // data. This is handled by `completeClassData`.
-  if ((DebugKind <= CodeGenOptions::LimitedDebugInfo &&
+  // Limited debug info should only remove struct definitions that can
+  // safely be replaced by a forward declaration in the source code.
+  if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration &&
        !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) ||
       (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) {
     llvm::DIDescriptor FDContext =
@@ -1885,7 +1886,7 @@ llvm::DIType CGDebugInfo::CreateType(con
   llvm::DIType ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);
   if (!Ty->getPointeeType()->isFunctionType())
     return DBuilder.createMemberPointerType(
-        getOrCreateType(Ty->getPointeeType(), U), ClassType);
+        getOrCreateType(Ty->getPointeeType(), U, true), ClassType);
   return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType(
       CGM.getContext().getPointerType(
           QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())),
@@ -2065,18 +2066,26 @@ llvm::Value *CGDebugInfo::getCachedInter
 
 /// getOrCreateType - Get the type from the cache or create a new
 /// one if necessary.
-llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
+llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit,
+                                          bool Declaration) {
   if (Ty.isNull())
     return llvm::DIType();
 
   // Unwrap the type as needed for debug information.
   Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
 
-  if (llvm::DIType T = getCompletedTypeOrNull(Ty))
+  if (llvm::DIType T = getCompletedTypeOrNull(Ty)) {
+    // If we're looking for a definition, make sure we have definitions of any
+    // underlying types.
+    if (const TypedefType* TTy = dyn_cast<TypedefType>(Ty))
+      getOrCreateType(TTy->getDecl()->getUnderlyingType(), Unit, Declaration);
+    if (Ty.hasLocalQualifiers())
+      getOrCreateType(QualType(Ty.getTypePtr(), 0), Unit, Declaration);
     return T;
+  }
 
   // Otherwise create the type.
-  llvm::DIType Res = CreateTypeNode(Ty, Unit);
+  llvm::DIType Res = CreateTypeNode(Ty, Unit, Declaration);
   void* TyPtr = Ty.getAsOpaquePtr();
 
   // And update the type cache.
@@ -2145,10 +2154,11 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCI
 }
 
 /// CreateTypeNode - Create a new debug type node.
-llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
+llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit,
+                                         bool Declaration) {
   // Handle qualifiers, which recursively handles what they refer to.
   if (Ty.hasLocalQualifiers())
-    return CreateQualifiedType(Ty, Unit);
+    return CreateQualifiedType(Ty, Unit, Declaration);
 
   const char *Diag = 0;
 
@@ -2183,9 +2193,9 @@ llvm::DIType CGDebugInfo::CreateTypeNode
   case Type::BlockPointer:
     return CreateType(cast<BlockPointerType>(Ty), Unit);
   case Type::Typedef:
-    return CreateType(cast<TypedefType>(Ty), Unit);
+    return CreateType(cast<TypedefType>(Ty), Unit, Declaration);
   case Type::Record:
-    return CreateType(cast<RecordType>(Ty));
+    return CreateType(cast<RecordType>(Ty), Declaration);
   case Type::Enum:
     return CreateEnumType(cast<EnumType>(Ty));
   case Type::FunctionProto:
@@ -2371,7 +2381,7 @@ llvm::DIDescriptor CGDebugInfo::getDecla
   // in unlimited debug info)
   if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
     return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
-                           getOrCreateFile(TD->getLocation()));
+                           getOrCreateFile(TD->getLocation()), true);
   // Otherwise fall back to a fairly rudimentary cache of existing declarations.
   // This doesn't handle providing declarations (for functions or variables) for
   // entities without definitions in this TU, nor when the definition proceeds

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=189906&r1=189905&r2=189906&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Tue Sep  3 21:12:12 2013
@@ -107,14 +107,14 @@ class CGDebugInfo {
   unsigned Checksum(const ObjCInterfaceDecl *InterfaceDecl);
   llvm::DIType CreateType(const BuiltinType *Ty);
   llvm::DIType CreateType(const ComplexType *Ty);
-  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg);
-  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg);
+  llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F, bool Declaration);
+  llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F, bool Declaration);
   llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
                           llvm::DIFile F);
   llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
-  llvm::DIType CreateType(const RecordType *Tyg);
+  llvm::DIType CreateType(const RecordType *Ty, bool Declaration);
   llvm::DIType CreateTypeDefinition(const RecordType *Ty);
   llvm::DICompositeType CreateLimitedType(const RecordType *Ty);
   void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);
@@ -330,14 +330,14 @@ private:
 
   /// getOrCreateType - Get the type from the cache or create a new type if
   /// necessary.
-  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile Fg);
+  llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F, bool Declaration = false);
 
   /// getOrCreateLimitedType - Get the type from the cache or create a new
   /// partial type if necessary.
   llvm::DIType getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile F);
 
   /// CreateTypeNode - Create type metadata for a source language type.
-  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile Fg);
+  llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F, bool Declaration);
 
   /// getObjCInterfaceDecl - return the underlying ObjCInterfaceDecl
   /// if Ty is an ObjCInterface or a pointer to one.





More information about the cfe-commits mailing list