]> granicus.if.org Git - clang/commitdiff
DebugInfo: Unify & optimize the lazy addition of record types
authorDavid Blaikie <dblaikie@gmail.com>
Thu, 15 Aug 2013 20:49:17 +0000 (20:49 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 15 Aug 2013 20:49:17 +0000 (20:49 +0000)
Rather than going through the whole getOrCreateType machinery to
manifest a type, cut straight to the implementation because we know we
have to do work.

While the previous implementation was sufficient for the two cases
(completeness and required completeness) we have already (the general
machinery could inspect the type for those attributes & go down the full
definition path), a pending change (to emit info for types when we emit
their vtables) won't have that luxury & we'll need to force the creation
rather than relying on the general purpose routine.

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

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

index 5ac4a5dccbf1b862cb86efb75377c7d2919cf3b9..94f1bde38d512a55c64cce283a9c1a2bdb2fcc90 100644 (file)
@@ -1403,6 +1403,26 @@ llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D,
   return T;
 }
 
+void CGDebugInfo::completeType(const RecordDecl *RD) {
+  if (DebugKind > CodeGenOptions::LimitedDebugInfo ||
+      !CGM.getLangOpts().CPlusPlus)
+    completeRequiredType(RD);
+}
+
+void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
+  QualType Ty = CGM.getContext().getRecordType(RD);
+  llvm::DIType T = getTypeOrNull(Ty);
+  if (!T || !T.isForwardDecl())
+    return;
+  void* TyPtr = Ty.getAsOpaquePtr();
+  if (CompletedTypeCache.count(TyPtr))
+    return;
+  llvm::DIType Res = CreateTypeDefinition(Ty->castAs<RecordType>());
+  assert(!Res.isForwardDecl());
+  CompletedTypeCache[TyPtr] = Res;
+  TypeCache[TyPtr] = Res;
+}
+
 /// CreateType - get structure or union type.
 llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) {
   RecordDecl *RD = Ty->getDecl();
@@ -1419,6 +1439,12 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) {
     return RetTy;
   }
 
+  return CreateTypeDefinition(Ty);
+}
+
+llvm::DIType CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
+  RecordDecl *RD = Ty->getDecl();
+
   // Get overall information about the record type for the debug info.
   llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
 
@@ -1930,20 +1956,6 @@ llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
   return llvm::DIType(cast_or_null<llvm::MDNode>(V));
 }
 
-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 &&
-      CGM.getLangOpts().CPlusPlus)
-    return;
-
-  QualType QTy = CGM.getContext().getRecordType(&RD);
-  llvm::DIType T = getTypeOrNull(QTy);
-
-  if (T && T.isForwardDecl())
-    getOrCreateType(QTy, getOrCreateFile(RD.getLocation()));
-}
-
 /// getCachedInterfaceTypeOrNull - Get the type from the interface
 /// cache, unless it needs to regenerated. Otherwise return null.
 llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) {
index 74b8e95999305e8f4a01d6b38aa5c1d89d032931..72d956ed3737813332a2c89ad9980828b4372231 100644 (file)
@@ -115,6 +115,7 @@ class CGDebugInfo {
   llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const RecordType *Ty, bool Declaration);
+  llvm::DIType CreateTypeDefinition(const RecordType *Ty);
   llvm::DIType CreateLimitedType(const RecordType *Ty);
   llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
@@ -288,7 +289,9 @@ public:
   llvm::DIType getOrCreateInterfaceType(QualType Ty,
                                         SourceLocation Loc);
 
-  void completeFwdDecl(const RecordDecl &TD);
+  void completeType(const RecordDecl *RD);
+  void completeRequiredType(const RecordDecl *RD);
+
 
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
index 88a1393a68f395ef5bf08b2f50bbd37308b98ff2..442f2931a0a350f451a0de6eb5c0e05b37c0779f 100644 (file)
@@ -264,7 +264,7 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
   // If necessary, provide the full definition of a type only used with a
   // declaration so far.
   if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
-    DI->completeFwdDecl(*RD);
+    DI->completeType(RD);
 }
 
 static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,
index c6d40330e0cdfd3dc1ec301112d7f8221ca78ea4..a33b3a38fb589d68b41507867f67bd3f6e256ffb 100644 (file)
@@ -100,7 +100,7 @@ namespace {
     virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) LLVM_OVERRIDE {
       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
-          DI->completeFwdDecl(*RD);
+          DI->completeRequiredType(RD);
     }
 
     virtual void HandleTranslationUnit(ASTContext &Ctx) {