Pull in r200797 from upstream clang trunk (by Adrian Prantl): Debug info: fix a crasher when when emitting debug info for not-yet-completed templated types. getTypeSize() needs a complete type. rdar://problem/15931354 Introduced here: http://svnweb.freebsd.org/changeset/base/271282 Index: tools/clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2251,9 +2251,10 @@ llvm::DICompositeType CGDebugInfo::CreateLimitedTy if (T && (!T.isForwardDecl() || !RD->getDefinition())) return T; - // If this is just a forward declaration, construct an appropriately - // marked node and just return it. - if (!RD->getDefinition()) + // If this is just a forward or incomplete declaration, construct an + // appropriately marked node and just return it. + const RecordDecl *D = RD->getDefinition(); + if (!D || !D->isCompleteDefinition()) return getOrCreateRecordFwdDecl(Ty, RDContext); uint64_t Size = CGM.getContext().getTypeSize(Ty); Index: tools/clang/test/CodeGenCXX/debug-info-template-fwd.cpp =================================================================== --- tools/clang/test/CodeGenCXX/debug-info-template-fwd.cpp +++ tools/clang/test/CodeGenCXX/debug-info-template-fwd.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -g -emit-llvm -o - | FileCheck %s +// This test is for a crash when emitting debug info for not-yet-completed types. +// Test that we don't actually emit a forward decl for the offending class: +// CHECK: [ DW_TAG_class_type ] [Derived] {{.*}} [def] +// rdar://problem/15931354 +typedef const struct __CFString * CFStringRef; +template class Returner {}; +typedef const __CFString String; + +template class Derived; + +template +class Base +{ + static Derived* create(); +}; + +template +class Derived : public Base { +public: + static void foo(); +}; + +class Foo +{ + Foo(); + static Returner > all(); +}; + +Foo::Foo(){} + +Returner > Foo::all() +{ + Derived::foo(); + return Foo::all(); +}