diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1541,7 +1541,64 @@ OS << " &&"; break; } - // FIXME: Exception specification. + + switch (EPI.ExceptionSpec.Type) { + case EST_None: + break; + case EST_DynamicNone: + OS << " exceptionspec_dynamic_none"; + break; + case EST_Dynamic: + OS << " exceptionspec_dynamic"; + break; + case EST_MSAny: + OS << " exceptionspec_ms_any"; + break; + case EST_NoThrow: + OS << " exceptionspec_nothrow"; + break; + case EST_BasicNoexcept: + OS << " exceptionspec_basic_noexcept"; + break; + case EST_DependentNoexcept: + OS << " exceptionspec_dependent_noexcept"; + break; + case EST_NoexceptFalse: + OS << " exceptionspec_noexcept_false"; + break; + case EST_NoexceptTrue: + OS << " exceptionspec_noexcept_true"; + break; + case EST_Unevaluated: + OS << " exceptionspec_unevaluated"; + break; + case EST_Uninstantiated: + OS << " exceptionspec_uninstantiated"; + break; + case EST_Unparsed: + OS << " exceptionspec_unparsed"; + break; + } + if (!EPI.ExceptionSpec.Exceptions.empty()) { + AddChild([=] { + OS << "Exceptions:"; + for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N; + ++I) { + if (I) + OS << ","; + dumpType(EPI.ExceptionSpec.Exceptions[I]); + } + }); + } + if (EPI.ExceptionSpec.NoexceptExpr) { + AddChild([=] { + OS << "NoexceptExpr: "; + Visit(EPI.ExceptionSpec.NoexceptExpr); + }); + } + dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl"); + dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate"); + // FIXME: Consumed parameters. VisitFunctionType(T); } diff --git a/clang/test/AST/ast-dump-functionprototype.cpp b/clang/test/AST/ast-dump-functionprototype.cpp new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-functionprototype.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -Wno-dynamic-exception-spec -ast-dump %s | FileCheck -strict-whitespace %s + +struct A {}; +struct B {}; + +typedef void (type1)() noexcept(10 > 5); + +// CHECK: TypedefDecl {{.*}} type1 'void () noexcept(10 > 5)':'void () noexcept(10 > 5)' +// CHECK-NEXT: `-ParenType {{.*}} +// CHECK-NEXT: `-FunctionProtoType {{.*}} 'void () noexcept(10 > 5)' exceptionspec_noexcept_true cdecl +// CHECK-NEXT: |-NoexceptExpr: ConstantExpr {{.*}} 'bool' +// CHECK-NEXT: | `-value: Int 1 +// CHECK-NEXT: `-BuiltinType {{.*}} 'void' + +typedef void (type2)() throw(A, B); + +// CHECK: TypedefDecl {{.*}} type2 'void () throw(A, B)':'void () throw(A, B)' +// CHECK-NEXT: `-ParenType {{.*}} +// CHECK-NEXT: `-FunctionProtoType {{.*}} 'void () throw(A, B)' exceptionspec_dynamic cdecl +// CHECK-NEXT: |-Exceptions: 'A':'A', 'B':'B' +// CHECK-NEXT: `-BuiltinType {{.*}} 'void' +