blob: cdb767f58c7933643a97f756dd8431c08ef53711 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- SemaType.cpp - Semantic Analysis for Types -----------------------===//
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 type-related semantic analysis.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/Parse/DeclSpec.h"
18#include "clang/Lex/IdentifierTable.h"
19using namespace clang;
20
21/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate
22/// type object. This returns null on error.
23static QualType ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) {
24 // FIXME: Should move the logic from DeclSpec::Finish to here for validity
25 // checking.
26
27 switch (DS.getTypeSpecType()) {
28 default: return QualType(); // FIXME: Handle unimp cases!
29 case DeclSpec::TST_void: return Ctx.VoidTy;
30 case DeclSpec::TST_char:
31 if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
32 return Ctx.CharTy;
33 else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed)
34 return Ctx.SignedCharTy;
35 else {
36 assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
37 "Unknown TSS value");
38 return Ctx.UnsignedCharTy;
39 }
40 case DeclSpec::TST_int:
41 if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
42 switch (DS.getTypeSpecWidth()) {
43 case DeclSpec::TSW_unspecified: return Ctx.IntTy;
44 case DeclSpec::TSW_short: return Ctx.ShortTy;
45 case DeclSpec::TSW_long: return Ctx.LongTy;
46 case DeclSpec::TSW_longlong: return Ctx.LongLongTy;
47 }
48 } else {
49 switch (DS.getTypeSpecWidth()) {
50 case DeclSpec::TSW_unspecified: return Ctx.UnsignedIntTy;
51 case DeclSpec::TSW_short: return Ctx.UnsignedShortTy;
52 case DeclSpec::TSW_long: return Ctx.UnsignedLongTy;
53 case DeclSpec::TSW_longlong: return Ctx.UnsignedLongLongTy;
54 }
55 }
56 case DeclSpec::TST_float:
57 if (DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified)
58 return Ctx.FloatTy;
59 assert(DS.getTypeSpecComplex() == DeclSpec::TSC_complex &&
60 "FIXME: imaginary types not supported yet!");
61 return Ctx.FloatComplexTy;
62
63 case DeclSpec::TST_double: {
64 bool isLong = DS.getTypeSpecWidth() == DeclSpec::TSW_long;
65 if (DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified)
66 return isLong ? Ctx.LongDoubleTy : Ctx.DoubleTy;
67 assert(DS.getTypeSpecComplex() == DeclSpec::TSC_complex &&
68 "FIXME: imaginary types not supported yet!");
69 return isLong ? Ctx.LongDoubleComplexTy : Ctx.DoubleComplexTy;
70 }
71 case DeclSpec::TST_bool: // _Bool or bool
72 return Ctx.BoolTy;
73 case DeclSpec::TST_decimal32: // _Decimal32
74 case DeclSpec::TST_decimal64: // _Decimal64
75 case DeclSpec::TST_decimal128: // _Decimal128
76 assert(0 && "FIXME: GNU decimal extensions not supported yet!");
77 case DeclSpec::TST_enum:
78 case DeclSpec::TST_union:
79 case DeclSpec::TST_struct: {
80 Decl *D = static_cast<Decl *>(DS.getTypeRep());
81 assert(D && "Didn't get a decl for a enum/union/struct?");
82 assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
83 DS.getTypeSpecSign() == 0 &&
84 "Can't handle qualifiers on typedef names yet!");
85 // TypeQuals handled by caller.
86 return Ctx.getTagDeclType(cast<TagDecl>(D));
87 }
88 case DeclSpec::TST_typedef: {
89 Decl *D = static_cast<Decl *>(DS.getTypeRep());
90 assert(D && "Didn't get a decl for a typedef?");
91 assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
92 DS.getTypeSpecSign() == 0 &&
93 "Can't handle qualifiers on typedef names yet!");
94 // TypeQuals handled by caller.
95 return Ctx.getTypedefType(cast<TypedefDecl>(D));
96 }
97 }
98}
99
100/// GetTypeForDeclarator - Convert the type for the specified declarator to Type
101/// instances.
102QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
103 QualType T = ConvertDeclSpecToType(D.getDeclSpec(), Context);
104
105 // If there was an error parsing declspecs, return a null type pointer.
106 if (T.isNull()) return T;
107
108 // Apply const/volatile/restrict qualifiers to T.
109 T = T.getQualifiedType(D.getDeclSpec().getTypeQualifiers());
110
111 // Walk the DeclTypeInfo, building the recursive type as we go. DeclTypeInfos
112 // are ordered from the identifier out, which is opposite of what we want :).
113 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
114 const DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
115 switch (DeclType.Kind) {
116 default: assert(0 && "Unknown decltype!");
117 case DeclaratorChunk::Pointer:
118 if (isa<ReferenceType>(T.getCanonicalType().getTypePtr())) {
119 // C++ 8.3.2p4: There shall be no ... pointers to references ...
120 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_pointer_to_reference,
121 D.getIdentifier()->getName());
122 return QualType();
123 }
124
125 // Apply the pointer typequals to the pointer object.
126 T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals);
127 break;
128 case DeclaratorChunk::Reference:
129 if (isa<ReferenceType>(T.getCanonicalType().getTypePtr())) {
130 // C++ 8.3.2p4: There shall be no references to references ...
131 Diag(D.getIdentifierLoc(),
132 diag::err_illegal_decl_reference_to_reference,
133 D.getIdentifier()->getName());
134 return QualType();
135 }
136
137 T = Context.getReferenceType(T);
138 break;
139 case DeclaratorChunk::Array: {
140 const DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
141 ArrayType::ArraySizeModifier ASM;
142 if (ATI.isStar)
143 ASM = ArrayType::Star;
144 else if (ATI.hasStatic)
145 ASM = ArrayType::Static;
146 else
147 ASM = ArrayType::Normal;
148
149 Type *CanonicalT = T.getCanonicalType().getTypePtr();
150
151 // C99 6.7.5.2p1: If the element type is an incomplete or function type,
152 // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
153 if (T->isIncompleteType()) {
154 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_incomplete_type,
155 T.getAsString());
156 return QualType();
157 } else if (isa<FunctionType>(CanonicalT)) {
158 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_functions,
159 D.getIdentifier()->getName());
160 return QualType();
161 } else if (isa<ReferenceType>(CanonicalT)) {
162 // C++ 8.3.2p4: There shall be no ... arrays of references ...
163 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references,
164 D.getIdentifier()->getName());
165 return QualType();
166 } else if (RecordType *EltTy = dyn_cast<RecordType>(CanonicalT)) {
167 // If the element type is a struct or union that contains a variadic
168 // array, reject it: C99 6.7.2.1p2.
169 if (EltTy->getDecl()->hasFlexibleArrayMember()) {
170 Diag(DeclType.Loc, diag::err_flexible_array_in_array,
171 T.getAsString());
172 return QualType();
173 }
174 }
175 T = Context.getArrayType(T, ASM, ATI.TypeQuals,
176 static_cast<Expr *>(ATI.NumElts));
177 break;
178 }
179 case DeclaratorChunk::Function:
180 // If the function declarator has a prototype (i.e. it is not () and
181 // does not have a K&R-style identifier list), then the arguments are part
182 // of the type, otherwise the argument list is ().
183 const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
184 if (!FTI.hasPrototype) {
185 // Simple void foo(), where the incoming T is the result type.
186 T = Context.getFunctionTypeNoProto(T);
187
188 // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
189 if (FTI.NumArgs != 0)
190 Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
191
192 } else {
193 // Otherwise, we have a function with an argument list that is
194 // potentially variadic.
195 llvm::SmallVector<QualType, 16> ArgTys;
196
197 for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
198 QualType ArgTy = QualType::getFromOpaquePtr(FTI.ArgInfo[i].TypeInfo);
199 if (ArgTy.isNull())
200 return QualType(); // Error occurred parsing argument type.
201
202 // Look for 'void'. void is allowed only as a single argument to a
203 // function with no other parameters (C99 6.7.5.3p10). We record
204 // int(void) as a FunctionTypeProto with an empty argument list.
205 if (ArgTy->isVoidType()) {
206 // If this is something like 'float(int, void)', reject it. 'void'
207 // is an incomplete type (C99 6.2.5p19) and function decls cannot
208 // have arguments of incomplete type.
209 if (FTI.NumArgs != 1 || FTI.isVariadic) {
210 Diag(DeclType.Loc, diag::err_void_only_param);
211 return QualType();
212 }
213 // Reject, but continue to parse 'int(void abc)'.
214 if (FTI.ArgInfo[i].Ident)
215 Diag(FTI.ArgInfo[i].IdentLoc,
216 diag::err_void_param_with_identifier);
217
218 // Reject, but continue to parse 'float(const void)'.
219 if (ArgTy.getQualifiers())
220 Diag(DeclType.Loc, diag::err_void_param_qualified);
221
222 // Do not add 'void' to the ArgTys list.
223 break;
224 }
225
226 ArgTys.push_back(ArgTy);
227 }
228 T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
229 FTI.isVariadic);
230 }
231 break;
232 }
233 }
234
235 return T;
236}
237
238Sema::TypeResult Sema::ParseTypeName(Scope *S, Declarator &D) {
239 // C99 6.7.6: Type names have no identifier. This is already validated by
240 // the parser.
241 assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
242
243 QualType T = GetTypeForDeclarator(D, S);
244
245 // If the type of the declarator was invalid, this is an invalid typename.
246 if (T.isNull())
247 return true;
248
249 return T.getAsOpaquePtr();
250}
251
252Sema::TypeResult Sema::ParseParamDeclaratorType(Scope *S, Declarator &D) {
253 // Note: parameters have identifiers, but we don't care about them here, we
254 // just want the type converted.
255 QualType T = GetTypeForDeclarator(D, S);
256
257 // If the type of the declarator was invalid, this is an invalid typename.
258 if (T.isNull())
259 return true;
260
261 return T.getAsOpaquePtr();
262}