blob: 752a0fb3e1a8eba6c5b620ee382ed7d7476e3528 [file] [log] [blame]
Chris Lattner6953a072008-06-26 18:38:35 +00001//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements decl-related attribute processing.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/ASTContext.h"
Chris Lattnerdc789562008-06-27 22:18:37 +000016#include "clang/Basic/TargetInfo.h"
Chris Lattner6953a072008-06-26 18:38:35 +000017using namespace clang;
18
19static const FunctionTypeProto *getFunctionProto(Decl *d) {
20 QualType Ty;
21
22 if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
23 Ty = decl->getType();
24 else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
25 Ty = decl->getType();
26 else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
27 Ty = decl->getUnderlyingType();
28 else
29 return 0;
30
31 if (Ty->isFunctionPointerType())
32 Ty = Ty->getAsPointerType()->getPointeeType();
33
34 if (const FunctionType *FnTy = Ty->getAsFunctionType())
35 return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType());
36
37 return 0;
38}
39
40static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
41 if (!T->isPointerType())
42 return false;
43
44 T = T->getAsPointerType()->getPointeeType().getCanonicalType();
45 ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr());
46
47 if (!ClsT)
48 return false;
49
50 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
51
52 // FIXME: Should we walk the chain of classes?
53 return ClsName == &Ctx.Idents.get("NSString") ||
54 ClsName == &Ctx.Idents.get("NSMutableString");
55}
56
Chris Lattnerd7e83d82008-06-28 23:58:55 +000057void Sema::ProcessDeclAttributes(Decl *D, const AttributeList *DeclSpecAttrs,
58 const AttributeList *DeclaratorAttrs) {
Chris Lattner1c151132008-06-28 23:36:30 +000059 if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
Chris Lattnerd7e83d82008-06-28 23:58:55 +000060
61 ProcessDeclAttributeList(D, DeclSpecAttrs);
Chris Lattner1c151132008-06-28 23:36:30 +000062
63 // If there are any type attributes that were in the declarator, apply them to
64 // its top level type.
Chris Lattnerd7e83d82008-06-28 23:58:55 +000065 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
Chris Lattner1c151132008-06-28 23:36:30 +000066 QualType DT = VD->getType();
67 ProcessTypeAttributes(DT, DeclaratorAttrs);
68 VD->setType(DT);
Chris Lattnerd7e83d82008-06-28 23:58:55 +000069 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
Chris Lattner1c151132008-06-28 23:36:30 +000070 QualType DT = TD->getUnderlyingType();
71 ProcessTypeAttributes(DT, DeclaratorAttrs);
72 TD->setUnderlyingType(DT);
73 }
74
Chris Lattnerd7e83d82008-06-28 23:58:55 +000075 ProcessDeclAttributeList(D, DeclaratorAttrs);
76}
77
78/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
79/// attribute list to the specified decl, ignoring any type attributes.
80void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
81 while (AttrList) {
82 ProcessDeclAttribute(D, *AttrList);
83 AttrList = AttrList->getNext();
Chris Lattner1c151132008-06-28 23:36:30 +000084 }
85}
86
87/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
88/// the attribute applies to decls. If the attribute is a type attribute, just
89/// silently ignore it.
Chris Lattnerd7e83d82008-06-28 23:58:55 +000090void Sema::ProcessDeclAttribute(Decl *D, const AttributeList &Attr) {
Chris Lattner1c151132008-06-28 23:36:30 +000091 switch (Attr.getKind()) {
92 case AttributeList::AT_address_space:
93 // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
94 break;
Chris Lattnerd7e83d82008-06-28 23:58:55 +000095 case AttributeList::AT_vector_size: HandleVectorSizeAttribute(D, Attr); break;
96 case AttributeList::AT_ext_vector_type:
97 HandleExtVectorTypeAttribute(D, Attr);
Chris Lattner6953a072008-06-26 18:38:35 +000098 break;
Chris Lattnerd7e83d82008-06-28 23:58:55 +000099 case AttributeList::AT_mode: HandleModeAttribute(D, Attr); break;
100 case AttributeList::AT_alias: HandleAliasAttribute(D, Attr); break;
101 case AttributeList::AT_deprecated: HandleDeprecatedAttribute(D, Attr);break;
102 case AttributeList::AT_visibility: HandleVisibilityAttribute(D, Attr);break;
103 case AttributeList::AT_weak: HandleWeakAttribute(D, Attr); break;
104 case AttributeList::AT_dllimport: HandleDLLImportAttribute(D, Attr); break;
105 case AttributeList::AT_dllexport: HandleDLLExportAttribute(D, Attr); break;
106 case AttributeList::AT_nothrow: HandleNothrowAttribute(D, Attr); break;
107 case AttributeList::AT_stdcall: HandleStdCallAttribute(D, Attr); break;
108 case AttributeList::AT_fastcall: HandleFastCallAttribute(D, Attr); break;
109 case AttributeList::AT_aligned: HandleAlignedAttribute(D, Attr); break;
110 case AttributeList::AT_packed: HandlePackedAttribute(D, Attr); break;
111 case AttributeList::AT_annotate: HandleAnnotateAttribute(D, Attr); break;
112 case AttributeList::AT_noreturn: HandleNoReturnAttribute(D, Attr); break;
113 case AttributeList::AT_format: HandleFormatAttribute(D, Attr); break;
Chris Lattner6953a072008-06-26 18:38:35 +0000114 case AttributeList::AT_transparent_union:
Chris Lattnerd7e83d82008-06-28 23:58:55 +0000115 HandleTransparentUnionAttribute(D, Attr);
Chris Lattner6953a072008-06-26 18:38:35 +0000116 break;
117 default:
118#if 0
119 // TODO: when we have the full set of attributes, warn about unknown ones.
120 Diag(Attr->getLoc(), diag::warn_attribute_ignored,
121 Attr->getName()->getName());
122#endif
123 break;
124 }
125}
126
Chris Lattner1c151132008-06-28 23:36:30 +0000127void Sema::HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr) {
128 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
129 if (tDecl == 0) {
130 Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
131 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000132 }
133
Chris Lattner6953a072008-06-26 18:38:35 +0000134 QualType curType = tDecl->getUnderlyingType();
135 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000136 if (Attr.getNumArgs() != 1) {
137 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000138 std::string("1"));
139 return;
140 }
Chris Lattner1c151132008-06-28 23:36:30 +0000141 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000142 llvm::APSInt vecSize(32);
143 if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000144 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000145 "ext_vector_type", sizeExpr->getSourceRange());
146 return;
147 }
148 // unlike gcc's vector_size attribute, we do not allow vectors to be defined
149 // in conjunction with complex types (pointers, arrays, functions, etc.).
150 Type *canonType = curType.getCanonicalType().getTypePtr();
151 if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
Chris Lattner1c151132008-06-28 23:36:30 +0000152 Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
Chris Lattner6953a072008-06-26 18:38:35 +0000153 curType.getCanonicalType().getAsString());
154 return;
155 }
156 // unlike gcc's vector_size attribute, the size is specified as the
157 // number of elements, not the number of bytes.
158 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
159
160 if (vectorSize == 0) {
Chris Lattner1c151132008-06-28 23:36:30 +0000161 Diag(Attr.getLoc(), diag::err_attribute_zero_size,
Chris Lattner6953a072008-06-26 18:38:35 +0000162 sizeExpr->getSourceRange());
163 return;
164 }
165 // Instantiate/Install the vector type, the number of elements is > 0.
166 tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize));
167 // Remember this typedef decl, we will need it later for diagnostics.
168 ExtVectorDecls.push_back(tDecl);
169}
170
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000171
172/// HandleVectorSizeAttribute - this attribute is only applicable to
173/// integral and float scalars, although arrays, pointers, and function
174/// return values are allowed in conjunction with this construct. Aggregates
175/// with this attribute are invalid, even if they are of the same size as a
176/// corresponding scalar.
177/// The raw attribute should contain precisely 1 argument, the vector size
178/// for the variable, measured in bytes. If curType and rawAttr are well
179/// formed, this routine will return a new vector type.
180void Sema::HandleVectorSizeAttribute(Decl *D, const AttributeList &Attr) {
181 QualType CurType;
182 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
183 CurType = VD->getType();
184 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
185 CurType = TD->getUnderlyingType();
186 else {
187 Diag(D->getLocation(), diag::err_attr_wrong_decl,std::string("vector_size"),
188 SourceRange(Attr.getLoc(), Attr.getLoc()));
189 return;
190 }
191
192 // Check the attribute arugments.
Chris Lattner1c151132008-06-28 23:36:30 +0000193 if (Attr.getNumArgs() != 1) {
194 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000195 std::string("1"));
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000196 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000197 }
Chris Lattner1c151132008-06-28 23:36:30 +0000198 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000199 llvm::APSInt vecSize(32);
200 if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000201 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000202 "vector_size", sizeExpr->getSourceRange());
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000203 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000204 }
205 // navigate to the base type - we need to provide for vector pointers,
206 // vector arrays, and functions returning vectors.
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000207 Type *canonType = CurType.getCanonicalType().getTypePtr();
Chris Lattner6953a072008-06-26 18:38:35 +0000208
209 if (canonType->isPointerType() || canonType->isArrayType() ||
210 canonType->isFunctionType()) {
211 assert(0 && "HandleVector(): Complex type construction unimplemented");
212 /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
213 do {
214 if (PointerType *PT = dyn_cast<PointerType>(canonType))
215 canonType = PT->getPointeeType().getTypePtr();
216 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
217 canonType = AT->getElementType().getTypePtr();
218 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
219 canonType = FT->getResultType().getTypePtr();
220 } while (canonType->isPointerType() || canonType->isArrayType() ||
221 canonType->isFunctionType());
222 */
223 }
224 // the base type must be integer or float.
225 if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
Chris Lattner1c151132008-06-28 23:36:30 +0000226 Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000227 CurType.getCanonicalType().getAsString());
228 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000229 }
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000230 unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(CurType));
Chris Lattner6953a072008-06-26 18:38:35 +0000231 // vecSize is specified in bytes - convert to bits.
232 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
233
234 // the vector size needs to be an integral multiple of the type size.
235 if (vectorSize % typeSize) {
Chris Lattner1c151132008-06-28 23:36:30 +0000236 Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
Chris Lattner6953a072008-06-26 18:38:35 +0000237 sizeExpr->getSourceRange());
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000238 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000239 }
240 if (vectorSize == 0) {
Chris Lattner1c151132008-06-28 23:36:30 +0000241 Diag(Attr.getLoc(), diag::err_attribute_zero_size,
Chris Lattner6953a072008-06-26 18:38:35 +0000242 sizeExpr->getSourceRange());
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000243 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000244 }
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000245
246 // Success! Instantiate the vector type, the number of elements is > 0, and
247 // not required to be a power of 2, unlike GCC.
248 CurType = Context.getVectorType(CurType, vectorSize/typeSize);
249
250 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
251 VD->setType(CurType);
252 else
253 cast<TypedefDecl>(D)->setUnderlyingType(CurType);
Chris Lattner6953a072008-06-26 18:38:35 +0000254}
255
Chris Lattner1c151132008-06-28 23:36:30 +0000256void Sema::HandlePackedAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000257 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000258 if (Attr.getNumArgs() > 0) {
259 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000260 std::string("0"));
261 return;
262 }
263
264 if (TagDecl *TD = dyn_cast<TagDecl>(d))
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000265 TD->addAttr(new PackedAttr());
Chris Lattner6953a072008-06-26 18:38:35 +0000266 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
267 // If the alignment is less than or equal to 8 bits, the packed attribute
268 // has no effect.
269 if (!FD->getType()->isIncompleteType() &&
270 Context.getTypeAlign(FD->getType()) <= 8)
Chris Lattner1c151132008-06-28 23:36:30 +0000271 Diag(Attr.getLoc(),
Chris Lattner6953a072008-06-26 18:38:35 +0000272 diag::warn_attribute_ignored_for_field_of_type,
Chris Lattner1c151132008-06-28 23:36:30 +0000273 Attr.getName()->getName(), FD->getType().getAsString());
Chris Lattner6953a072008-06-26 18:38:35 +0000274 else
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000275 FD->addAttr(new PackedAttr());
Chris Lattner6953a072008-06-26 18:38:35 +0000276 } else
Chris Lattner1c151132008-06-28 23:36:30 +0000277 Diag(Attr.getLoc(), diag::warn_attribute_ignored,
278 Attr.getName()->getName());
Chris Lattner6953a072008-06-26 18:38:35 +0000279}
280
Chris Lattner1c151132008-06-28 23:36:30 +0000281void Sema::HandleAliasAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000282 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000283 if (Attr.getNumArgs() != 1) {
284 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000285 std::string("1"));
286 return;
287 }
288
Chris Lattner1c151132008-06-28 23:36:30 +0000289 Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000290 Arg = Arg->IgnoreParenCasts();
291 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
292
293 if (Str == 0 || Str->isWide()) {
Chris Lattner1c151132008-06-28 23:36:30 +0000294 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000295 "alias", std::string("1"));
296 return;
297 }
298
299 const char *Alias = Str->getStrData();
300 unsigned AliasLen = Str->getByteLength();
301
302 // FIXME: check if target symbol exists in current file
303
304 d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
305}
306
Chris Lattner1c151132008-06-28 23:36:30 +0000307void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000308 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000309 if (Attr.getNumArgs() != 0) {
310 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000311 std::string("0"));
312 return;
313 }
314
315 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
Chris Lattner6953a072008-06-26 18:38:35 +0000316 if (!Fn) {
Chris Lattner1c151132008-06-28 23:36:30 +0000317 Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
Chris Lattner6953a072008-06-26 18:38:35 +0000318 "noreturn", "function");
319 return;
320 }
321
322 d->addAttr(new NoReturnAttr());
323}
324
Chris Lattner1c151132008-06-28 23:36:30 +0000325void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000326 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000327 if (Attr.getNumArgs() != 0) {
328 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000329 std::string("0"));
330 return;
331 }
332
333 d->addAttr(new DeprecatedAttr());
334}
335
Chris Lattner1c151132008-06-28 23:36:30 +0000336void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000337 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000338 if (Attr.getNumArgs() != 1) {
339 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000340 std::string("1"));
341 return;
342 }
343
Chris Lattner1c151132008-06-28 23:36:30 +0000344 Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000345 Arg = Arg->IgnoreParenCasts();
346 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
347
348 if (Str == 0 || Str->isWide()) {
Chris Lattner1c151132008-06-28 23:36:30 +0000349 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000350 "visibility", std::string("1"));
351 return;
352 }
353
354 const char *TypeStr = Str->getStrData();
355 unsigned TypeLen = Str->getByteLength();
356 VisibilityAttr::VisibilityTypes type;
357
358 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
359 type = VisibilityAttr::DefaultVisibility;
360 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
361 type = VisibilityAttr::HiddenVisibility;
362 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
363 type = VisibilityAttr::HiddenVisibility; // FIXME
364 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
365 type = VisibilityAttr::ProtectedVisibility;
366 else {
Chris Lattner1c151132008-06-28 23:36:30 +0000367 Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
Chris Lattner6953a072008-06-26 18:38:35 +0000368 "visibility", TypeStr);
369 return;
370 }
371
372 d->addAttr(new VisibilityAttr(type));
373}
374
Chris Lattner1c151132008-06-28 23:36:30 +0000375void Sema::HandleWeakAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000376 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000377 if (Attr.getNumArgs() != 0) {
378 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000379 std::string("0"));
380 return;
381 }
382
383 d->addAttr(new WeakAttr());
384}
385
Chris Lattner1c151132008-06-28 23:36:30 +0000386void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000387 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000388 if (Attr.getNumArgs() != 0) {
389 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000390 std::string("0"));
391 return;
392 }
393
394 d->addAttr(new DLLImportAttr());
395}
396
Chris Lattner1c151132008-06-28 23:36:30 +0000397void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000398 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000399 if (Attr.getNumArgs() != 0) {
400 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000401 std::string("0"));
402 return;
403 }
404
405 d->addAttr(new DLLExportAttr());
406}
407
Chris Lattner1c151132008-06-28 23:36:30 +0000408void Sema::HandleStdCallAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000409 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000410 if (Attr.getNumArgs() != 0) {
411 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000412 std::string("0"));
413 return;
414 }
415
416 d->addAttr(new StdCallAttr());
417}
418
Chris Lattner1c151132008-06-28 23:36:30 +0000419void Sema::HandleFastCallAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000420 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000421 if (Attr.getNumArgs() != 0) {
422 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000423 std::string("0"));
424 return;
425 }
426
427 d->addAttr(new FastCallAttr());
428}
429
Chris Lattner1c151132008-06-28 23:36:30 +0000430void Sema::HandleNothrowAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000431 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000432 if (Attr.getNumArgs() != 0) {
433 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000434 std::string("0"));
435 return;
436 }
437
438 d->addAttr(new NoThrowAttr());
439}
440
441/// Handle __attribute__((format(type,idx,firstarg))) attributes
442/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chris Lattner1c151132008-06-28 23:36:30 +0000443void Sema::HandleFormatAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000444
Chris Lattner1c151132008-06-28 23:36:30 +0000445 if (!Attr.getParameterName()) {
446 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000447 "format", std::string("1"));
448 return;
449 }
450
Chris Lattner1c151132008-06-28 23:36:30 +0000451 if (Attr.getNumArgs() != 2) {
452 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000453 std::string("3"));
454 return;
455 }
456
457 // GCC ignores the format attribute on K&R style function
458 // prototypes, so we ignore it as well
459 const FunctionTypeProto *proto = getFunctionProto(d);
460
461 if (!proto) {
Chris Lattner1c151132008-06-28 23:36:30 +0000462 Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000463 "format", "function");
Chris Lattner6953a072008-06-26 18:38:35 +0000464 return;
465 }
466
467 // FIXME: in C++ the implicit 'this' function parameter also counts.
468 // this is needed in order to be compatible with GCC
469 // the index must start in 1 and the limit is numargs+1
470 unsigned NumArgs = proto->getNumArgs();
471 unsigned FirstIdx = 1;
472
Chris Lattner1c151132008-06-28 23:36:30 +0000473 const char *Format = Attr.getParameterName()->getName();
474 unsigned FormatLen = Attr.getParameterName()->getLength();
Chris Lattner6953a072008-06-26 18:38:35 +0000475
476 // Normalize the argument, __foo__ becomes foo.
477 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
478 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
479 Format += 2;
480 FormatLen -= 4;
481 }
482
483 bool Supported = false;
484 bool is_NSString = false;
485 bool is_strftime = false;
486
487 switch (FormatLen) {
488 default: break;
489 case 5:
490 Supported = !memcmp(Format, "scanf", 5);
491 break;
492 case 6:
493 Supported = !memcmp(Format, "printf", 6);
494 break;
495 case 7:
496 Supported = !memcmp(Format, "strfmon", 7);
497 break;
498 case 8:
499 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
500 (is_NSString = !memcmp(Format, "NSString", 8));
501 break;
502 }
503
504 if (!Supported) {
Chris Lattner1c151132008-06-28 23:36:30 +0000505 Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
506 "format", Attr.getParameterName()->getName());
Chris Lattner6953a072008-06-26 18:38:35 +0000507 return;
508 }
509
510 // checks for the 2nd argument
Chris Lattner1c151132008-06-28 23:36:30 +0000511 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000512 llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType()));
513 if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000514 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000515 "format", std::string("2"), IdxExpr->getSourceRange());
516 return;
517 }
518
519 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
Chris Lattner1c151132008-06-28 23:36:30 +0000520 Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
Chris Lattner6953a072008-06-26 18:38:35 +0000521 "format", std::string("2"), IdxExpr->getSourceRange());
522 return;
523 }
524
525 // FIXME: Do we need to bounds check?
526 unsigned ArgIdx = Idx.getZExtValue() - 1;
527
528 // make sure the format string is really a string
529 QualType Ty = proto->getArgType(ArgIdx);
530
531 if (is_NSString) {
532 // FIXME: do we need to check if the type is NSString*? What are
533 // the semantics?
534 if (!isNSStringType(Ty, Context)) {
535 // FIXME: Should highlight the actual expression that has the
536 // wrong type.
Chris Lattner1c151132008-06-28 23:36:30 +0000537 Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
Chris Lattner6953a072008-06-26 18:38:35 +0000538 IdxExpr->getSourceRange());
539 return;
540 }
541 } else if (!Ty->isPointerType() ||
542 !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
543 // FIXME: Should highlight the actual expression that has the
544 // wrong type.
Chris Lattner1c151132008-06-28 23:36:30 +0000545 Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000546 IdxExpr->getSourceRange());
547 return;
548 }
549
550 // check the 3rd argument
Chris Lattner1c151132008-06-28 23:36:30 +0000551 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
Chris Lattner6953a072008-06-26 18:38:35 +0000552 llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType()));
553 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000554 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000555 "format", std::string("3"), FirstArgExpr->getSourceRange());
556 return;
557 }
558
559 // check if the function is variadic if the 3rd argument non-zero
560 if (FirstArg != 0) {
561 if (proto->isVariadic()) {
562 ++NumArgs; // +1 for ...
563 } else {
564 Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
565 return;
566 }
567 }
568
569 // strftime requires FirstArg to be 0 because it doesn't read from any variable
570 // the input is just the current time + the format string
571 if (is_strftime) {
572 if (FirstArg != 0) {
Chris Lattner1c151132008-06-28 23:36:30 +0000573 Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
Chris Lattner6953a072008-06-26 18:38:35 +0000574 FirstArgExpr->getSourceRange());
575 return;
576 }
577 // if 0 it disables parameter checking (to use with e.g. va_list)
578 } else if (FirstArg != 0 && FirstArg != NumArgs) {
Chris Lattner1c151132008-06-28 23:36:30 +0000579 Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
Chris Lattner6953a072008-06-26 18:38:35 +0000580 "format", std::string("3"), FirstArgExpr->getSourceRange());
581 return;
582 }
583
584 d->addAttr(new FormatAttr(std::string(Format, FormatLen),
585 Idx.getZExtValue(), FirstArg.getZExtValue()));
586}
587
588void Sema::HandleTransparentUnionAttribute(Decl *d,
Chris Lattner1c151132008-06-28 23:36:30 +0000589 const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000590 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000591 if (Attr.getNumArgs() != 0) {
592 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000593 std::string("0"));
594 return;
595 }
596
597 TypeDecl *decl = dyn_cast<TypeDecl>(d);
598
599 if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) {
Chris Lattner1c151132008-06-28 23:36:30 +0000600 Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
Chris Lattner6953a072008-06-26 18:38:35 +0000601 "transparent_union", "union");
602 return;
603 }
604
605 //QualType QTy = Context.getTypeDeclType(decl);
606 //const RecordType *Ty = QTy->getAsUnionType();
607
608// FIXME
609// Ty->addAttr(new TransparentUnionAttr());
610}
611
Chris Lattner1c151132008-06-28 23:36:30 +0000612void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000613 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000614 if (Attr.getNumArgs() != 1) {
615 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000616 std::string("1"));
617 return;
618 }
Chris Lattner1c151132008-06-28 23:36:30 +0000619 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000620 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
621
622 // Make sure that there is a string literal as the annotation's single
623 // argument.
624 if (!SE) {
Chris Lattner1c151132008-06-28 23:36:30 +0000625 Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
Chris Lattner6953a072008-06-26 18:38:35 +0000626 return;
627 }
628 d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
629 SE->getByteLength())));
630}
631
Chris Lattner1c151132008-06-28 23:36:30 +0000632void Sema::HandleAlignedAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000633 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000634 if (Attr.getNumArgs() > 1) {
635 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000636 std::string("1"));
637 return;
638 }
639
640 unsigned Align = 0;
Chris Lattner1c151132008-06-28 23:36:30 +0000641 if (Attr.getNumArgs() == 0) {
Chris Lattner6953a072008-06-26 18:38:35 +0000642 // FIXME: This should be the target specific maximum alignment.
643 // (For now we just use 128 bits which is the maximum on X86.
644 Align = 128;
645 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000646 }
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000647
648 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
649 llvm::APSInt Alignment(32);
650 if (!alignmentExpr->isIntegerConstantExpr(Alignment, Context)) {
651 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
652 "aligned", alignmentExpr->getSourceRange());
653 return;
654 }
655 d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
Chris Lattner6953a072008-06-26 18:38:35 +0000656}
Chris Lattnerdc789562008-06-27 22:18:37 +0000657
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000658/// HandleModeAttribute - This attribute modifies the width of a decl with
659/// primitive type.
Chris Lattnerdc789562008-06-27 22:18:37 +0000660///
661/// Despite what would be logical, the mode attribute is a decl attribute,
662/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
663/// 'G' be HImode, not an intermediate pointer.
664///
665void Sema::HandleModeAttribute(Decl *D, const AttributeList &Attr) {
666 // This attribute isn't documented, but glibc uses it. It changes
667 // the width of an int or unsigned int to the specified size.
668
669 // Check that there aren't any arguments
670 if (Attr.getNumArgs() != 0) {
671 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
672 std::string("0"));
673 return;
674 }
675
676 IdentifierInfo *Name = Attr.getParameterName();
677 if (!Name) {
678 Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
679 return;
680 }
681 const char *Str = Name->getName();
682 unsigned Len = Name->getLength();
683
684 // Normalize the attribute name, __foo__ becomes foo.
685 if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
686 Str[Len - 2] == '_' && Str[Len - 1] == '_') {
687 Str += 2;
688 Len -= 4;
689 }
690
691 unsigned DestWidth = 0;
692 bool IntegerMode = true;
693 switch (Len) {
694 case 2:
695 if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; }
696 if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
697 if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
698 if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
699 if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
700 if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
701 if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
702 if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
703 if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
704 break;
705 case 4:
706 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
707 // pointer on PIC16 and other embedded platforms.
708 if (!memcmp(Str, "word", 4))
709 DestWidth = Context.Target.getPointerWidth(0);
710 if (!memcmp(Str, "byte", 4))
711 DestWidth = Context.Target.getCharWidth();
712 break;
713 case 7:
714 if (!memcmp(Str, "pointer", 7))
715 DestWidth = Context.Target.getPointerWidth(0);
716 break;
717 }
718
719 QualType OldTy;
720 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
721 OldTy = TD->getUnderlyingType();
722 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
723 OldTy = VD->getType();
724 else {
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000725 Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
Chris Lattnerdc789562008-06-27 22:18:37 +0000726 SourceRange(Attr.getLoc(), Attr.getLoc()));
727 return;
728 }
729
730 // FIXME: Need proper fixed-width types
731 QualType NewTy;
732 switch (DestWidth) {
733 case 0:
734 Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
735 return;
736 default:
737 Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
738 return;
739 case 8:
740 assert(IntegerMode);
741 if (OldTy->isSignedIntegerType())
742 NewTy = Context.SignedCharTy;
743 else
744 NewTy = Context.UnsignedCharTy;
745 break;
746 case 16:
747 assert(IntegerMode);
748 if (OldTy->isSignedIntegerType())
749 NewTy = Context.ShortTy;
750 else
751 NewTy = Context.UnsignedShortTy;
752 break;
753 case 32:
754 if (!IntegerMode)
755 NewTy = Context.FloatTy;
756 else if (OldTy->isSignedIntegerType())
757 NewTy = Context.IntTy;
758 else
759 NewTy = Context.UnsignedIntTy;
760 break;
761 case 64:
762 if (!IntegerMode)
763 NewTy = Context.DoubleTy;
764 else if (OldTy->isSignedIntegerType())
765 NewTy = Context.LongLongTy;
766 else
767 NewTy = Context.UnsignedLongLongTy;
768 break;
769 }
770
771 if (!OldTy->getAsBuiltinType())
772 Diag(Attr.getLoc(), diag::err_mode_not_primitive);
773 else if (!(IntegerMode && OldTy->isIntegerType()) &&
774 !(!IntegerMode && OldTy->isFloatingType())) {
775 Diag(Attr.getLoc(), diag::err_mode_wrong_type);
776 }
777
778 // Install the new type.
779 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
780 TD->setUnderlyingType(NewTy);
781 else
782 cast<ValueDecl>(D)->setType(NewTy);
783}