<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 11, 2015 at 11:55 AM, Adrian Prantl <span dir="ltr"><<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="h5"><br><div><blockquote type="cite"><div>On Sep 11, 2015, at 11:21 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:</div><br><div><br><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">On Fri, Sep 11, 2015 at 10:23 AM, Adrian Prantl via cfe-commits<span> </span><span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span><span> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: adrian<br>Date: Fri Sep 11 12:23:08 2015<br>New Revision: 247432<br><br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project?rev=247432&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=247432&view=rev</a><br>Log:<br>Module Debugging: Emit forward declarations for types that are defined in<br>clang modules, if -dwarf-ext-refs (DebugTypesExtRefs) is specified.<br><br>This reimplements r247369 in about a third of the amount of code.<br>Thanks to David Blaikie pointing this out in post-commit review!<br><br>Added:<br>   <span> </span>cfe/trunk/test/Modules/ExtDebugInfo.cpp<br>   <span> </span>cfe/trunk/test/Modules/ExtDebugInfo.m<br>Modified:<br>   <span> </span>cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>   <span> </span>cfe/trunk/lib/CodeGen/CGDebugInfo.h<br><br>Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=247432&r1=247431&r2=247432&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=247432&r1=247431&r2=247432&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Sep 11 12:23:08 2015<br>@@ -148,7 +148,9 @@ void CGDebugInfo::setLocation(SourceLoca<br> }<br><br> llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(const Decl *D) {<br>-  return getContextDescriptor(cast<Decl>(D->getDeclContext()), TheCU);<br>+  llvm::DIScope *Mod = getParentModuleOrNull(D);<br>+  return getContextDescriptor(cast<Decl>(D->getDeclContext()),<br>+                              Mod ? Mod : TheCU);<br></blockquote><div><br></div><div>Might've been nice to separate the module-parenting part of the change, smaller patches (easier to revert, review, etc), the usual stuff.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> }<br><br> llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,<br>@@ -1448,6 +1450,9 @@ void CGDebugInfo::completeRequiredType(c<br>     if (CXXDecl->isDynamicClass())<br>       return;<br><br>+  if (DebugTypeExtRefs && RD->isFromASTFile())<br>+    return;<br>+<br>   QualType Ty = CGM.getContext().getRecordType(RD);<br>   llvm::DIType *T = getTypeOrNull(Ty);<br>   if (T && T->isForwardDecl())<br>@@ -1478,8 +1483,19 @@ static bool hasExplicitMemberDefinition(<br> }<br><br> static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind,<br>+                                 bool DebugTypeExtRefs,<br>                                 <span> </span>const RecordDecl *RD,<br>                                 <span> </span>const LangOptions &LangOpts) {<br>+  // Does the type exist in an imported clang module?<br>+  if (DebugTypeExtRefs && RD->isFromASTFile()) {<br>+    if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))<br>+      if (CTSD->isExplicitInstantiationOrSpecialization())<br>+        // We may not assume that this type made it into the module.<br></blockquote><div><br></div><div>I guess you mean "we may assume this type made it into the module"? (the "not" seems erroneous - but perhaps I'm misparsing the sentence?)</div></div></div></blockquote><br></div></div></div><div>Yes, I inverted the condition without inverting the comment.</div><div><br></div><div><span class=""><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+        return true;<br></blockquote><div><br></div><div>Does this case ^ actually do anything? (aren't all these instantiations going to be definitions anyway? so if you removed that code the below would return true anyway, wouldn't it?)</div></div></div></blockquote><div><br></div></span><div>Good catch! I removed the condition.</div><span class=""><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+    if (RD->getDefinition())<br>+      return true;<br>+  }<br>+<br>   if (DebugKind > CodeGenOptions::LimitedDebugInfo)<br>     return false;<br><br>@@ -1513,7 +1529,8 @@ static bool shouldOmitDefinition(CodeGen<br> llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {<br>   RecordDecl *RD = Ty->getDecl();<br>   llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0)));<br>-  if (T || shouldOmitDefinition(DebugKind, RD, CGM.getLangOpts())) {<br>+  if (T || shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD,<br>+                                CGM.getLangOpts())) {<br>     if (!T)<br>       T = getOrCreateRecordFwdDecl(Ty, getDeclContextDescriptor(RD));<br>     return T;<br>@@ -1616,6 +1633,12 @@ llvm::DIType *CGDebugInfo::CreateType(co<br>   if (!ID)<br>     return nullptr;<br><br>+  // Return a forward declaration if this type was imported from a clang module.<br></blockquote><div><br></div><div>What's this extra code needed for? Isn't this what shouldOmitDefinition already does? It causes calls to getOrCreateRecordFwdDecl and so we should never get into the CreateTypeDefinition function for the type.</div></div></div></blockquote><div><br></div></span>An ObjCInterfaceType is not a RecordDecl, so we have to replicate this here.<span class=""><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+  if (DebugTypeExtRefs && ID->isFromASTFile() && ID->getDefinition())<br>+    return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,<br>+                                      ID->getName(),<br>+                                      getDeclContextDescriptor(ID), Unit, 0);<br>+<br>   // Get overall information about the record type for the debug info.<br>   llvm::DIFile *DefUnit = getOrCreateFile(ID->getLocation());<br>   unsigned Line = getLineNumber(ID->getLocation());<br>@@ -1669,9 +1692,9 @@ CGDebugInfo::getOrCreateModuleRef(Extern<br>       TheCU->getSourceLanguage(), internString(Mod.ModuleName),<br>       internString(Mod.Path), TheCU->getProducer(), true, StringRef(), 0,<br>       internString(Mod.ASTFile), llvm::DIBuilder::FullDebug, Mod.Signature);<br>-  llvm::DIModule *M =<br>-      DIB.createModule(CU, Mod.ModuleName, ConfigMacros, internString(Mod.Path),<br>-                       internString(CGM.getHeaderSearchOpts().Sysroot));<br>+  llvm::DIModule *M = DIB.createModule(<br>+      CU, Mod.ModuleName, ConfigMacros, internString(Mod.Path),<br>+      internString(CGM.getHeaderSearchOpts().Sysroot));<br></blockquote><div><br></div><div>This is just reformatting, yes? (stared at it for a while & couldn't spot the difference)</div></div></div></blockquote><div><br></div></span><div>Sorry, yes.</div><span class=""><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">   DIB.finalize();<br>   ModRef.reset(M);<br>   return M;<br>@@ -1930,6 +1953,7 @@ llvm::DIType *CGDebugInfo::CreateType(co<br><br> llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {<br>   const EnumDecl *ED = Ty->getDecl();<br>+<br>   uint64_t Size = 0;<br>   uint64_t Align = 0;<br>   if (!ED->getTypeForDecl()->isIncompleteType()) {<br>@@ -1939,9 +1963,12 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp<br><br>   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);<br><br>+  bool isImportedFromModule =<br>+      DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();<br>+<br></blockquote><div><br></div><div>Again, seems like code that shouldn't be here - shouldOmitDefinition returning true should mean that getOrCreateRecordFwdDecl is called and we never reach into the concrete CreateXXX functions.</div></div></div></blockquote><div><br></div></span><div>Again, an EnumDecl is not a RecordDecl (<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html</a>). Am I missing something obvious here?</div></div></div></blockquote><div><br></div><div>Nope, don't think you're missing anything - thanks for the pointer/explanation.<br><br>Reckon there's anything we can do to unify these bits of code (perhaps over all TagTypes)? (eg: there's a fair bit of overlap between the declaration portions of getOrCreateRecordFwdDecl and CreateEnumType. CreateType(const ObjCInterfaceType*, DIFile*) has some overlap, but it's a bit trickier - checking for implementation as well as definition, etc - dunno.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span class=""><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">   // If this is just a forward declaration, construct an appropriately<br>   // marked node and just return it.<br>-  if (!ED->getDefinition()) {<br>+  if (isImportedFromModule || !ED->getDefinition()) {<br>     llvm::DIScope *EDContext = getDeclContextDescriptor(ED);<br>     llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());<br>     unsigned Line = getLineNumber(ED->getLocation());<br>@@ -2081,9 +2108,8 @@ llvm::DIType *CGDebugInfo::getOrCreateTy<br>   if (auto *T = getTypeOrNull(Ty))<br>     return T;<br><br>-  // Otherwise create the type.<br>   llvm::DIType *Res = CreateTypeNode(Ty, Unit);<br>-  void *TyPtr = Ty.getAsOpaquePtr();<br>+  void* TyPtr = Ty.getAsOpaquePtr();<br><br>   // And update the type cache.<br>   TypeCache[TyPtr].reset(Res);<br>@@ -2115,6 +2141,19 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCI<br>   }<br> }<br><br>+llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) {<br>+  if (!DebugTypeExtRefs || !D || !D->isFromASTFile())<br></blockquote><div><br></div><div>Is a null Decl valid here? What's that for?</div></div></div></blockquote><div><br></div></span>Removed.<div><div class="h5"><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+    return nullptr;<br>+<br>+  llvm::DIModule *ModuleRef = nullptr;<br>+  auto *Reader = CGM.getContext().getExternalSource();<br>+  auto Idx = D->getOwningModuleID();<br>+  auto Info = Reader->getSourceDescriptor(Idx);<br>+  if (Info)<br>+    ModuleRef = getOrCreateModuleRef(*Info);<br>+  return ModuleRef;<br>+}<br>+<br> llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {<br>   // Handle qualifiers, which recursively handles what they refer to.<br>   if (Ty.hasLocalQualifiers())<br>@@ -2325,8 +2364,10 @@ void CGDebugInfo::collectFunctionDeclPro<br>         dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))<br>       FDContext = getOrCreateNameSpace(NSDecl);<br>     else if (const RecordDecl *RDecl =<br>-             dyn_cast_or_null<RecordDecl>(FD->getDeclContext()))<br>-      FDContext = getContextDescriptor(RDecl, TheCU);<br>+             dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) {<br>+      llvm::DIScope *Mod = getParentModuleOrNull(RDecl);<br>+      FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);<br>+    }<br>     // Collect template parameters.<br>     TParamsArray = CollectFunctionTemplateParams(FD, Unit);<br>   }<br>@@ -2374,7 +2415,9 @@ void CGDebugInfo::collectVarDeclProps(co<br>   // outside the class by putting it in the global scope.<br>   if (DC->isRecord())<br>     DC = CGM.getContext().getTranslationUnitDecl();<br>-  VDContext = getContextDescriptor(cast<Decl>(DC), TheCU);<br>+<br>+ llvm::DIScope *Mod = getParentModuleOrNull(VD);<br>+ VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);<br></blockquote><div><br>I'm not quite seeing why this (& the other two/three cases) aren't using the <span style="font-family:monospace">getDeclContextDescriptor helper you added? Could you explain it to me?</span></div></div></div></blockquote><div><br></div></div></div><div>They are either manually picking a DeclContext different than the one returned by Decl->GetDeclContext(), or they are using the Decl as its own DeclContext.</div><div><div class="h5"><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> }<br><br> llvm::DISubprogram *<br>@@ -3299,7 +3342,8 @@ void CGDebugInfo::EmitGlobalVariable(con<br> llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {<br>   if (!LexicalBlockStack.empty())<br>     return LexicalBlockStack.back();<br>-  return getContextDescriptor(D, TheCU);<br>+  llvm::DIScope *Mod = getParentModuleOrNull(D);<br>+  return getContextDescriptor(D, Mod ? Mod : TheCU);<br> }<br><br> void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {<br><br>Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=247432&r1=247431&r2=247432&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=247432&r1=247431&r2=247432&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)<br>+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Fri Sep 11 12:23:08 2015<br>@@ -397,6 +397,9 @@ private:<br>   llvm::DIModule *<br>   getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod);<br><br>+  /// DebugTypeExtRefs: If \p D originated in a clang module, return it.<br>+  llvm::DIModule *getParentModuleOrNull(const Decl *D);<br>+<br>   /// Get the type from the cache or create a new partial type if<br>   /// necessary.<br>   llvm::DICompositeType *getOrCreateLimitedType(const RecordType *Ty,<br><br>Added: cfe/trunk/test/Modules/ExtDebugInfo.cpp<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.cpp?rev=247432&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.cpp?rev=247432&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/Modules/ExtDebugInfo.cpp (added)<br>+++ cfe/trunk/test/Modules/ExtDebugInfo.cpp Fri Sep 11 12:23:08 2015<br>@@ -0,0 +1,69 @@<br>+// RUN: rm -rf %t<br>+// Test that only forward declarations are emitted for types dfined in modules.<br>+<br>+// Modules:<br>+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -g -dwarf-ext-refs -fmodules \<br>+// RUN:     -fmodule-format=obj -fimplicit-module-maps -DMODULES \<br>+// RUN:     -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll<br>+// RUN: cat %t-mod.ll |  FileCheck %s<br>+<br>+// PCH:<br>+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch -I%S/Inputs \<br>+// RUN:     -o %t.pch %S/Inputs/DebugCXX.h<br>+// RUN: %clang_cc1 -std=c++11 -g -dwarf-ext-refs -fmodule-format=obj \<br>+// RUN:     -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s<br>+// RUN: cat %t-pch.ll |  FileCheck %s<br>+<br>+#ifdef MODULES<br>+@import DebugCXX;<br>+#endif<br>+<br>+using DebugCXX::Struct;<br>+<br>+Struct s;<br>+DebugCXX::Enum e;<br>+DebugCXX::Template<long> implicitTemplate;<br>+DebugCXX::Template<int> explicitTemplate;<br>+DebugCXX::FloatInstatiation typedefTemplate;<br>+int Struct::static_member = -1;<br>+enum {<br>+  e3 = -1<br>+} conflicting_uid = e3;<br>+auto anon_enum = DebugCXX::e2;<br>+char _anchor = anon_enum + conflicting_uid;<br>+<br>+// CHECK: ![[NS:.*]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],<br>+// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX<br>+<br>+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct",<br>+// CHECK-SAME:             scope: ![[NS]],<br>+// CHECK-SAME:             flags: DIFlagFwdDecl,<br>+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX6StructE")<br>+<br>+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum",<br>+// CHECK-SAME:             scope: ![[NS]],<br>+// CHECK-SAME:             flags: DIFlagFwdDecl,<br>+// CHECK-SAME:             identifier:  "_ZTSN8DebugCXX4EnumE")<br>+<br>+// CHECK: !DICompositeType(tag: DW_TAG_class_type,<br>+<br>+// CHECK: !DICompositeType(tag: DW_TAG_class_type,<br>+// CHECK-SAME:             name: "Template<int, DebugCXX::traits<int> >",<br>+// CHECK-SAME:             scope: ![[NS]],<br>+// CHECK-SAME:             flags: DIFlagFwdDecl,<br>+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")<br>+<br>+// CHECK: !DICompositeType(tag: DW_TAG_class_type,<br>+// CHECK-SAME:             name: "Template<float, DebugCXX::traits<float> >",<br>+// CHECK-SAME:             scope: ![[NS]],<br>+// CHECK-SAME:             flags: DIFlagFwdDecl,<br>+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")<br>+<br>+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member",<br>+// CHECK-SAME:           scope: !"_ZTSN8DebugCXX6StructE"<br>+<br>+// CHECK: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: ![[ANON_ENUM:[0-9]+]]<br>+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[NS]],<br>+// CHECK-SAME:             line: 16<br>+<br>+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !"_ZTSN8DebugCXX6StructE", line: 21)<br><br>Added: cfe/trunk/test/Modules/ExtDebugInfo.m<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.m?rev=247432&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.m?rev=247432&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/Modules/ExtDebugInfo.m (added)<br>+++ cfe/trunk/test/Modules/ExtDebugInfo.m Fri Sep 11 12:23:08 2015<br>@@ -0,0 +1,29 @@<br>+// RUN: rm -rf %t<br>+// Test that only forward declarations are emitted for types dfined in modules.<br></blockquote><div><br></div><div>Typo "dfined".<br><br>I don't see where/how this test is testing for forward declarations - it doesn't seem to test for any declarations or definitions. (they could be emitted as either, or not emitted at all?)</div></div></div></blockquote><div><br></div></div></div>I made it stricter now.</div><div><br></div><div>thanks!</div><span class="HOEnZb"><font color="#888888"><div>adrian</div></font></span><div><div class="h5"><div><br><blockquote type="cite"><div><div class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+<br>+// Modules:<br>+// RUN: %clang_cc1 -x objective-c -g -dwarf-ext-refs -fmodules \<br>+// RUN:     -fmodule-format=obj -fimplicit-module-maps -DMODULES \<br>+// RUN:     -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll<br>+// RUN: cat %t-mod.ll |  FileCheck %s<br>+<br>+// PCH:<br>+// RUN: %clang_cc1 -x objective-c -fmodule-format=obj -emit-pch -I%S/Inputs \<br>+// RUN:     -o %t.pch %S/Inputs/DebugObjC.h<br>+// RUN: %clang_cc1 -x objective-c -g -dwarf-ext-refs -fmodule-format=obj \<br>+// RUN:     -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s<br>+// RUN: cat %t-pch.ll |  FileCheck %s<br>+<br>+#ifdef MODULES<br>+@import DebugObjC;<br>+#endif<br>+<br>+int foo(ObjCClass *c) {<br>+  [c instanceMethodWithInt: 0];<br>+  return [c property];<br>+}<br>+<br>+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,<br>+// CHECK-SAME:             scope: ![[MOD:[0-9]+]],<br>+// CHECK-SAME:             flags: DIFlagFwdDecl)<br>+// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugObjC </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a></blockquote></div></div></blockquote></div><br></div></div></div></blockquote></div><br></div></div>