Comes back from cxx_init, below init_asm_output prepares the file for outputting assemble code.
lang_dependent_init (continue)
4535 init_asm_output (name);
4536
4537 /* These create various _DECL nodes, so need to be called after the
4538 front end is initialized. */
4539 init_eh ();
At configuring gcc, we can use --enable-sjlj-exceptions to force using C library setjmp and longjmp in exception handling, which is a quite out-of date facility. Now new chip usually gives consideration upon exception handling, for example offers special register. So, if it doesn’t enforce using setjmp/longjmp, the compiler would judge if it needs use setjmp/longjmp.
146 #ifndef MUST_USE_SJLJ_EXCEPTIONS in except.h
147 # if !(defined (EH_RETURN_DATA_REGNO) /
148 && (defined (IA64_UNWIND_INFO) /
149 || (DWARF2_UNWIND_INFO /
150 && (defined (EH_RETURN_HANDLER_RTX) /
151 || defined (HAVE_eh_return)))))
152 # define MUST_USE_SJLJ_EXCEPTIONS 1
153 # else
154 # define MUST_USE_SJLJ_EXCEPTIONS 0
155 # endif
156 #endif
Above, EH_RETURN_DATA_REGNO(N) is a C expression whose value is the Nth register number used for data by exception handlers, or `INVALID_REGNUM' if fewer than N registers are usable. For x86, it is registers of NO. 0~1 (i.e, AX, DX). And IA64_UNWIND_INFO is only defined for ia64 chip.
282 #if !defined (DWARF2_UNWIND_INFO) && defined (INCOMING_RETURN_ADDR_RTX)
283 #define DWARF2_UNWIND_INFO 1
284 #endif
INCOMING_RETURN_ADDR_RTX is a C expression whose value is RTL representing the location of the incoming return address at the beginning of any function, before the prologue. For x86, this location is on stack, the macro is defined. And EH_RETURN_HANDLER_RTX, if defined, is a C expression whose value is RTL representing a location in which to store the address of an exception handler to which we should return. x86 doesn’t define this macro, but defines HAVE_eh_return at configuration stage.
So to x86, MUST_USE_SJLJ_EXCEPTIONS is 0, means using setjmp/longjmp is not must.
158 #ifdef CONFIG_SJLJ_EXCEPTIONS in except.h
159 # if CONFIG_SJLJ_EXCEPTIONS == 1
160 # define USING_SJLJ_EXCEPTIONS 1
161 # endif
162 # if CONFIG_SJLJ_EXCEPTIONS == 0
163 # define USING_SJLJ_EXCEPTIONS 0
164 # ifndef EH_RETURN_DATA_REGNO
165 #error "EH_RETURN_DATA_REGNO required"
166 # endif
167 # if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return)
168 #error "EH_RETURN_HANDLER_RTX or eh_return required"
169 # endif
170 # if !defined(DWARF2_UNWIND_INFO) && !defined(IA64_UNWIND_INFO)
171 #error "{DWARF2,IA64}_UNWIND_INFO required"
172 # endif
173 # endif
174 #else
175 # define USING_SJLJ_EXCEPTIONS MUST_USE_SJLJ_EXCEPTIONS
176 #endif
Macro CONFIG_SJLJ_EXCEPTIONS is set by configuration option --enable-sjlj-exceptions (or --disable-sjlj-exceptions). When inhibits using setjmp/longjmp, the compiler needs to check if it is feasible. Here, USING_SJLJ_EXCEPTIONS is defined by MUST_USE_SJLJ_EXCEPTIONS, both 0! Then below init_eh almost has nothing to do. The function majorly creates an important data structure SjLj_Function_Context for the mechanism using setjmp/longjmp. This structure at time of exception handling would be allocated upon stack, and in its definition, can see filed for maintainence -- prev. So the front-end needs know the definition for this maintanence.
54 struct SjLj_Function_Context in unwind-sjlj.c
55 {
56 /* This is the chain through all registered contexts. It is
57 filled in by _Unwind_SjLj_Register. */
58 struct SjLj_Function_Context *prev;
59
60 /* This is assigned in by the target function before every call
61 to the index of the call site in the lsda. It is assigned by
62 the personality routine to the landing pad index. */
63 int call_site;
64
65 /* This is how data is returned from the personality routine to
66 the target function's handler. */
67 _Unwind_Word data[4];
68
69 /* These are filled in once by the target function before any
70 exceptions are expected to be handled. */
71 _Unwind_Personality_Fn personality;
72 void *lsda;
73
74 #ifdef DONT_USE_BUILTIN_SETJMP
75 /* We don't know what sort of alignment requirements the system
76 jmp_buf has. We over estimated in except.c, and now we have
77 to match that here just in case the system *didn't* have more
78 restrictive requirements. */
79 jmp_buf jbuf __attribute__((aligned));
80 #else
81 void *jbuf[];
82 #endif
83 };
It is excusable, because this context is passed to setjmp and longjmp (field jbuf). But in the other mechanism, every context is isolated, they don’t need know each other, and the processing and maintanence is provided by the runtime. No extra operation is required from the front-end. So no need tell the front-end about it.
366 void
367 init_eh (void) in except.c
368 {
369 if (! flag_exceptions)
370 return;
371
372 type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
373
374 /* Create the SjLj_Function_Context structure. This should match
375 the definition in unwind-sjlj.c. */
376 if (USING_SJLJ_EXCEPTIONS)
377 {
...
455 }
456 }
Regular it defines a group of exceptions, with base and serval derived classes. And at exception handling, there are usually a list of catch statements to filter the exception type to select out the matching handler. So compiler would create tinfo object for exception class automatically. But above, we have seen that if the class doesn’t define virtual functions, in its node there is no place to hold the tinfo object. As resolution, the front-end constructs type_to_runtime_map to bind exception classes with their tinfo objects.