<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 11, 2015, at 8:27 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="">dblaikie@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><br class="Apple-interchange-newline"><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">On Fri, Sep 11, 2015 at 8:18 AM, Adrian Prantl<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:aprantl@apple.com" target="_blank" class="">aprantl@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><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;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Sep 10, 2015, at 6:56 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>> wrote:</div><br class=""><div class=""><br class=""><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;" class=""><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 Thu, Sep 10, 2015 at 6:40 PM, David Blaikie<span class=""> </span><span dir="ltr" class=""><<a href="mailto:dblaikie@gmail.com" target="_blank" class="">dblaikie@gmail.com</a>></span><span class=""> </span>wrote:<br class=""><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;"><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote"><span class="">On Thu, Sep 10, 2015 at 6:03 PM, Adrian Prantl via cfe-commits<span class=""> </span><span dir="ltr" class=""><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a>></span><span class=""> </span>wrote:<br class=""><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 class="">Date: Thu Sep 10 20:03:26 2015<br class="">New Revision: 247369<br class=""><br class="">URL:<span class=""> </span><a href="http://llvm.org/viewvc/llvm-project?rev=247369&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=247369&view=rev</a><br class="">Log:<br class="">Module Debugging: Emit forward declarations for types that are defined in<br class="">clang modules, if -dwarf-ext-refs (DebugTypesExtRefs) is specified.<br class=""></blockquote></span><div class=""><br class="">This change seems to have a lot more code in it than I was expecting... <br class=""><br class="">I was rather expecting something a lot like the flimit-debug-info support. Specifically, I would've expected one more conditional added to CGDebugInfo::shouldOmitDefinition.<br class=""><br class="">Why the extra complexity?<br class=""><br class="">I guess part of it is to be able to omit definitions of things other than record types - is there much value in that? (especially typedefs - it seems like a typedef is too small to benefit from a declaration (even if we could emit one)?)<br class=""></div></div></div></div></blockquote></div></div></blockquote><div class=""><br class=""></div></span><div class="">The typedef itself is not interesting, but it can be used to anchor template instantiations like std::string. The contract between the debug info in the module and the debug info referencing the module is that all explicit template specializations<span class="Apple-converted-space"> </span></div></div></div></blockquote><div class=""><br class="">This I get ^ (though does that case need any special handling, or will the isFromASTFile return true for the location of the explicit specialization declaration/definition?)<br class=""> </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;"><div style="word-wrap: break-word;" class=""><div class=""><div class="">and template instantiations referenced used in a typedef can be expected to exist in the module.</div></div></div></blockquote><div class=""><br class="">This I do not get & would imagine it could cause substantial size increase... <br class=""><br class="">Might be worth splitting out that change to look at it more carefully. I'd love to see numbers here.<br class=""></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;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class=""><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 class="">Also, we could possibly solve both the problem of "don't emit definitions for module things when compiling the main source file" and "don't emit definitions for module things defined in other modules" with the same tool. If there's a way to say "is this in a foreign AST file" then testing for that in CGDebugInfo::shouldOmitDefinition would solve both problems, I think (conditionalized on the appropriate flags, either dwarf-ext-refs or "I'm building a module here”).<br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">I believe that this is a good point. Really, getExtRefOrNull is a separate function mostly for evolutionary reasons — it used to do different things like mangling names of ObjC types etc. I will see if I can merge the existing functionality into shouldOmitDefinition().</div></div></div></blockquote><div class=""><br class=""></div><div class="">From a review perspective it might be easier to revert this & commit a new patch - I haven't reviewed all these changes in detail because they just seemed more complex than necessary, but if you're going to evolve it from here I'll need to dig into the current implementation/be more careful about checking that future changes remove the complexity along with whatever they add.<br class=""><br class=""></div></div></div></blockquote><div><br class=""></div><div>I just did this in r24743[12].</div><div><br class=""></div><div>-- adrian</div><br class=""><blockquote type="cite" class=""><div class=""><div class="gmail_quote" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="">- Dave</div><div class=""> </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;"><div style="word-wrap: break-word;" class=""><div class=""><span class="HOEnZb"><font color="#888888" class=""><div class=""><br class=""></div>-- adrian</font></span><div class=""><div class="h5"><br class=""><blockquote type="cite" class=""><div class=""><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 class=""> </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;"><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><div class=""><div class=""><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 class="">Added:<br class="">   <span class=""> </span>cfe/trunk/test/Modules/ExtDebugInfo.cpp<br class="">   <span class=""> </span>cfe/trunk/test/Modules/ExtDebugInfo.m<br class="">Modified:<br class="">   <span class=""> </span>cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br class="">   <span class=""> </span>cfe/trunk/lib/CodeGen/CGDebugInfo.h<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br class="">URL:<span class=""> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=247369&r1=247368&r2=247369&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=247369&r1=247368&r2=247369&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Sep 10 20:03:26 2015<br class="">@@ -148,7 +148,9 @@ void CGDebugInfo::setLocation(SourceLoca<br class=""> }<br class=""><br class=""> llvm::DIScope *CGDebugInfo::getDeclContextDescriptor(const Decl *D) {<br class="">-  return getContextDescriptor(cast<Decl>(D->getDeclContext()), TheCU);<br class="">+  llvm::DIScope *Mod = getParentModuleOrNull(D);<br class="">+  return getContextDescriptor(cast<Decl>(D->getDeclContext()),<br class="">+                              Mod ? Mod : TheCU);<br class=""> }<br class=""><br class=""> llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,<br class="">@@ -1448,6 +1450,9 @@ void CGDebugInfo::completeRequiredType(c<br class="">     if (CXXDecl->isDynamicClass())<br class="">       return;<br class=""><br class="">+  if (DebugTypeExtRefs && RD->isFromASTFile())<br class="">+    return;<br class="">+<br class="">   QualType Ty = CGM.getContext().getRecordType(RD);<br class="">   llvm::DIType *T = getTypeOrNull(Ty);<br class="">   if (T && T->isForwardDecl())<br class="">@@ -1669,9 +1674,9 @@ CGDebugInfo::getOrCreateModuleRef(Extern<br class="">       TheCU->getSourceLanguage(), internString(Mod.ModuleName),<br class="">       internString(Mod.Path), TheCU->getProducer(), true, StringRef(), 0,<br class="">       internString(Mod.ASTFile), llvm::DIBuilder::FullDebug, Mod.Signature);<br class="">-  llvm::DIModule *M =<br class="">-      DIB.createModule(CU, Mod.ModuleName, ConfigMacros, internString(Mod.Path),<br class="">-                       internString(CGM.getHeaderSearchOpts().Sysroot));<br class="">+  llvm::DIModule *M = DIB.createModule(<br class="">+      CU, Mod.ModuleName, ConfigMacros, internString(Mod.Path),<br class="">+      internString(CGM.getHeaderSearchOpts().Sysroot));<br class="">   DIB.finalize();<br class="">   ModRef.reset(M);<br class="">   return M;<br class="">@@ -2081,9 +2086,16 @@ llvm::DIType *CGDebugInfo::getOrCreateTy<br class="">   if (auto *T = getTypeOrNull(Ty))<br class="">     return T;<br class=""><br class="">+  llvm::DIType *Res = nullptr;<br class="">+  if (DebugTypeExtRefs)<br class="">+    // Make a forward declaration of an external type.<br class="">+    Res = getTypeExtRefOrNull(Ty, Unit);<br class="">+<br class="">   // Otherwise create the type.<br class="">-  llvm::DIType *Res = CreateTypeNode(Ty, Unit);<br class="">-  void *TyPtr = Ty.getAsOpaquePtr();<br class="">+  if (!Res)<br class="">+    Res = CreateTypeNode(Ty, Unit);<br class="">+<br class="">+  void* TyPtr = Ty.getAsOpaquePtr();<br class=""><br class="">   // And update the type cache.<br class="">   TypeCache[TyPtr].reset(Res);<br class="">@@ -2115,6 +2127,123 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCI<br class="">   }<br class=""> }<br class=""><br class="">+llvm::DIModule *CGDebugInfo::getParentModuleOrNull(const Decl *D) {<br class="">+  if (!DebugTypeExtRefs || !D || !D->isFromASTFile())<br class="">+    return nullptr;<br class="">+<br class="">+  llvm::DIModule *ModuleRef = nullptr;<br class="">+  auto *Reader = CGM.getContext().getExternalSource();<br class="">+  auto Idx = D->getOwningModuleID();<br class="">+  auto Info = Reader->getSourceDescriptor(Idx);<br class="">+  if (Info)<br class="">+    ModuleRef = getOrCreateModuleRef(*Info);<br class="">+  return ModuleRef;<br class="">+}<br class="">+<br class="">+llvm::DIType *CGDebugInfo::getTypeExtRefOrNull(QualType Ty, llvm::DIFile *F,<br class="">+                                               bool Anchored) {<br class="">+  assert(DebugTypeExtRefs && "module debugging only");<br class="">+  Decl *TyDecl = nullptr;<br class="">+  StringRef Name;<br class="">+  SmallString<256> UID;<br class="">+  unsigned Tag = 0;<br class="">+<br class="">+  // Handle all types that have a declaration.<br class="">+  switch (Ty->getTypeClass()) {<br class="">+  case Type::Typedef: {<br class="">+    TyDecl = cast<TypedefType>(Ty)->getDecl();<br class="">+    if (!TyDecl->isFromASTFile())<br class="">+      return nullptr;<br class="">+<br class="">+    // A typedef will anchor a type in the module.<br class="">+    if (auto *TD = dyn_cast<TypedefDecl>(TyDecl)) {<br class="">+      // This is a working around the fact that LLVM does not allow<br class="">+      // typedefs to be forward declarations.<br class="">+      QualType Ty = TD->getUnderlyingType();<br class="">+      Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());<br class="">+      if (auto *AnchoredTy = getTypeExtRefOrNull(Ty, F, /*Anchored=*/true)) {<br class="">+        TypeCache[Ty.getAsOpaquePtr()].reset(AnchoredTy);<br class="">+        SourceLocation Loc = TD->getLocation();<br class="">+        return DBuilder.createTypedef(AnchoredTy, TD->getName(),<br class="">+                                      getOrCreateFile(Loc), getLineNumber(Loc),<br class="">+                                      getDeclContextDescriptor(TD));<br class="">+      }<br class="">+    }<br class="">+    break;<br class="">+  }<br class="">+<br class="">+  case Type::Record: {<br class="">+    TyDecl = cast<RecordType>(Ty)->getDecl();<br class="">+    if (!TyDecl->isFromASTFile())<br class="">+      return nullptr;<br class="">+<br class="">+    if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TyDecl))<br class="">+      if (!CTSD->isExplicitInstantiationOrSpecialization() && !Anchored)<br class="">+        // We may not assume that this type made it into the module.<br class="">+        return nullptr;<br class="">+    // C++ classes and template instantiations.<br class="">+    if (auto *RD = dyn_cast<CXXRecordDecl>(TyDecl)) {<br class="">+      if (!RD->getDefinition())<br class="">+        return nullptr;<br class="">+      Tag = getTagForRecord(RD);<br class="">+      UID =<br class="">+          getUniqueTagTypeName(cast<TagType>(RD->getTypeForDecl()), CGM, TheCU);<br class="">+      Name = getClassName(RD);<br class="">+    } else if (auto *RD = dyn_cast<RecordDecl>(TyDecl)) {<br class="">+      // C-style structs.<br class="">+      if (!RD->getDefinition())<br class="">+        return nullptr;<br class="">+      Tag = getTagForRecord(RD);<br class="">+      Name = getClassName(RD);<br class="">+    }<br class="">+    break;<br class="">+  }<br class="">+<br class="">+  case Type::Enum: {<br class="">+    TyDecl = cast<EnumType>(Ty)->getDecl();<br class="">+    if (!TyDecl->isFromASTFile())<br class="">+      return nullptr;<br class="">+<br class="">+    if (auto *ED = dyn_cast<EnumDecl>(TyDecl)) {<br class="">+      if (!ED->getDefinition())<br class="">+        return nullptr;<br class="">+      Tag = llvm::dwarf::DW_TAG_enumeration_type;<br class="">+      if ((TheCU->getSourceLanguage() == llvm::dwarf::DW_LANG_C_plus_plus) ||<br class="">+          (TheCU->getSourceLanguage() == llvm::dwarf::DW_LANG_ObjC_plus_plus)) {<br class="">+        UID = getUniqueTagTypeName(cast<TagType>(ED->getTypeForDecl()), CGM,<br class="">+                                   TheCU);<br class="">+        Name = ED->getName();<br class="">+      }<br class="">+    }<br class="">+    break;<br class="">+  }<br class="">+<br class="">+  case Type::ObjCInterface: {<br class="">+    TyDecl = cast<ObjCInterfaceType>(Ty)->getDecl();<br class="">+    if (!TyDecl->isFromASTFile())<br class="">+      return nullptr;<br class="">+<br class="">+    if (auto *ID = dyn_cast<ObjCInterfaceDecl>(TyDecl)) {<br class="">+      if (!ID->getDefinition())<br class="">+        return nullptr;<br class="">+      Tag = llvm::dwarf::DW_TAG_structure_type;<br class="">+      Name = ID->getName();<br class="">+    }<br class="">+    break;<br class="">+  }<br class="">+<br class="">+  default:<br class="">+    return nullptr;<br class="">+  }<br class="">+<br class="">+  if (Tag && !Name.empty()) {<br class="">+    assert(TyDecl);<br class="">+    auto *Ctx = getDeclContextDescriptor(TyDecl);<br class="">+    return DBuilder.createForwardDecl(Tag, Name, Ctx, F, 0, 0, 0, 0, UID);<br class="">+  } else<br class="">+    return nullptr;<br class="">+}<br class="">+<br class=""> llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {<br class="">   // Handle qualifiers, which recursively handles what they refer to.<br class="">   if (Ty.hasLocalQualifiers())<br class="">@@ -2325,8 +2454,10 @@ void CGDebugInfo::collectFunctionDeclPro<br class="">         dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))<br class="">       FDContext = getOrCreateNameSpace(NSDecl);<br class="">     else if (const RecordDecl *RDecl =<br class="">-             dyn_cast_or_null<RecordDecl>(FD->getDeclContext()))<br class="">-      FDContext = getContextDescriptor(RDecl, TheCU);<br class="">+             dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) {<br class="">+      llvm::DIScope *Mod = getParentModuleOrNull(RDecl);<br class="">+      FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU);<br class="">+    }<br class="">     // Collect template parameters.<br class="">     TParamsArray = CollectFunctionTemplateParams(FD, Unit);<br class="">   }<br class="">@@ -2374,7 +2505,9 @@ void CGDebugInfo::collectVarDeclProps(co<br class="">   // outside the class by putting it in the global scope.<br class="">   if (DC->isRecord())<br class="">     DC = CGM.getContext().getTranslationUnitDecl();<br class="">-  VDContext = getContextDescriptor(cast<Decl>(DC), TheCU);<br class="">+<br class="">+ llvm::DIScope *Mod = getParentModuleOrNull(VD);<br class="">+ VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);<br class=""> }<br class=""><br class=""> llvm::DISubprogram *<br class="">@@ -3299,7 +3432,8 @@ void CGDebugInfo::EmitGlobalVariable(con<br class=""> llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {<br class="">   if (!LexicalBlockStack.empty())<br class="">     return LexicalBlockStack.back();<br class="">-  return getContextDescriptor(D, TheCU);<br class="">+  llvm::DIScope *Mod = getParentModuleOrNull(D);<br class="">+  return getContextDescriptor(D, Mod ? Mod : TheCU);<br class=""> }<br class=""><br class=""> void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h<br class="">URL:<span class=""> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=247369&r1=247368&r2=247369&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=247369&r1=247368&r2=247369&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Thu Sep 10 20:03:26 2015<br class="">@@ -397,6 +397,15 @@ private:<br class="">   llvm::DIModule *<br class="">   getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod);<br class=""><br class="">+  /// DebugTypeExtRefs: If \p D originated in a clang module, return it.<br class="">+  llvm::DIModule *getParentModuleOrNull(const Decl *D);<br class="">+<br class="">+  /// Return a forward declaration of an external type, if this type<br class="">+  /// came from a clang module.  If \p Anchored is true, template<br class="">+  /// types will be assumed to have been instantiated in the module.<br class="">+  llvm::DIType *getTypeExtRefOrNull(QualType Ty, llvm::DIFile *F,<br class="">+                                    bool Anchored = false);<br class="">+<br class="">   /// Get the type from the cache or create a new partial type if<br class="">   /// necessary.<br class="">   llvm::DICompositeType *getOrCreateLimitedType(const RecordType *Ty,<br class=""><br class="">Added: cfe/trunk/test/Modules/ExtDebugInfo.cpp<br class="">URL:<span class=""> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.cpp?rev=247369&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.cpp?rev=247369&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/Modules/ExtDebugInfo.cpp (added)<br class="">+++ cfe/trunk/test/Modules/ExtDebugInfo.cpp Thu Sep 10 20:03:26 2015<br class="">@@ -0,0 +1,74 @@<br class="">+// RUN: rm -rf %t<br class="">+// Test that only forward declarations are emitted for types dfined in modules.<br class="">+<br class="">+// Modules:<br class="">+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -g -dwarf-ext-refs -fmodules \<br class="">+// RUN:     -fmodule-format=obj -fimplicit-module-maps -DMODULES \<br class="">+// RUN:     -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll<br class="">+// RUN: cat %t-mod.ll |  FileCheck %s<br class="">+<br class="">+// PCH:<br class="">+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodule-format=obj -emit-pch -I%S/Inputs \<br class="">+// RUN:     -o %t.pch %S/Inputs/DebugCXX.h<br class="">+// RUN: %clang_cc1 -std=c++11 -g -dwarf-ext-refs -fmodule-format=obj \<br class="">+// RUN:     -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s<br class="">+// RUN: cat %t-pch.ll |  FileCheck %s<br class="">+<br class="">+#ifdef MODULES<br class="">+@import DebugCXX;<br class="">+#endif<br class="">+<br class="">+using DebugCXX::Struct;<br class="">+<br class="">+Struct s;<br class="">+DebugCXX::Enum e;<br class="">+DebugCXX::Template<long> implicitTemplate;<br class="">+DebugCXX::Template<int> explicitTemplate;<br class="">+DebugCXX::FloatInstatiation typedefTemplate;<br class="">+int Struct::static_member = -1;<br class="">+enum {<br class="">+  e3 = -1<br class="">+} conflicting_uid = e3;<br class="">+auto anon_enum = DebugCXX::e2;<br class="">+char _anchor = anon_enum + conflicting_uid;<br class="">+<br class="">+// CHECK: ![[ANON_ENUM:[0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type<br class="">+// CHECK-SAME:             scope: ![[MOD:[0-9]+]],<br class="">+// CHECK-SAME: {{.*}}line: 16, {{.*}}, elements: ![[EE:[0-9]+]])<br class="">+<br class="">+// CHECK: ![[NS:.*]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],<br class="">+// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX<br class="">+<br class="">+// CHECK: ![[EE]] = !{![[E2:[0-9]+]]}<br class="">+// CHECK: ![[E2]] = !DIEnumerator(name: "e2", value: 50)<br class="">+<br class="">+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct",<br class="">+// CHECK-SAME:             scope: ![[NS]],<br class="">+// CHECK-SAME:             flags: DIFlagFwdDecl,<br class="">+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX6StructE")<br class="">+<br class="">+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum",<br class="">+// CHECK-SAME:             scope: ![[NS]],<br class="">+// CHECK-SAME:             flags: DIFlagFwdDecl,<br class="">+// CHECK-SAME:             identifier:  "_ZTSN8DebugCXX4EnumE")<br class="">+<br class="">+// CHECK: !DICompositeType(tag: DW_TAG_class_type,<br class="">+<br class="">+// CHECK: !DICompositeType(tag: DW_TAG_class_type,<br class="">+// CHECK-SAME:             name: "Template<int, DebugCXX::traits<int> >",<br class="">+// CHECK-SAME:             scope: ![[NS]],<br class="">+// CHECK-SAME:             flags: DIFlagFwdDecl,<br class="">+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")<br class="">+<br class="">+// CHECK: !DICompositeType(tag: DW_TAG_class_type,<br class="">+// CHECK-SAME:             name: "Template<float, DebugCXX::traits<float> >",<br class="">+// CHECK-SAME:             scope: ![[NS]],<br class="">+// CHECK-SAME:             flags: DIFlagFwdDecl,<br class="">+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")<br class="">+<br class="">+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_member",<br class="">+// CHECK-SAME:           scope: !"_ZTSN8DebugCXX6StructE"<br class="">+<br class="">+// CHECK: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: ![[ANON_ENUM]]<br class="">+<br class="">+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !"_ZTSN8DebugCXX6StructE", line: 21)<br class=""><br class="">Added: cfe/trunk/test/Modules/ExtDebugInfo.m<br class="">URL:<span class=""> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.m?rev=247369&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ExtDebugInfo.m?rev=247369&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/Modules/ExtDebugInfo.m (added)<br class="">+++ cfe/trunk/test/Modules/ExtDebugInfo.m Thu Sep 10 20:03:26 2015<br class="">@@ -0,0 +1,29 @@<br class="">+// RUN: rm -rf %t<br class="">+// Test that only forward declarations are emitted for types dfined in modules.<br class="">+<br class="">+// Modules:<br class="">+// RUN: %clang_cc1 -x objective-c -g -dwarf-ext-refs -fmodules \<br class="">+// RUN:     -fmodule-format=obj -fimplicit-module-maps -DMODULES \<br class="">+// RUN:     -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t-mod.ll<br class="">+// RUN: cat %t-mod.ll |  FileCheck %s<br class="">+<br class="">+// PCH:<br class="">+// RUN: %clang_cc1 -x objective-c -fmodule-format=obj -emit-pch -I%S/Inputs \<br class="">+// RUN:     -o %t.pch %S/Inputs/DebugObjC.h<br class="">+// RUN: %clang_cc1 -x objective-c -g -dwarf-ext-refs -fmodule-format=obj \<br class="">+// RUN:     -include-pch %t.pch %s -emit-llvm -o %t-pch.ll %s<br class="">+// RUN: cat %t-pch.ll |  FileCheck %s<br class="">+<br class="">+#ifdef MODULES<br class="">+@import DebugObjC;<br class="">+#endif<br class="">+<br class="">+int foo(ObjCClass *c) {<br class="">+  [c instanceMethodWithInt: 0];<br class="">+  return [c property];<br class="">+}<br class="">+<br class="">+// CHECK: !DICompositeType(tag: DW_TAG_structure_type,<br class="">+// CHECK-SAME:             scope: ![[MOD:[0-9]+]],<br class="">+// CHECK-SAME:             flags: DIFlagFwdDecl)<br class="">+// CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugObjC<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" target="_blank" class="">cfe-commits@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a></blockquote></div></div></div></div></div></blockquote></div></div></blockquote></div></div></div></div></blockquote></div></div></blockquote></div><br class=""></body></html>