blob: 1b61faa53e75e14ade38577596cf2fa848a6557c [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"
Steve Naroff980e5082007-10-01 19:00:59 +000017#include "clang/AST/DeclObjC.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000018#include "clang/Parse/DeclSpec.h"
19#include "clang/Lex/IdentifierTable.h"
Chris Lattnerb23deda2007-08-28 16:40:32 +000020#include "clang/Basic/LangOptions.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000021using namespace clang;
22
23/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate
24/// type object. This returns null on error.
25static QualType ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) {
26 // FIXME: Should move the logic from DeclSpec::Finish to here for validity
27 // checking.
28
29 switch (DS.getTypeSpecType()) {
30 default: return QualType(); // FIXME: Handle unimp cases!
31 case DeclSpec::TST_void: return Ctx.VoidTy;
32 case DeclSpec::TST_char:
33 if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
34 return Ctx.CharTy;
35 else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed)
36 return Ctx.SignedCharTy;
37 else {
38 assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
39 "Unknown TSS value");
40 return Ctx.UnsignedCharTy;
41 }
Chris Lattner7a543ad2007-07-13 21:02:29 +000042 case DeclSpec::TST_unspecified: // Unspecific typespec defaults to int.
Chris Lattner3cbc38b2007-08-21 17:02:28 +000043 case DeclSpec::TST_int: {
44 QualType Result;
Reid Spencer5f016e22007-07-11 17:01:13 +000045 if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
46 switch (DS.getTypeSpecWidth()) {
Chris Lattner3cbc38b2007-08-21 17:02:28 +000047 case DeclSpec::TSW_unspecified: Result = Ctx.IntTy; break;
48 case DeclSpec::TSW_short: Result = Ctx.ShortTy; break;
49 case DeclSpec::TSW_long: Result = Ctx.LongTy; break;
50 case DeclSpec::TSW_longlong: Result = Ctx.LongLongTy; break;
Reid Spencer5f016e22007-07-11 17:01:13 +000051 }
52 } else {
53 switch (DS.getTypeSpecWidth()) {
Chris Lattner3cbc38b2007-08-21 17:02:28 +000054 case DeclSpec::TSW_unspecified: Result = Ctx.UnsignedIntTy; break;
55 case DeclSpec::TSW_short: Result = Ctx.UnsignedShortTy; break;
56 case DeclSpec::TSW_long: Result = Ctx.UnsignedLongTy; break;
57 case DeclSpec::TSW_longlong: Result = Ctx.UnsignedLongLongTy; break;
Reid Spencer5f016e22007-07-11 17:01:13 +000058 }
59 }
Chris Lattner3cbc38b2007-08-21 17:02:28 +000060 // Handle complex integer types.
61 if (DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified)
62 return Result;
63 assert(DS.getTypeSpecComplex() == DeclSpec::TSC_complex &&
64 "FIXME: imaginary types not supported yet!");
65 return Ctx.getComplexType(Result);
66 }
Reid Spencer5f016e22007-07-11 17:01:13 +000067 case DeclSpec::TST_float:
68 if (DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified)
69 return Ctx.FloatTy;
70 assert(DS.getTypeSpecComplex() == DeclSpec::TSC_complex &&
71 "FIXME: imaginary types not supported yet!");
Chris Lattner3cbc38b2007-08-21 17:02:28 +000072 return Ctx.getComplexType(Ctx.FloatTy);
Reid Spencer5f016e22007-07-11 17:01:13 +000073
74 case DeclSpec::TST_double: {
75 bool isLong = DS.getTypeSpecWidth() == DeclSpec::TSW_long;
Chris Lattner3cbc38b2007-08-21 17:02:28 +000076 QualType T = isLong ? Ctx.LongDoubleTy : Ctx.DoubleTy;
Reid Spencer5f016e22007-07-11 17:01:13 +000077 if (DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified)
Chris Lattner3cbc38b2007-08-21 17:02:28 +000078 return T;
Reid Spencer5f016e22007-07-11 17:01:13 +000079 assert(DS.getTypeSpecComplex() == DeclSpec::TSC_complex &&
80 "FIXME: imaginary types not supported yet!");
Chris Lattner3cbc38b2007-08-21 17:02:28 +000081 return Ctx.getComplexType(T);
Reid Spencer5f016e22007-07-11 17:01:13 +000082 }
83 case DeclSpec::TST_bool: // _Bool or bool
84 return Ctx.BoolTy;
85 case DeclSpec::TST_decimal32: // _Decimal32
86 case DeclSpec::TST_decimal64: // _Decimal64
87 case DeclSpec::TST_decimal128: // _Decimal128
88 assert(0 && "FIXME: GNU decimal extensions not supported yet!");
89 case DeclSpec::TST_enum:
90 case DeclSpec::TST_union:
91 case DeclSpec::TST_struct: {
92 Decl *D = static_cast<Decl *>(DS.getTypeRep());
93 assert(D && "Didn't get a decl for a enum/union/struct?");
94 assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
95 DS.getTypeSpecSign() == 0 &&
96 "Can't handle qualifiers on typedef names yet!");
97 // TypeQuals handled by caller.
98 return Ctx.getTagDeclType(cast<TagDecl>(D));
99 }
100 case DeclSpec::TST_typedef: {
101 Decl *D = static_cast<Decl *>(DS.getTypeRep());
102 assert(D && "Didn't get a decl for a typedef?");
103 assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
104 DS.getTypeSpecSign() == 0 &&
105 "Can't handle qualifiers on typedef names yet!");
Steve Naroff3536b442007-09-06 21:24:23 +0000106 // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
107 // we have this "hack" for now...
108 if (isa<ObjcInterfaceDecl>(D))
109 return Ctx.getObjcInterfaceType(cast<ObjcInterfaceDecl>(D));
Reid Spencer5f016e22007-07-11 17:01:13 +0000110 // TypeQuals handled by caller.
111 return Ctx.getTypedefType(cast<TypedefDecl>(D));
112 }
Steve Naroffd1861fd2007-07-31 12:34:36 +0000113 case DeclSpec::TST_typeofType: {
114 QualType T = QualType::getFromOpaquePtr(DS.getTypeRep());
115 assert(!T.isNull() && "Didn't get a type for typeof?");
116 // TypeQuals handled by caller.
117 return Ctx.getTypeOfType(T);
118 }
119 case DeclSpec::TST_typeofExpr: {
120 Expr *E = static_cast<Expr *>(DS.getTypeRep());
121 assert(E && "Didn't get an expression for typeof?");
122 // TypeQuals handled by caller.
Steve Naroff8d1a3b82007-08-01 17:20:42 +0000123 return Ctx.getTypeOfExpr(E);
Steve Naroffd1861fd2007-07-31 12:34:36 +0000124 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000125 }
126}
127
128/// GetTypeForDeclarator - Convert the type for the specified declarator to Type
129/// instances.
130QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
Chris Lattnerb23deda2007-08-28 16:40:32 +0000131 // long long is a C99 feature.
Chris Lattnerd1eb3322007-08-28 16:41:29 +0000132 if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
Chris Lattnerb23deda2007-08-28 16:40:32 +0000133 D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong)
134 Diag(D.getDeclSpec().getTypeSpecWidthLoc(), diag::ext_longlong);
135
Reid Spencer5f016e22007-07-11 17:01:13 +0000136 QualType T = ConvertDeclSpecToType(D.getDeclSpec(), Context);
Steve Naroffe1223f72007-08-28 03:03:08 +0000137
Reid Spencer5f016e22007-07-11 17:01:13 +0000138 // Apply const/volatile/restrict qualifiers to T.
139 T = T.getQualifiedType(D.getDeclSpec().getTypeQualifiers());
140
141 // Walk the DeclTypeInfo, building the recursive type as we go. DeclTypeInfos
142 // are ordered from the identifier out, which is opposite of what we want :).
143 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
144 const DeclaratorChunk &DeclType = D.getTypeObject(e-i-1);
145 switch (DeclType.Kind) {
146 default: assert(0 && "Unknown decltype!");
147 case DeclaratorChunk::Pointer:
Chris Lattner02c642e2007-07-31 21:33:24 +0000148 if (T->isReferenceType()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000149 // C++ 8.3.2p4: There shall be no ... pointers to references ...
150 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_pointer_to_reference,
151 D.getIdentifier()->getName());
Steve Naroffe1223f72007-08-28 03:03:08 +0000152 D.setInvalidType(true);
Chris Lattner5265af52007-07-19 00:42:40 +0000153 T = Context.IntTy;
Reid Spencer5f016e22007-07-11 17:01:13 +0000154 }
155
156 // Apply the pointer typequals to the pointer object.
157 T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals);
158 break;
159 case DeclaratorChunk::Reference:
Chris Lattnera1d9fde2007-07-31 16:56:34 +0000160 if (const ReferenceType *RT = T->getAsReferenceType()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000161 // C++ 8.3.2p4: There shall be no references to references ...
162 Diag(D.getIdentifierLoc(),
163 diag::err_illegal_decl_reference_to_reference,
164 D.getIdentifier()->getName());
Steve Naroffe1223f72007-08-28 03:03:08 +0000165 D.setInvalidType(true);
Chris Lattner5265af52007-07-19 00:42:40 +0000166 T = RT->getReferenceeType();
Reid Spencer5f016e22007-07-11 17:01:13 +0000167 }
168
169 T = Context.getReferenceType(T);
170 break;
171 case DeclaratorChunk::Array: {
172 const DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
Chris Lattner94f81fd2007-08-28 16:54:00 +0000173 Expr *ArraySize = static_cast<Expr*>(ATI.NumElts);
Reid Spencer5f016e22007-07-11 17:01:13 +0000174 ArrayType::ArraySizeModifier ASM;
175 if (ATI.isStar)
176 ASM = ArrayType::Star;
177 else if (ATI.hasStatic)
178 ASM = ArrayType::Static;
179 else
180 ASM = ArrayType::Normal;
Chris Lattner5265af52007-07-19 00:42:40 +0000181
Reid Spencer5f016e22007-07-11 17:01:13 +0000182 // C99 6.7.5.2p1: If the element type is an incomplete or function type,
183 // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
184 if (T->isIncompleteType()) {
185 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_incomplete_type,
186 T.getAsString());
Steve Naroffe1223f72007-08-28 03:03:08 +0000187 T = Context.IntTy;
188 D.setInvalidType(true);
Chris Lattner5265af52007-07-19 00:42:40 +0000189 } else if (T->isFunctionType()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000190 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_functions,
191 D.getIdentifier()->getName());
Steve Naroffe1223f72007-08-28 03:03:08 +0000192 T = Context.getPointerType(T);
193 D.setInvalidType(true);
Chris Lattnera1d9fde2007-07-31 16:56:34 +0000194 } else if (const ReferenceType *RT = T->getAsReferenceType()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000195 // C++ 8.3.2p4: There shall be no ... arrays of references ...
196 Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references,
197 D.getIdentifier()->getName());
Steve Naroffe1223f72007-08-28 03:03:08 +0000198 T = RT->getReferenceeType();
199 D.setInvalidType(true);
Chris Lattner02c642e2007-07-31 21:33:24 +0000200 } else if (const RecordType *EltTy = T->getAsRecordType()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000201 // If the element type is a struct or union that contains a variadic
202 // array, reject it: C99 6.7.2.1p2.
203 if (EltTy->getDecl()->hasFlexibleArrayMember()) {
204 Diag(DeclType.Loc, diag::err_flexible_array_in_array,
205 T.getAsString());
Steve Naroffe1223f72007-08-28 03:03:08 +0000206 T = Context.IntTy;
207 D.setInvalidType(true);
Reid Spencer5f016e22007-07-11 17:01:13 +0000208 }
209 }
Steve Naroff42471f82007-08-30 22:35:45 +0000210 // C99 6.7.5.2p1: The size expression shall have integer type.
211 if (ArraySize && !ArraySize->getType()->isIntegerType()) {
212 Diag(ArraySize->getLocStart(), diag::err_array_size_non_int,
213 ArraySize->getType().getAsString(), ArraySize->getSourceRange());
214 D.setInvalidType(true);
215 }
Steve Naroffc9406122007-08-30 18:10:14 +0000216 llvm::APSInt ConstVal(32);
217 // If no expression was provided, we consider it a VLA.
218 if (!ArraySize || !ArraySize->isIntegerConstantExpr(ConstVal, Context))
219 T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
Steve Naroff42471f82007-08-30 22:35:45 +0000220 else {
221 // C99 6.7.5.2p1: If the expression is a constant expression, it shall
222 // have a value greater than zero.
223 if (ConstVal.isSigned()) {
224 if (ConstVal.isNegative()) {
225 Diag(ArraySize->getLocStart(),
226 diag::err_typecheck_negative_array_size,
227 ArraySize->getSourceRange());
228 D.setInvalidType(true);
229 } else if (ConstVal == 0) {
230 // GCC accepts zero sized static arrays.
231 Diag(ArraySize->getLocStart(), diag::ext_typecheck_zero_array_size,
232 ArraySize->getSourceRange());
233 }
234 }
Steve Naroffc9406122007-08-30 18:10:14 +0000235 T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals);
Steve Naroff42471f82007-08-30 22:35:45 +0000236 }
Chris Lattner94f81fd2007-08-28 16:54:00 +0000237 // If this is not C99, extwarn about VLA's and C99 array size modifiers.
238 if (!getLangOptions().C99 &&
239 (ASM != ArrayType::Normal ||
240 (ArraySize && !ArraySize->isIntegerConstantExpr(Context))))
241 Diag(D.getIdentifierLoc(), diag::ext_vla);
Reid Spencer5f016e22007-07-11 17:01:13 +0000242 break;
243 }
244 case DeclaratorChunk::Function:
245 // If the function declarator has a prototype (i.e. it is not () and
246 // does not have a K&R-style identifier list), then the arguments are part
247 // of the type, otherwise the argument list is ().
248 const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
249 if (!FTI.hasPrototype) {
250 // Simple void foo(), where the incoming T is the result type.
251 T = Context.getFunctionTypeNoProto(T);
252
253 // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
254 if (FTI.NumArgs != 0)
255 Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
256
257 } else {
258 // Otherwise, we have a function with an argument list that is
259 // potentially variadic.
260 llvm::SmallVector<QualType, 16> ArgTys;
261
262 for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
263 QualType ArgTy = QualType::getFromOpaquePtr(FTI.ArgInfo[i].TypeInfo);
Chris Lattner78c75fb2007-07-21 05:30:18 +0000264 assert(!ArgTy.isNull() && "Couldn't parse type?");
Steve Naroff08d51392007-09-10 22:17:00 +0000265 //
266 // Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
267 // This matches the conversion that is done in
268 // Sema::ParseParamDeclarator(). Without this conversion, the
269 // argument type in the function prototype *will not* match the
270 // type in ParmVarDecl (which makes the code generator unhappy).
271 //
272 // FIXME: We still apparently need the conversion in
273 // Sema::ParseParamDeclarator(). This doesn't make any sense, since
274 // it should be driving off the type being created here.
275 //
276 // FIXME: If a source translation tool needs to see the original type,
277 // then we need to consider storing both types somewhere...
278 //
279 if (const ArrayType *AT = ArgTy->getAsArrayType())
280 ArgTy = Context.getPointerType(AT->getElementType());
281 else if (ArgTy->isFunctionType())
282 ArgTy = Context.getPointerType(ArgTy);
Reid Spencer5f016e22007-07-11 17:01:13 +0000283 // Look for 'void'. void is allowed only as a single argument to a
284 // function with no other parameters (C99 6.7.5.3p10). We record
285 // int(void) as a FunctionTypeProto with an empty argument list.
Steve Naroff08d51392007-09-10 22:17:00 +0000286 else if (ArgTy->isVoidType()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000287 // If this is something like 'float(int, void)', reject it. 'void'
288 // is an incomplete type (C99 6.2.5p19) and function decls cannot
289 // have arguments of incomplete type.
290 if (FTI.NumArgs != 1 || FTI.isVariadic) {
291 Diag(DeclType.Loc, diag::err_void_only_param);
Chris Lattner2ff54262007-07-21 05:18:12 +0000292 ArgTy = Context.IntTy;
Chris Lattner78c75fb2007-07-21 05:30:18 +0000293 FTI.ArgInfo[i].TypeInfo = ArgTy.getAsOpaquePtr();
Chris Lattner2ff54262007-07-21 05:18:12 +0000294 } else if (FTI.ArgInfo[i].Ident) {
295 // Reject, but continue to parse 'int(void abc)'.
Reid Spencer5f016e22007-07-11 17:01:13 +0000296 Diag(FTI.ArgInfo[i].IdentLoc,
Chris Lattner4565d4e2007-07-21 05:26:43 +0000297 diag::err_param_with_void_type);
Chris Lattner2ff54262007-07-21 05:18:12 +0000298 ArgTy = Context.IntTy;
Chris Lattner78c75fb2007-07-21 05:30:18 +0000299 FTI.ArgInfo[i].TypeInfo = ArgTy.getAsOpaquePtr();
Chris Lattner2ff54262007-07-21 05:18:12 +0000300 } else {
301 // Reject, but continue to parse 'float(const void)'.
302 if (ArgTy.getQualifiers())
303 Diag(DeclType.Loc, diag::err_void_param_qualified);
304
305 // Do not add 'void' to the ArgTys list.
306 break;
307 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000308 }
309
310 ArgTys.push_back(ArgTy);
311 }
312 T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
313 FTI.isVariadic);
314 }
315 break;
316 }
317 }
318
319 return T;
320}
321
Steve Naroff08d92e42007-09-15 18:49:24 +0000322Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000323 // C99 6.7.6: Type names have no identifier. This is already validated by
324 // the parser.
325 assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
326
327 QualType T = GetTypeForDeclarator(D, S);
Steve Naroff5912a352007-08-28 20:14:24 +0000328
329 assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
Reid Spencer5f016e22007-07-11 17:01:13 +0000330
Steve Naroff5912a352007-08-28 20:14:24 +0000331 // In this context, we *do not* check D.getInvalidType(). If the declarator
332 // type was invalid, GetTypeForDeclarator() still returns a "valid" type,
333 // though it will not reflect the user specified type.
Reid Spencer5f016e22007-07-11 17:01:13 +0000334 return T.getAsOpaquePtr();
335}
336
Steve Naroffe1223f72007-08-28 03:03:08 +0000337// Called from Parser::ParseParenDeclarator().
Steve Naroff08d92e42007-09-15 18:49:24 +0000338Sema::TypeResult Sema::ActOnParamDeclaratorType(Scope *S, Declarator &D) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000339 // Note: parameters have identifiers, but we don't care about them here, we
340 // just want the type converted.
341 QualType T = GetTypeForDeclarator(D, S);
342
Steve Naroff5912a352007-08-28 20:14:24 +0000343 assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
344
345 // In this context, we *do not* check D.getInvalidType(). If the declarator
346 // type was invalid, GetTypeForDeclarator() still returns a "valid" type,
347 // though it will not reflect the user specified type.
Reid Spencer5f016e22007-07-11 17:01:13 +0000348 return T.getAsOpaquePtr();
349}