]> granicus.if.org Git - clang/commitdiff
Alternative fix for r184473.
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 21 Jun 2013 00:40:50 +0000 (00:40 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 21 Jun 2013 00:40:50 +0000 (00:40 +0000)
This just seems a bit tidier/more principled. Based on a patch provided
by Adrian - with the only minor tweak that it needed to use
"getTypeOrNull" rather than "getCompletedTypeOrNull" since we don't
store declarations in the CompletedTypes cache.

No intended functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184509 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDebugInfo.cpp
lib/CodeGen/CGDebugInfo.h
lib/CodeGen/CodeGenTypes.cpp

index f8c814cb94f94cbc7b2045939bc47553c73d0908..e1b6342349684e40ccb7f95f1920811db950a9e7 100644 (file)
@@ -1886,22 +1886,6 @@ llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {
   return llvm::DIType();
 }
 
-/// ContainsFwdDecl - True if Ty is either a forward declaration or a
-/// derived type of a forward declaration.
-static bool ContainsFwdDecl(llvm::DIType Ty) {
-  // Composite types such as structs inherit from DIDerivedType, so
-  // check this first and do an early exit.
-  if (Ty.isForwardDecl())
-    return true;
-
-  if (Ty.isDerivedType()) {
-    llvm::DIDerivedType DTy(Ty);
-    return ContainsFwdDecl(DTy.getTypeDerivedFrom());
-  }
-
-  return false;
-}
-
 /// getCompletedTypeOrNull - Get the type from the cache or return null if it
 /// doesn't exist.
 llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
@@ -1920,19 +1904,22 @@ llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
   }
 
   // Verify that any cached debug info still exists.
-  if (V != 0) {
-    llvm::DIType CachedType(cast<llvm::MDNode>(V));
+  if (V != 0)
+    return llvm::DIType(cast<llvm::MDNode>(V));
 
-    // Unless we are limiting debug info, attempt to resolve any
-    // forward declarations.
-    if (DebugKind > CodeGenOptions::LimitedDebugInfo &&
-        ContainsFwdDecl(CachedType))
-      return llvm::DIType();
+  return llvm::DIType();
+}
 
-    return CachedType;
-  }
+void CGDebugInfo::completeFwdDecl(const RecordDecl &RD) {
+  // In limited debug info we only want to do this if the complete type was
+  // required.
+  if (DebugKind <= CodeGenOptions::LimitedDebugInfo)
+    return;
 
-  return llvm::DIType();
+  llvm::DIType T = getTypeOrNull(CGM.getContext().getRecordType(&RD));
+
+  if (T.Verify() && T.isForwardDecl())
+    getOrCreateType(QTy, getOrCreateFile(RD.getLocation());
 }
 
 /// getCachedInterfaceTypeOrNull - Get the type from the interface
index fc62600c32525705ad5db2d2b4af7b27058a26fe..72a9d71d79f3e71c07e7905c1da25ce477da5807 100644 (file)
@@ -289,6 +289,8 @@ public:
   llvm::DIType getOrCreateInterfaceType(QualType Ty,
                                         SourceLocation Loc);
 
+  void completeFwdDecls(const RecordDecl *TD);
+
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
index 4240216b230c66b331b1cfab199b8eb5f6664dc8..6ebb418e5ef5e7d922c8ff130fbda69474112bcc 100644 (file)
@@ -260,6 +260,11 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
   // yet, we'll just do it lazily.
   if (RecordDeclTypes.count(Context.getTagDeclType(RD).getTypePtr()))
     ConvertRecordDeclType(RD);
+
+  // If necessary, provide the full definition of a type only used with a
+  // declaration so far.
+  if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
+    DI->completeFwdDecls(RD);
 }
 
 static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,