blob: 878ab11b84c9e34f915e41f6313f999bc823f321 [file] [log] [blame]
Chris Lattnerb9093cd2006-08-04 04:39:53 +00001//===--- Declarations.cpp - Declaration Representation Implementation -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Declaration representation classes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Declarations.h"
15using namespace llvm;
16using namespace clang;
17
18/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
19///
20unsigned DeclSpec::getParsedSpecifiers() const {
21 unsigned Res = 0;
22 if (StorageClassSpec != SCS_unspecified)
23 Res |= PQ_StorageClassSpecifier;
24
25 if (TypeQualifiers != TQ_unspecified)
26 Res |= PQ_TypeQualifier;
27
28 if (TypeSpecWidth != TSW_unspecified ||
29 TypeSpecComplex != TSC_unspecified ||
30 TypeSpecSign != TSS_unspecified ||
31 TypeSpecType != TST_unspecified)
32 Res |= PQ_TypeSpecifier;
33
34 if (FuncSpec != FS_unspecified)
35 Res |= PQ_FunctionSpecifier;
36 return Res;
37}
38
39
40static bool BadSpecifier(DeclSpec::TSW W, const char *&PrevSpec) {
41 switch (W) {
42 case DeclSpec::TSW_unspecified: PrevSpec = "unspecified"; break;
43 case DeclSpec::TSW_short: PrevSpec = "short"; break;
44 case DeclSpec::TSW_long: PrevSpec = "long"; break;
45 case DeclSpec::TSW_longlong: PrevSpec = "long long"; break;
46 }
47 return true;
48}
49
50static bool BadSpecifier(DeclSpec::TSC C, const char *&PrevSpec) {
51 switch (C) {
52 case DeclSpec::TSC_unspecified: PrevSpec = "unspecified"; break;
53 case DeclSpec::TSC_imaginary: PrevSpec = "imaginary"; break;
54 case DeclSpec::TSC_complex: PrevSpec = "complex"; break;
55 }
56 return true;
57}
58
59
60static bool BadSpecifier(DeclSpec::TSS S, const char *&PrevSpec) {
61 switch (S) {
62 case DeclSpec::TSS_unspecified: PrevSpec = "unspecified"; break;
63 case DeclSpec::TSS_signed: PrevSpec = "signed"; break;
64 case DeclSpec::TSS_unsigned: PrevSpec = "unsigned"; break;
65 }
66 return true;
67}
68
69static bool BadSpecifier(DeclSpec::TST T, const char *&PrevSpec) {
70 switch (T) {
71 case DeclSpec::TST_unspecified: PrevSpec = "unspecified"; break;
72 case DeclSpec::TST_void: PrevSpec = "void"; break;
73 case DeclSpec::TST_char: PrevSpec = "char"; break;
74 case DeclSpec::TST_int: PrevSpec = "int"; break;
75 case DeclSpec::TST_float: PrevSpec = "float"; break;
76 case DeclSpec::TST_double: PrevSpec = "double"; break;
77 case DeclSpec::TST_bool: PrevSpec = "_Bool"; break;
78 case DeclSpec::TST_decimal32: PrevSpec = "_Decimal32"; break;
79 case DeclSpec::TST_decimal64: PrevSpec = "_Decimal64"; break;
80 case DeclSpec::TST_decimal128: PrevSpec = "_Decimal128"; break;
81 }
82 return true;
83}
84
85
86/// These methods set the specified attribute of the DeclSpec, but return true
87/// and ignore the request if invalid (e.g. "extern" then "auto" is
88/// specified).
89bool DeclSpec::SetTypeSpecWidth(TSW W, const char *&PrevSpec) {
90 if (TypeSpecWidth != TSW_unspecified)
91 return BadSpecifier(TypeSpecWidth, PrevSpec);
92 TypeSpecWidth = W;
93 return false;
94}
95
96bool DeclSpec::SetTypeSpecComplex(TSC C, const char *&PrevSpec) {
97 if (TypeSpecComplex != TSC_unspecified)
98 return BadSpecifier(TypeSpecComplex, PrevSpec);
99 TypeSpecComplex = C;
100 return false;
101}
102
103bool DeclSpec::SetTypeSpecSign(TSS S, const char *&PrevSpec) {
104 if (TypeSpecSign != TSS_unspecified)
105 return BadSpecifier(TypeSpecSign, PrevSpec);
106 return false;
107}
108
109bool DeclSpec::SetTypeSpecType(TST T, const char *&PrevSpec) {
110 if (TypeSpecType != TST_unspecified)
111 return BadSpecifier(TypeSpecType, PrevSpec);
112 return false;
113}
114
115
116bool DeclSpec::SetFuncSpec(FS F, const char *&PrevSpec) {
117 // 'inline inline' is ok.
118 FuncSpec = F;
119 return false;
120}
121
122/// Finish - This does final analysis of the declspec, rejecting things like
123/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
124/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
125/// DeclSpec is guaranteed self-consistent, even if an error occurred.
126diag::kind DeclSpec::Finish() {
127 // FIXME: implement this.
128
129 return diag::NUM_DIAGNOSTICS;
130}