1 // $Id: modifier.cpp,v 1.33 2004/03/25 13:32:28 ericb Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others.  All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 
10 #include "platform.h"
11 #include "semantic.h"
12 #include "option.h"
13 #include "javasym.h"
14 #include "stream.h"
15 
16 #ifdef HAVE_JIKES_NAMESPACE
17 namespace Jikes { // Open namespace Jikes block
18 #endif
19 
20 
21 //
22 // Process modifiers, returning the AccessFlags they represent.
23 //
24 // Diagnostics are emitted in the following cases:
25 // . Invalid modifiers based on context.
26 // . Duplicated mutually exclusive modifiers (public, protected, private).
27 // . Duplicated general modifiers.
28 // . Modifier combinations not legal (such as final abstract).
29 // . Modifiers not in the recommended order (controlled by +Pmodifier-order).
30 // . Explicit specification of implicit modifier (controlled by
31 //   +Predundant-modifiers).
32 //
ProcessModifiers(AstModifiers * modifiers,const wchar_t * declaration_kind_name,u2 valid_flags,u2 implicit_flags)33 AccessFlags Semantic::ProcessModifiers(AstModifiers* modifiers,
34                                        const wchar_t* declaration_kind_name,
35                                        u2 valid_flags, u2 implicit_flags)
36 {
37     if (! modifiers)
38         return AccessFlags(implicit_flags);
39     AccessFlags access_flags;
40     bool seen_keyword = false;
41     for (unsigned i = 0; i < modifiers -> NumModifiers(); i++)
42     {
43         Ast* mod = modifiers -> Modifier(i);
44         AstAnnotation* annotation = mod -> AnnotationCast();
45         AstModifierKeyword* keyword = mod -> ModifierKeywordCast();
46         if (annotation)
47         {
48             if (seen_keyword)
49             {
50                 ReportSemError(SemanticError::RECOMMENDED_ANNOTATION_ORDER,
51                                mod,
52                                lex_stream -> NameString(annotation -> name ->
53                                                         identifier_token));
54             }
55             // TODO: Add annotation support for 1.5.
56             ReportSemError(SemanticError::ANNOTATION_MODIFIER_UNSUPPORTED,
57                            mod);
58             continue;
59         }
60         assert(keyword);
61         seen_keyword = true;
62         u2 flag;
63         switch (lex_stream -> Kind(keyword -> modifier_token))
64         {
65         case TK_abstract: flag = AccessFlags::ACCESS_ABSTRACT; break;
66         case TK_final: flag = AccessFlags::ACCESS_FINAL; break;
67         case TK_native: flag = AccessFlags::ACCESS_NATIVE; break;
68         case TK_public: flag = AccessFlags::ACCESS_PUBLIC; break;
69         case TK_protected: flag = AccessFlags::ACCESS_PROTECTED; break;
70         case TK_private: flag = AccessFlags::ACCESS_PRIVATE; break;
71         case TK_static: flag = AccessFlags::ACCESS_STATIC; break;
72         case TK_strictfp: flag = AccessFlags::ACCESS_STRICTFP; break;
73         case TK_synchronized: flag = AccessFlags::ACCESS_SYNCHRONIZED; break;
74         case TK_transient: flag = AccessFlags::ACCESS_TRANSIENT; break;
75         case TK_volatile: flag = AccessFlags::ACCESS_VOLATILE; break;
76         default:
77             assert(false && "token was not modifier");
78         }
79         if ((flag & valid_flags) == 0)
80         {
81             ReportSemError(SemanticError::INVALID_MODIFIER, mod,
82                            lex_stream -> NameString(keyword -> modifier_token),
83                            declaration_kind_name);
84         }
85         else if ((flag & AccessFlags::ACCESS_ACCESS) &&
86                  (access_flags.Flags() & AccessFlags::ACCESS_ACCESS))
87         {
88             ReportSemError(SemanticError::DUPLICATE_ACCESS_MODIFIER, mod);
89         }
90         else if (access_flags.IsSet(flag))
91         {
92             ReportSemError(SemanticError::DUPLICATE_MODIFIER, mod,
93                            lex_stream -> NameString(keyword ->
94                                                     modifier_token));
95         }
96         else
97         {
98             // We have a valid flag if it is alone.
99             if ((flag & implicit_flags) != 0)
100             {
101                 ReportSemError(SemanticError::REDUNDANT_MODIFIER, mod,
102                                lex_stream -> NameString(keyword ->
103                                                         modifier_token),
104                                declaration_kind_name);
105             }
106             if (! access_flags.RecommendedOrder(flag))
107             {
108                 ReportSemError(SemanticError::RECOMMENDED_MODIFIER_ORDER, mod,
109                                lex_stream -> NameString(keyword ->
110                                                         modifier_token));
111             }
112             access_flags.SetFlags(flag);
113             if (access_flags.ACC_FINAL())
114             {
115                 if (access_flags.ACC_VOLATILE())
116                 {
117                     // We know it's a field because of volatile.
118                     ReportSemError(SemanticError::VOLATILE_FINAL_FIELD, mod,
119                                    lex_stream -> NameString(keyword ->
120                                                             modifier_token));
121                     access_flags.ResetFlags(flag);
122                 }
123                 else if (access_flags.ACC_ABSTRACT())
124                 {
125                     ReportSemError(SemanticError::FINAL_ABSTRACT_ENTITY, mod,
126                                    declaration_kind_name);
127                     access_flags.ResetFlags(flag);
128                 }
129             }
130             else if (access_flags.ACC_ABSTRACT() &&
131                      (valid_flags & AccessFlags::ACCESS_NATIVE))
132             {
133                 //
134                 // Classes can be private static abstract strictfp, but methods
135                 // cannot. Hence, we checked that we are dealing with a method
136                 // by looking for NATIVE in the legal flags.
137                 //
138                 if (access_flags.ACC_SYNCHRONIZED() ||
139                     access_flags.ACC_NATIVE() || access_flags.ACC_PRIVATE() ||
140                     access_flags.ACC_STATIC() || access_flags.ACC_STRICTFP())
141                 {
142                     ReportSemError(SemanticError::BAD_ABSTRACT_METHOD_MODIFIER,
143                                    mod);
144                     access_flags.ResetFlags(flag);
145                 }
146             }
147             else if (access_flags.ACC_STRICTFP() && access_flags.ACC_NATIVE())
148             {
149                 ReportSemError(SemanticError::STRICTFP_NATIVE_METHOD, mod);
150                 access_flags.ResetFlags(flag);
151             }
152         }
153     }
154     access_flags.SetFlags(implicit_flags);
155     return access_flags;
156 }
157 
158 //
159 // Process modifiers of packages (annotations only, added in 1.5).
160 //
ProcessPackageModifiers(AstPackageDeclaration * package)161 AccessFlags Semantic::ProcessPackageModifiers(AstPackageDeclaration* package)
162 {
163     return ProcessModifiers(package -> modifiers_opt, L"a package", 0);
164 }
165 
166 
167 //
168 // Process modifiers of top-level types.
169 //
ProcessTopLevelTypeModifiers(AstDeclaredType * decl)170 AccessFlags Semantic::ProcessTopLevelTypeModifiers(AstDeclaredType* decl)
171 {
172     AstClassDeclaration* class_decl = decl -> ClassDeclarationCast();
173     AstEnumDeclaration* enum_decl = decl -> EnumDeclarationCast();
174     AstInterfaceDeclaration* interface_decl =
175         decl -> InterfaceDeclarationCast();
176     AstAnnotationDeclaration* annotation_decl =
177         decl -> AnnotationDeclarationCast();
178     u2 valid_flags;
179     u2 implicit_flags = 0;
180     const wchar_t* context;
181     if (class_decl)
182     {
183         context = L"a top-level class";
184         valid_flags = AccessFlags::ACCESS_ABSTRACT |
185             AccessFlags::ACCESS_FINAL | AccessFlags::ACCESS_PUBLIC |
186             AccessFlags::ACCESS_STRICTFP;
187     }
188     else if (enum_decl)
189     {
190         valid_flags = AccessFlags::ACCESS_ABSTRACT |
191             AccessFlags::ACCESS_FINAL | AccessFlags::ACCESS_PUBLIC |
192             AccessFlags::ACCESS_STRICTFP;
193         implicit_flags = AccessFlags::ACCESS_FINAL;
194         for (unsigned i = 0; i < enum_decl -> NumEnumConstants(); i++)
195         {
196             if (enum_decl -> EnumConstant(i) -> class_body_opt)
197             {
198                 valid_flags &= ~ AccessFlags::ACCESS_FINAL;
199                 implicit_flags = 0;
200                 break;
201             }
202         }
203         context = implicit_flags
204             ? L"a top-level enumeration (all enum constants without a body)"
205             : L"a top-level enumeration (some enum constants with a body)";
206     }
207     else
208     {
209         valid_flags = AccessFlags::ACCESS_ABSTRACT |
210             AccessFlags::ACCESS_PUBLIC | AccessFlags::ACCESS_STRICTFP;
211         implicit_flags = AccessFlags::ACCESS_INTERFACE |
212             AccessFlags::ACCESS_ABSTRACT;
213         if (interface_decl)
214             context = L"a top-level interface";
215         else
216         {
217             assert(annotation_decl);
218             context = L"a top-level annotation type";
219             implicit_flags |= AccessFlags::ACCESS_ANNOTATION;
220         }
221     }
222     return ProcessModifiers(decl -> modifiers_opt, context, valid_flags,
223                             implicit_flags);
224 }
225 
226 
227 //
228 // Process modifiers of local classes declared as a statement in a method.
229 //
ProcessLocalClassModifiers(AstDeclaredType * decl)230 AccessFlags Semantic::ProcessLocalClassModifiers(AstDeclaredType* decl)
231 {
232     AstClassDeclaration* class_decl = decl -> ClassDeclarationCast();
233     AstEnumDeclaration* enum_decl = decl -> EnumDeclarationCast();
234     u2 valid_flags = AccessFlags::ACCESS_ABSTRACT |
235         AccessFlags::ACCESS_FINAL | AccessFlags::ACCESS_STRICTFP;
236     u2 implicit_flags = 0;
237     const wchar_t* context;
238     if (class_decl)
239         context = L"a local inner class";
240     else
241     {
242         assert(enum_decl);
243         implicit_flags = AccessFlags::ACCESS_FINAL;
244         for (unsigned i = 0; i < enum_decl -> NumEnumConstants(); i++)
245         {
246             if (enum_decl -> EnumConstant(i) -> class_body_opt)
247             {
248                 valid_flags &= ~ AccessFlags::ACCESS_FINAL;
249                 implicit_flags = 0;
250                 break;
251             }
252         }
253         context = implicit_flags
254             ? L"a local enumeration (all enum constants without a body)"
255             : L"a local enumeration (some enum constants with a body)";
256     }
257     return ProcessModifiers(decl -> modifiers_opt, context, valid_flags,
258                             implicit_flags);
259 }
260 
261 
262 //
263 // Process modifiers of nested and inner types.
264 //
ProcessNestedTypeModifiers(TypeSymbol * containing_type,AstDeclaredType * decl)265 AccessFlags Semantic::ProcessNestedTypeModifiers(TypeSymbol* containing_type,
266                                                  AstDeclaredType* decl)
267 {
268     AstClassDeclaration* class_decl = decl -> ClassDeclarationCast();
269     AstEnumDeclaration* enum_decl = decl -> EnumDeclarationCast();
270     AstInterfaceDeclaration* interface_decl =
271         decl -> InterfaceDeclarationCast();
272     AstAnnotationDeclaration* annotation_decl =
273         decl -> AnnotationDeclarationCast();
274     u2 valid_flags;
275     u2 implicit_flags = 0;
276     const wchar_t* context;
277     if (class_decl || enum_decl)
278     {
279         if (containing_type -> ACC_INTERFACE())
280         {
281             valid_flags = AccessFlags::ACCESS_ABSTRACT |
282                 AccessFlags::ACCESS_FINAL | AccessFlags::ACCESS_PUBLIC |
283                 AccessFlags::ACCESS_STATIC | AccessFlags::ACCESS_STRICTFP;
284             implicit_flags = AccessFlags::ACCESS_STATIC |
285                 AccessFlags::ACCESS_PUBLIC;
286         }
287         else
288         {
289             valid_flags = AccessFlags::ACCESS_ABSTRACT |
290                 AccessFlags::ACCESS_FINAL | AccessFlags::ACCESS_ACCESS |
291                 AccessFlags::ACCESS_STATIC | AccessFlags::ACCESS_STRICTFP;
292         }
293         if (class_decl)
294             context = L"a member class";
295         else
296         {
297             implicit_flags |= AccessFlags::ACCESS_FINAL |
298                 AccessFlags::ACCESS_STATIC;
299             for (unsigned i = 0; i < enum_decl -> NumEnumConstants(); i++)
300             {
301                 if (enum_decl -> EnumConstant(i) -> class_body_opt)
302                 {
303                     valid_flags &= ~ AccessFlags::ACCESS_FINAL;
304                     implicit_flags &= ~ AccessFlags::ACCESS_FINAL;
305                     break;
306                 }
307             }
308             context = (implicit_flags & AccessFlags::ACCESS_FINAL)
309                 ? L"a member enumeration (all enum constants without a body)"
310                 : L"a member enumeration (some enum constants with a body)";
311         }
312     }
313     else
314     {
315         if (containing_type -> ACC_INTERFACE())
316         {
317             valid_flags = AccessFlags::ACCESS_ABSTRACT |
318                 AccessFlags::ACCESS_PUBLIC | AccessFlags::ACCESS_STATIC |
319                 AccessFlags::ACCESS_STRICTFP;
320             implicit_flags = AccessFlags::ACCESS_INTERFACE |
321                 AccessFlags::ACCESS_ABSTRACT | AccessFlags::ACCESS_STATIC |
322                 AccessFlags::ACCESS_PUBLIC;
323         }
324         else
325         {
326             valid_flags = AccessFlags::ACCESS_ABSTRACT |
327                 AccessFlags::ACCESS_ACCESS | AccessFlags::ACCESS_STATIC |
328                 AccessFlags::ACCESS_STRICTFP;
329             implicit_flags = AccessFlags::ACCESS_INTERFACE |
330                 AccessFlags::ACCESS_ABSTRACT | AccessFlags::ACCESS_STATIC;
331         }
332         if (interface_decl)
333             context = L"a member interface";
334         else
335         {
336             assert(annotation_decl);
337             context = L"a member annotation type";
338             implicit_flags |= AccessFlags::ACCESS_ANNOTATION;
339         }
340     }
341     return ProcessModifiers(decl -> modifiers_opt, context, valid_flags,
342                             implicit_flags);
343 }
344 
345 
346 //
347 // Process modifiers of fields declared in classes.
348 //
ProcessFieldModifiers(AstFieldDeclaration * field_declaration)349 AccessFlags Semantic::ProcessFieldModifiers(AstFieldDeclaration* field_declaration)
350 {
351     return ProcessModifiers(field_declaration -> modifiers_opt,
352                             L"a class's member field",
353                             (AccessFlags::ACCESS_ACCESS |
354                              AccessFlags::ACCESS_STATIC |
355                              AccessFlags::ACCESS_FINAL |
356                              AccessFlags::ACCESS_TRANSIENT |
357                              AccessFlags::ACCESS_VOLATILE));
358 }
359 
360 
361 //
362 // Process modifiers of local variables.
363 //
ProcessLocalModifiers(AstLocalVariableStatement * decl)364 AccessFlags Semantic::ProcessLocalModifiers(AstLocalVariableStatement* decl)
365 {
366     return ProcessModifiers(decl -> modifiers_opt, L"a local variable",
367                             AccessFlags::ACCESS_FINAL);
368 }
369 
370 
371 //
372 // Process modifiers of parameters.
373 //
ProcessFormalModifiers(AstFormalParameter * decl)374 AccessFlags Semantic::ProcessFormalModifiers(AstFormalParameter* decl)
375 {
376     return ProcessModifiers(decl -> modifiers_opt, L"a formal parameter",
377                             AccessFlags::ACCESS_FINAL);
378 }
379 
380 
381 //
382 // Process modifiers of methods declared in classes.
383 //
ProcessMethodModifiers(AstMethodDeclaration * decl)384 AccessFlags Semantic::ProcessMethodModifiers(AstMethodDeclaration* decl)
385 {
386     return ProcessModifiers(decl -> modifiers_opt, L"a class's member method",
387                             (AccessFlags::ACCESS_ACCESS |
388                              AccessFlags::ACCESS_STATIC |
389                              AccessFlags::ACCESS_STRICTFP |
390                              AccessFlags::ACCESS_ABSTRACT |
391                              AccessFlags::ACCESS_FINAL |
392                              AccessFlags::ACCESS_NATIVE |
393                              AccessFlags::ACCESS_SYNCHRONIZED));
394 }
395 
396 
397 //
398 // Process modifiers of methods declared in interfaces.
399 //
ProcessInterfaceMethodModifiers(AstMethodDeclaration * method_declaration)400 AccessFlags Semantic::ProcessInterfaceMethodModifiers(AstMethodDeclaration* method_declaration)
401 {
402     return ProcessModifiers(method_declaration -> modifiers_opt,
403                             L"an interface's member method",
404                             (AccessFlags::ACCESS_PUBLIC |
405                              AccessFlags::ACCESS_ABSTRACT),
406                             (AccessFlags::ACCESS_PUBLIC |
407                              AccessFlags::ACCESS_ABSTRACT));
408 }
409 
410 
411 //
412 // Process modifiers of constructors.
413 //
ProcessConstructorModifiers(AstConstructorDeclaration * constructor_declaration)414 AccessFlags Semantic::ProcessConstructorModifiers(AstConstructorDeclaration* constructor_declaration)
415 {
416     return ProcessModifiers(constructor_declaration -> modifiers_opt,
417                             L"a constructor", AccessFlags::ACCESS_ACCESS);
418 }
419 
420 
421 //
422 // Process modifiers of fields declared in interfaces.
423 //
ProcessInterfaceFieldModifiers(AstFieldDeclaration * decl)424 AccessFlags Semantic::ProcessInterfaceFieldModifiers(AstFieldDeclaration* decl)
425 {
426     return ProcessModifiers(decl -> modifiers_opt,
427                             L"an interface's member field",
428                             (AccessFlags::ACCESS_PUBLIC |
429                              AccessFlags::ACCESS_STATIC |
430                              AccessFlags::ACCESS_FINAL),
431                             (AccessFlags::ACCESS_PUBLIC |
432                              AccessFlags::ACCESS_STATIC |
433                              AccessFlags::ACCESS_FINAL));
434 }
435 
436 
437 //
438 // Process static and instance initializer modifiers.
439 //
ProcessInitializerModifiers(AstInitializerDeclaration * initializer)440 AccessFlags Semantic::ProcessInitializerModifiers(AstInitializerDeclaration* initializer)
441 {
442     return ProcessModifiers(initializer -> modifiers_opt,
443                             L"an initializer block",
444                             AccessFlags::ACCESS_STATIC);
445 }
446 
447 
448 //
449 // Process static and instance initializer modifiers.
450 //
ProcessEnumConstantModifiers(AstEnumConstant * decl)451 AccessFlags Semantic::ProcessEnumConstantModifiers(AstEnumConstant* decl)
452 {
453     return ProcessModifiers(decl -> modifiers_opt, L"an enum constant", 0,
454                             (AccessFlags::ACCESS_PUBLIC |
455                              AccessFlags::ACCESS_STATIC |
456                              AccessFlags::ACCESS_FINAL |
457                              AccessFlags::ACCESS_ENUM));
458 }
459 
460 #ifdef HAVE_JIKES_NAMESPACE
461 } // Close namespace Jikes block
462 #endif
463