Index: cfe/trunk/lib/AST/DeclPrinter.cpp =================================================================== --- cfe/trunk/lib/AST/DeclPrinter.cpp +++ cfe/trunk/lib/AST/DeclPrinter.cpp @@ -128,9 +128,7 @@ // FIXME: This should be on the Type class! QualType BaseType = T; while (!BaseType->isSpecifierType()) { - if (isa(BaseType)) - break; - else if (const PointerType* PTy = BaseType->getAs()) + if (const PointerType *PTy = BaseType->getAs()) BaseType = PTy->getPointeeType(); else if (const BlockPointerType *BPy = BaseType->getAs()) BaseType = BPy->getPointeeType(); @@ -144,8 +142,11 @@ BaseType = RTy->getPointeeType(); else if (const AutoType *ATy = BaseType->getAs()) BaseType = ATy->getDeducedType(); + else if (const ParenType *PTy = BaseType->getAs()) + BaseType = PTy->desugar(); else - llvm_unreachable("Unknown declarator!"); + // This must be a syntax error. + break; } return BaseType; } Index: cfe/trunk/test/Sema/ast-print.c =================================================================== --- cfe/trunk/test/Sema/ast-print.c +++ cfe/trunk/test/Sema/ast-print.c @@ -15,6 +15,10 @@ }; }; +// This used to crash clang. +struct { +}(s1); + int foo(const struct blah *b) { // CHECK: return b->b; return b->b; Index: cfe/trunk/test/SemaCXX/ast-print-crash.cpp =================================================================== --- cfe/trunk/test/SemaCXX/ast-print-crash.cpp +++ cfe/trunk/test/SemaCXX/ast-print-crash.cpp @@ -0,0 +1,12 @@ +// RUN: not %clang_cc1 -triple %ms_abi_triple -ast-print %s -std=gnu++11 \ +// RUN: | FileCheck %s + +// The test compiles a file with a syntax error which used to cause a crash with +// -ast-print. Compilation fails due to the syntax error, but compiler should +// not crash and print out whatever it manager to parse. + +// CHECK: struct { +// CHECK-NEXT: } dont_crash_on_syntax_error; +// CHECK-NEXT: decltype(nullptr) p; +struct { +} dont_crash_on_syntax_error /* missing ; */ decltype(nullptr) p;