blob: cf339c10440b2478409c0bb880a22fd423d4b239 [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"
Chris Lattnerda48a8e2006-08-04 05:25:55 +000015#include "clang/Basic/LangOptions.h"
Chris Lattnerb9093cd2006-08-04 04:39:53 +000016using namespace llvm;
17using namespace clang;
18
19/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
20///
21unsigned DeclSpec::getParsedSpecifiers() const {
22 unsigned Res = 0;
23 if (StorageClassSpec != SCS_unspecified)
24 Res |= PQ_StorageClassSpecifier;
25
26 if (TypeQualifiers != TQ_unspecified)
27 Res |= PQ_TypeQualifier;
28
29 if (TypeSpecWidth != TSW_unspecified ||
30 TypeSpecComplex != TSC_unspecified ||
31 TypeSpecSign != TSS_unspecified ||
32 TypeSpecType != TST_unspecified)
33 Res |= PQ_TypeSpecifier;
34
35 if (FuncSpec != FS_unspecified)
36 Res |= PQ_FunctionSpecifier;
37 return Res;
38}
39
40
41static bool BadSpecifier(DeclSpec::TSW W, const char *&PrevSpec) {
42 switch (W) {
43 case DeclSpec::TSW_unspecified: PrevSpec = "unspecified"; break;
44 case DeclSpec::TSW_short: PrevSpec = "short"; break;
45 case DeclSpec::TSW_long: PrevSpec = "long"; break;
46 case DeclSpec::TSW_longlong: PrevSpec = "long long"; break;
47 }
48 return true;
49}
50
51static bool BadSpecifier(DeclSpec::TSC C, const char *&PrevSpec) {
52 switch (C) {
53 case DeclSpec::TSC_unspecified: PrevSpec = "unspecified"; break;
54 case DeclSpec::TSC_imaginary: PrevSpec = "imaginary"; break;
55 case DeclSpec::TSC_complex: PrevSpec = "complex"; break;
56 }
57 return true;
58}
59
60
61static bool BadSpecifier(DeclSpec::TSS S, const char *&PrevSpec) {
62 switch (S) {
63 case DeclSpec::TSS_unspecified: PrevSpec = "unspecified"; break;
64 case DeclSpec::TSS_signed: PrevSpec = "signed"; break;
65 case DeclSpec::TSS_unsigned: PrevSpec = "unsigned"; break;
66 }
67 return true;
68}
69
70static bool BadSpecifier(DeclSpec::TST T, const char *&PrevSpec) {
71 switch (T) {
72 case DeclSpec::TST_unspecified: PrevSpec = "unspecified"; break;
73 case DeclSpec::TST_void: PrevSpec = "void"; break;
74 case DeclSpec::TST_char: PrevSpec = "char"; break;
75 case DeclSpec::TST_int: PrevSpec = "int"; break;
76 case DeclSpec::TST_float: PrevSpec = "float"; break;
77 case DeclSpec::TST_double: PrevSpec = "double"; break;
78 case DeclSpec::TST_bool: PrevSpec = "_Bool"; break;
79 case DeclSpec::TST_decimal32: PrevSpec = "_Decimal32"; break;
80 case DeclSpec::TST_decimal64: PrevSpec = "_Decimal64"; break;
81 case DeclSpec::TST_decimal128: PrevSpec = "_Decimal128"; break;
82 }
83 return true;
84}
85
Chris Lattnerda48a8e2006-08-04 05:25:55 +000086static bool BadSpecifier(DeclSpec::TQ T, const char *&PrevSpec) {
87 switch (T) {
88 case DeclSpec::TQ_unspecified: PrevSpec = "unspecified"; break;
89 case DeclSpec::TQ_const: PrevSpec = "const"; break;
90 case DeclSpec::TQ_restrict: PrevSpec = "restrict"; break;
91 case DeclSpec::TQ_volatile: PrevSpec = "volatile"; break;
92 }
93 return true;
94}
Chris Lattnerb9093cd2006-08-04 04:39:53 +000095
96/// These methods set the specified attribute of the DeclSpec, but return true
97/// and ignore the request if invalid (e.g. "extern" then "auto" is
98/// specified).
99bool DeclSpec::SetTypeSpecWidth(TSW W, const char *&PrevSpec) {
100 if (TypeSpecWidth != TSW_unspecified)
101 return BadSpecifier(TypeSpecWidth, PrevSpec);
102 TypeSpecWidth = W;
103 return false;
104}
105
106bool DeclSpec::SetTypeSpecComplex(TSC C, const char *&PrevSpec) {
107 if (TypeSpecComplex != TSC_unspecified)
108 return BadSpecifier(TypeSpecComplex, PrevSpec);
109 TypeSpecComplex = C;
110 return false;
111}
112
113bool DeclSpec::SetTypeSpecSign(TSS S, const char *&PrevSpec) {
114 if (TypeSpecSign != TSS_unspecified)
115 return BadSpecifier(TypeSpecSign, PrevSpec);
Chris Lattnerdeb42f52006-08-04 05:26:52 +0000116 TypeSpecSign = S;
Chris Lattnerb9093cd2006-08-04 04:39:53 +0000117 return false;
118}
119
120bool DeclSpec::SetTypeSpecType(TST T, const char *&PrevSpec) {
121 if (TypeSpecType != TST_unspecified)
122 return BadSpecifier(TypeSpecType, PrevSpec);
Chris Lattnerdeb42f52006-08-04 05:26:52 +0000123 TypeSpecType = T;
Chris Lattnerb9093cd2006-08-04 04:39:53 +0000124 return false;
125}
126
Chris Lattnerda48a8e2006-08-04 05:25:55 +0000127bool DeclSpec::SetTypeQual(TQ T, const char *&PrevSpec,
128 const LangOptions &Lang) {
129 // Duplicates turn into warnings pre-C99.
130 if ((TypeQualifiers & T) && !Lang.C99)
131 return BadSpecifier(T, PrevSpec);
132 TypeQualifiers |= T;
133 return false;
134}
Chris Lattnerb9093cd2006-08-04 04:39:53 +0000135
136bool DeclSpec::SetFuncSpec(FS F, const char *&PrevSpec) {
137 // 'inline inline' is ok.
138 FuncSpec = F;
139 return false;
140}
141
142/// Finish - This does final analysis of the declspec, rejecting things like
143/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
144/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
145/// DeclSpec is guaranteed self-consistent, even if an error occurred.
Chris Lattnerda48a8e2006-08-04 05:25:55 +0000146diag::kind DeclSpec::Finish(const LangOptions &Lang) {
Chris Lattnerb9093cd2006-08-04 04:39:53 +0000147 // FIXME: implement this.
148
149 return diag::NUM_DIAGNOSTICS;
150}