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