blob: cdb54856665e09c6b0d52285174a3db30d1cf8fe [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 Lattner9b384ca2008-06-29 00:02:00 +000057void Sema::ProcessDeclAttributes(Decl *D, Declarator &PD) {
58 const AttributeList *DeclSpecAttrs = PD.getDeclSpec().getAttributes();
59 const AttributeList *DeclaratorAttrs = PD.getAttributes();
60
Chris Lattner1c151132008-06-28 23:36:30 +000061 if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
Chris Lattnerd7e83d82008-06-28 23:58:55 +000062
63 ProcessDeclAttributeList(D, DeclSpecAttrs);
Chris Lattner1c151132008-06-28 23:36:30 +000064
65 // If there are any type attributes that were in the declarator, apply them to
66 // its top level type.
Chris Lattnerd7e83d82008-06-28 23:58:55 +000067 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
Chris Lattner1c151132008-06-28 23:36:30 +000068 QualType DT = VD->getType();
69 ProcessTypeAttributes(DT, DeclaratorAttrs);
70 VD->setType(DT);
Chris Lattnerd7e83d82008-06-28 23:58:55 +000071 } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
Chris Lattner1c151132008-06-28 23:36:30 +000072 QualType DT = TD->getUnderlyingType();
73 ProcessTypeAttributes(DT, DeclaratorAttrs);
74 TD->setUnderlyingType(DT);
75 }
76
Chris Lattnerd7e83d82008-06-28 23:58:55 +000077 ProcessDeclAttributeList(D, DeclaratorAttrs);
78}
79
80/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
81/// attribute list to the specified decl, ignoring any type attributes.
82void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
83 while (AttrList) {
84 ProcessDeclAttribute(D, *AttrList);
85 AttrList = AttrList->getNext();
Chris Lattner1c151132008-06-28 23:36:30 +000086 }
87}
88
89/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
90/// the attribute applies to decls. If the attribute is a type attribute, just
91/// silently ignore it.
Chris Lattnerd7e83d82008-06-28 23:58:55 +000092void Sema::ProcessDeclAttribute(Decl *D, const AttributeList &Attr) {
Chris Lattner1c151132008-06-28 23:36:30 +000093 switch (Attr.getKind()) {
94 case AttributeList::AT_address_space:
95 // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
96 break;
Chris Lattnerd7e83d82008-06-28 23:58:55 +000097 case AttributeList::AT_vector_size: HandleVectorSizeAttribute(D, Attr); break;
98 case AttributeList::AT_ext_vector_type:
99 HandleExtVectorTypeAttribute(D, Attr);
Chris Lattner6953a072008-06-26 18:38:35 +0000100 break;
Chris Lattnerd7e83d82008-06-28 23:58:55 +0000101 case AttributeList::AT_mode: HandleModeAttribute(D, Attr); break;
102 case AttributeList::AT_alias: HandleAliasAttribute(D, Attr); break;
103 case AttributeList::AT_deprecated: HandleDeprecatedAttribute(D, Attr);break;
104 case AttributeList::AT_visibility: HandleVisibilityAttribute(D, Attr);break;
105 case AttributeList::AT_weak: HandleWeakAttribute(D, Attr); break;
106 case AttributeList::AT_dllimport: HandleDLLImportAttribute(D, Attr); break;
107 case AttributeList::AT_dllexport: HandleDLLExportAttribute(D, Attr); break;
108 case AttributeList::AT_nothrow: HandleNothrowAttribute(D, Attr); break;
109 case AttributeList::AT_stdcall: HandleStdCallAttribute(D, Attr); break;
110 case AttributeList::AT_fastcall: HandleFastCallAttribute(D, Attr); break;
111 case AttributeList::AT_aligned: HandleAlignedAttribute(D, Attr); break;
112 case AttributeList::AT_packed: HandlePackedAttribute(D, Attr); break;
113 case AttributeList::AT_annotate: HandleAnnotateAttribute(D, Attr); break;
114 case AttributeList::AT_noreturn: HandleNoReturnAttribute(D, Attr); break;
115 case AttributeList::AT_format: HandleFormatAttribute(D, Attr); break;
Chris Lattner6953a072008-06-26 18:38:35 +0000116 case AttributeList::AT_transparent_union:
Chris Lattnerd7e83d82008-06-28 23:58:55 +0000117 HandleTransparentUnionAttribute(D, Attr);
Chris Lattner6953a072008-06-26 18:38:35 +0000118 break;
119 default:
120#if 0
121 // TODO: when we have the full set of attributes, warn about unknown ones.
122 Diag(Attr->getLoc(), diag::warn_attribute_ignored,
123 Attr->getName()->getName());
124#endif
125 break;
126 }
127}
128
Chris Lattner1c151132008-06-28 23:36:30 +0000129void Sema::HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr) {
130 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
131 if (tDecl == 0) {
132 Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
133 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000134 }
135
Chris Lattner6953a072008-06-26 18:38:35 +0000136 QualType curType = tDecl->getUnderlyingType();
137 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000138 if (Attr.getNumArgs() != 1) {
139 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000140 std::string("1"));
141 return;
142 }
Chris Lattner1c151132008-06-28 23:36:30 +0000143 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000144 llvm::APSInt vecSize(32);
145 if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000146 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000147 "ext_vector_type", sizeExpr->getSourceRange());
148 return;
149 }
150 // unlike gcc's vector_size attribute, we do not allow vectors to be defined
151 // in conjunction with complex types (pointers, arrays, functions, etc.).
152 Type *canonType = curType.getCanonicalType().getTypePtr();
153 if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
Chris Lattner1c151132008-06-28 23:36:30 +0000154 Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
Chris Lattner6953a072008-06-26 18:38:35 +0000155 curType.getCanonicalType().getAsString());
156 return;
157 }
158 // unlike gcc's vector_size attribute, the size is specified as the
159 // number of elements, not the number of bytes.
160 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
161
162 if (vectorSize == 0) {
Chris Lattner1c151132008-06-28 23:36:30 +0000163 Diag(Attr.getLoc(), diag::err_attribute_zero_size,
Chris Lattner6953a072008-06-26 18:38:35 +0000164 sizeExpr->getSourceRange());
165 return;
166 }
167 // Instantiate/Install the vector type, the number of elements is > 0.
168 tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize));
169 // Remember this typedef decl, we will need it later for diagnostics.
170 ExtVectorDecls.push_back(tDecl);
171}
172
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000173
174/// HandleVectorSizeAttribute - this attribute is only applicable to
175/// integral and float scalars, although arrays, pointers, and function
176/// return values are allowed in conjunction with this construct. Aggregates
177/// with this attribute are invalid, even if they are of the same size as a
178/// corresponding scalar.
179/// The raw attribute should contain precisely 1 argument, the vector size
180/// for the variable, measured in bytes. If curType and rawAttr are well
181/// formed, this routine will return a new vector type.
182void Sema::HandleVectorSizeAttribute(Decl *D, const AttributeList &Attr) {
183 QualType CurType;
184 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
185 CurType = VD->getType();
186 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
187 CurType = TD->getUnderlyingType();
188 else {
189 Diag(D->getLocation(), diag::err_attr_wrong_decl,std::string("vector_size"),
190 SourceRange(Attr.getLoc(), Attr.getLoc()));
191 return;
192 }
193
194 // Check the attribute arugments.
Chris Lattner1c151132008-06-28 23:36:30 +0000195 if (Attr.getNumArgs() != 1) {
196 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000197 std::string("1"));
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000198 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000199 }
Chris Lattner1c151132008-06-28 23:36:30 +0000200 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000201 llvm::APSInt vecSize(32);
202 if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000203 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000204 "vector_size", sizeExpr->getSourceRange());
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000205 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000206 }
207 // navigate to the base type - we need to provide for vector pointers,
208 // vector arrays, and functions returning vectors.
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000209 Type *canonType = CurType.getCanonicalType().getTypePtr();
Chris Lattner6953a072008-06-26 18:38:35 +0000210
211 if (canonType->isPointerType() || canonType->isArrayType() ||
212 canonType->isFunctionType()) {
213 assert(0 && "HandleVector(): Complex type construction unimplemented");
214 /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
215 do {
216 if (PointerType *PT = dyn_cast<PointerType>(canonType))
217 canonType = PT->getPointeeType().getTypePtr();
218 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
219 canonType = AT->getElementType().getTypePtr();
220 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
221 canonType = FT->getResultType().getTypePtr();
222 } while (canonType->isPointerType() || canonType->isArrayType() ||
223 canonType->isFunctionType());
224 */
225 }
226 // the base type must be integer or float.
227 if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
Chris Lattner1c151132008-06-28 23:36:30 +0000228 Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type,
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000229 CurType.getCanonicalType().getAsString());
230 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000231 }
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000232 unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(CurType));
Chris Lattner6953a072008-06-26 18:38:35 +0000233 // vecSize is specified in bytes - convert to bits.
234 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
235
236 // the vector size needs to be an integral multiple of the type size.
237 if (vectorSize % typeSize) {
Chris Lattner1c151132008-06-28 23:36:30 +0000238 Diag(Attr.getLoc(), diag::err_attribute_invalid_size,
Chris Lattner6953a072008-06-26 18:38:35 +0000239 sizeExpr->getSourceRange());
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000240 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000241 }
242 if (vectorSize == 0) {
Chris Lattner1c151132008-06-28 23:36:30 +0000243 Diag(Attr.getLoc(), diag::err_attribute_zero_size,
Chris Lattner6953a072008-06-26 18:38:35 +0000244 sizeExpr->getSourceRange());
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000245 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000246 }
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000247
248 // Success! Instantiate the vector type, the number of elements is > 0, and
249 // not required to be a power of 2, unlike GCC.
250 CurType = Context.getVectorType(CurType, vectorSize/typeSize);
251
252 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
253 VD->setType(CurType);
254 else
255 cast<TypedefDecl>(D)->setUnderlyingType(CurType);
Chris Lattner6953a072008-06-26 18:38:35 +0000256}
257
Chris Lattner1c151132008-06-28 23:36:30 +0000258void Sema::HandlePackedAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000259 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000260 if (Attr.getNumArgs() > 0) {
261 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000262 std::string("0"));
263 return;
264 }
265
266 if (TagDecl *TD = dyn_cast<TagDecl>(d))
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000267 TD->addAttr(new PackedAttr());
Chris Lattner6953a072008-06-26 18:38:35 +0000268 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
269 // If the alignment is less than or equal to 8 bits, the packed attribute
270 // has no effect.
271 if (!FD->getType()->isIncompleteType() &&
272 Context.getTypeAlign(FD->getType()) <= 8)
Chris Lattner1c151132008-06-28 23:36:30 +0000273 Diag(Attr.getLoc(),
Chris Lattner6953a072008-06-26 18:38:35 +0000274 diag::warn_attribute_ignored_for_field_of_type,
Chris Lattner1c151132008-06-28 23:36:30 +0000275 Attr.getName()->getName(), FD->getType().getAsString());
Chris Lattner6953a072008-06-26 18:38:35 +0000276 else
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000277 FD->addAttr(new PackedAttr());
Chris Lattner6953a072008-06-26 18:38:35 +0000278 } else
Chris Lattner1c151132008-06-28 23:36:30 +0000279 Diag(Attr.getLoc(), diag::warn_attribute_ignored,
280 Attr.getName()->getName());
Chris Lattner6953a072008-06-26 18:38:35 +0000281}
282
Chris Lattner1c151132008-06-28 23:36:30 +0000283void Sema::HandleAliasAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000284 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000285 if (Attr.getNumArgs() != 1) {
286 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000287 std::string("1"));
288 return;
289 }
290
Chris Lattner1c151132008-06-28 23:36:30 +0000291 Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000292 Arg = Arg->IgnoreParenCasts();
293 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
294
295 if (Str == 0 || Str->isWide()) {
Chris Lattner1c151132008-06-28 23:36:30 +0000296 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000297 "alias", std::string("1"));
298 return;
299 }
300
301 const char *Alias = Str->getStrData();
302 unsigned AliasLen = Str->getByteLength();
303
304 // FIXME: check if target symbol exists in current file
305
306 d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
307}
308
Chris Lattner1c151132008-06-28 23:36:30 +0000309void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000310 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000311 if (Attr.getNumArgs() != 0) {
312 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000313 std::string("0"));
314 return;
315 }
316
317 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
Chris Lattner6953a072008-06-26 18:38:35 +0000318 if (!Fn) {
Chris Lattner1c151132008-06-28 23:36:30 +0000319 Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
Chris Lattner6953a072008-06-26 18:38:35 +0000320 "noreturn", "function");
321 return;
322 }
323
324 d->addAttr(new NoReturnAttr());
325}
326
Chris Lattner1c151132008-06-28 23:36:30 +0000327void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000328 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000329 if (Attr.getNumArgs() != 0) {
330 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000331 std::string("0"));
332 return;
333 }
334
335 d->addAttr(new DeprecatedAttr());
336}
337
Chris Lattner1c151132008-06-28 23:36:30 +0000338void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000339 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000340 if (Attr.getNumArgs() != 1) {
341 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000342 std::string("1"));
343 return;
344 }
345
Chris Lattner1c151132008-06-28 23:36:30 +0000346 Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000347 Arg = Arg->IgnoreParenCasts();
348 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
349
350 if (Str == 0 || Str->isWide()) {
Chris Lattner1c151132008-06-28 23:36:30 +0000351 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000352 "visibility", std::string("1"));
353 return;
354 }
355
356 const char *TypeStr = Str->getStrData();
357 unsigned TypeLen = Str->getByteLength();
358 VisibilityAttr::VisibilityTypes type;
359
360 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
361 type = VisibilityAttr::DefaultVisibility;
362 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
363 type = VisibilityAttr::HiddenVisibility;
364 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
365 type = VisibilityAttr::HiddenVisibility; // FIXME
366 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
367 type = VisibilityAttr::ProtectedVisibility;
368 else {
Chris Lattner1c151132008-06-28 23:36:30 +0000369 Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
Chris Lattner6953a072008-06-26 18:38:35 +0000370 "visibility", TypeStr);
371 return;
372 }
373
374 d->addAttr(new VisibilityAttr(type));
375}
376
Chris Lattner1c151132008-06-28 23:36:30 +0000377void Sema::HandleWeakAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000378 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000379 if (Attr.getNumArgs() != 0) {
380 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000381 std::string("0"));
382 return;
383 }
384
385 d->addAttr(new WeakAttr());
386}
387
Chris Lattner1c151132008-06-28 23:36:30 +0000388void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000389 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000390 if (Attr.getNumArgs() != 0) {
391 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000392 std::string("0"));
393 return;
394 }
395
396 d->addAttr(new DLLImportAttr());
397}
398
Chris Lattner1c151132008-06-28 23:36:30 +0000399void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000400 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000401 if (Attr.getNumArgs() != 0) {
402 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000403 std::string("0"));
404 return;
405 }
406
407 d->addAttr(new DLLExportAttr());
408}
409
Chris Lattner1c151132008-06-28 23:36:30 +0000410void Sema::HandleStdCallAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000411 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000412 if (Attr.getNumArgs() != 0) {
413 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000414 std::string("0"));
415 return;
416 }
417
418 d->addAttr(new StdCallAttr());
419}
420
Chris Lattner1c151132008-06-28 23:36:30 +0000421void Sema::HandleFastCallAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000422 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000423 if (Attr.getNumArgs() != 0) {
424 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000425 std::string("0"));
426 return;
427 }
428
429 d->addAttr(new FastCallAttr());
430}
431
Chris Lattner1c151132008-06-28 23:36:30 +0000432void Sema::HandleNothrowAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000433 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000434 if (Attr.getNumArgs() != 0) {
435 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000436 std::string("0"));
437 return;
438 }
439
440 d->addAttr(new NoThrowAttr());
441}
442
443/// Handle __attribute__((format(type,idx,firstarg))) attributes
444/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Chris Lattner1c151132008-06-28 23:36:30 +0000445void Sema::HandleFormatAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000446
Chris Lattner1c151132008-06-28 23:36:30 +0000447 if (!Attr.getParameterName()) {
448 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000449 "format", std::string("1"));
450 return;
451 }
452
Chris Lattner1c151132008-06-28 23:36:30 +0000453 if (Attr.getNumArgs() != 2) {
454 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000455 std::string("3"));
456 return;
457 }
458
459 // GCC ignores the format attribute on K&R style function
460 // prototypes, so we ignore it as well
461 const FunctionTypeProto *proto = getFunctionProto(d);
462
463 if (!proto) {
Chris Lattner1c151132008-06-28 23:36:30 +0000464 Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000465 "format", "function");
Chris Lattner6953a072008-06-26 18:38:35 +0000466 return;
467 }
468
469 // FIXME: in C++ the implicit 'this' function parameter also counts.
470 // this is needed in order to be compatible with GCC
471 // the index must start in 1 and the limit is numargs+1
472 unsigned NumArgs = proto->getNumArgs();
473 unsigned FirstIdx = 1;
474
Chris Lattner1c151132008-06-28 23:36:30 +0000475 const char *Format = Attr.getParameterName()->getName();
476 unsigned FormatLen = Attr.getParameterName()->getLength();
Chris Lattner6953a072008-06-26 18:38:35 +0000477
478 // Normalize the argument, __foo__ becomes foo.
479 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
480 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
481 Format += 2;
482 FormatLen -= 4;
483 }
484
485 bool Supported = false;
486 bool is_NSString = false;
487 bool is_strftime = false;
488
489 switch (FormatLen) {
490 default: break;
491 case 5:
492 Supported = !memcmp(Format, "scanf", 5);
493 break;
494 case 6:
495 Supported = !memcmp(Format, "printf", 6);
496 break;
497 case 7:
498 Supported = !memcmp(Format, "strfmon", 7);
499 break;
500 case 8:
501 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
502 (is_NSString = !memcmp(Format, "NSString", 8));
503 break;
504 }
505
506 if (!Supported) {
Chris Lattner1c151132008-06-28 23:36:30 +0000507 Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported,
508 "format", Attr.getParameterName()->getName());
Chris Lattner6953a072008-06-26 18:38:35 +0000509 return;
510 }
511
512 // checks for the 2nd argument
Chris Lattner1c151132008-06-28 23:36:30 +0000513 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000514 llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType()));
515 if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000516 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000517 "format", std::string("2"), IdxExpr->getSourceRange());
518 return;
519 }
520
521 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
Chris Lattner1c151132008-06-28 23:36:30 +0000522 Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
Chris Lattner6953a072008-06-26 18:38:35 +0000523 "format", std::string("2"), IdxExpr->getSourceRange());
524 return;
525 }
526
527 // FIXME: Do we need to bounds check?
528 unsigned ArgIdx = Idx.getZExtValue() - 1;
529
530 // make sure the format string is really a string
531 QualType Ty = proto->getArgType(ArgIdx);
532
533 if (is_NSString) {
534 // FIXME: do we need to check if the type is NSString*? What are
535 // the semantics?
536 if (!isNSStringType(Ty, Context)) {
537 // FIXME: Should highlight the actual expression that has the
538 // wrong type.
Chris Lattner1c151132008-06-28 23:36:30 +0000539 Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
Chris Lattner6953a072008-06-26 18:38:35 +0000540 IdxExpr->getSourceRange());
541 return;
542 }
543 } else if (!Ty->isPointerType() ||
544 !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
545 // FIXME: Should highlight the actual expression that has the
546 // wrong type.
Chris Lattner1c151132008-06-28 23:36:30 +0000547 Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
Chris Lattner6953a072008-06-26 18:38:35 +0000548 IdxExpr->getSourceRange());
549 return;
550 }
551
552 // check the 3rd argument
Chris Lattner1c151132008-06-28 23:36:30 +0000553 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
Chris Lattner6953a072008-06-26 18:38:35 +0000554 llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType()));
555 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) {
Chris Lattner1c151132008-06-28 23:36:30 +0000556 Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
Chris Lattner6953a072008-06-26 18:38:35 +0000557 "format", std::string("3"), FirstArgExpr->getSourceRange());
558 return;
559 }
560
561 // check if the function is variadic if the 3rd argument non-zero
562 if (FirstArg != 0) {
563 if (proto->isVariadic()) {
564 ++NumArgs; // +1 for ...
565 } else {
566 Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
567 return;
568 }
569 }
570
571 // strftime requires FirstArg to be 0 because it doesn't read from any variable
572 // the input is just the current time + the format string
573 if (is_strftime) {
574 if (FirstArg != 0) {
Chris Lattner1c151132008-06-28 23:36:30 +0000575 Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter,
Chris Lattner6953a072008-06-26 18:38:35 +0000576 FirstArgExpr->getSourceRange());
577 return;
578 }
579 // if 0 it disables parameter checking (to use with e.g. va_list)
580 } else if (FirstArg != 0 && FirstArg != NumArgs) {
Chris Lattner1c151132008-06-28 23:36:30 +0000581 Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds,
Chris Lattner6953a072008-06-26 18:38:35 +0000582 "format", std::string("3"), FirstArgExpr->getSourceRange());
583 return;
584 }
585
586 d->addAttr(new FormatAttr(std::string(Format, FormatLen),
587 Idx.getZExtValue(), FirstArg.getZExtValue()));
588}
589
590void Sema::HandleTransparentUnionAttribute(Decl *d,
Chris Lattner1c151132008-06-28 23:36:30 +0000591 const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000592 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000593 if (Attr.getNumArgs() != 0) {
594 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000595 std::string("0"));
596 return;
597 }
598
599 TypeDecl *decl = dyn_cast<TypeDecl>(d);
600
601 if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) {
Chris Lattner1c151132008-06-28 23:36:30 +0000602 Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
Chris Lattner6953a072008-06-26 18:38:35 +0000603 "transparent_union", "union");
604 return;
605 }
606
607 //QualType QTy = Context.getTypeDeclType(decl);
608 //const RecordType *Ty = QTy->getAsUnionType();
609
610// FIXME
611// Ty->addAttr(new TransparentUnionAttr());
612}
613
Chris Lattner1c151132008-06-28 23:36:30 +0000614void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000615 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000616 if (Attr.getNumArgs() != 1) {
617 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000618 std::string("1"));
619 return;
620 }
Chris Lattner1c151132008-06-28 23:36:30 +0000621 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
Chris Lattner6953a072008-06-26 18:38:35 +0000622 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
623
624 // Make sure that there is a string literal as the annotation's single
625 // argument.
626 if (!SE) {
Chris Lattner1c151132008-06-28 23:36:30 +0000627 Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
Chris Lattner6953a072008-06-26 18:38:35 +0000628 return;
629 }
630 d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
631 SE->getByteLength())));
632}
633
Chris Lattner1c151132008-06-28 23:36:30 +0000634void Sema::HandleAlignedAttribute(Decl *d, const AttributeList &Attr) {
Chris Lattner6953a072008-06-26 18:38:35 +0000635 // check the attribute arguments.
Chris Lattner1c151132008-06-28 23:36:30 +0000636 if (Attr.getNumArgs() > 1) {
637 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
Chris Lattner6953a072008-06-26 18:38:35 +0000638 std::string("1"));
639 return;
640 }
641
642 unsigned Align = 0;
Chris Lattner1c151132008-06-28 23:36:30 +0000643 if (Attr.getNumArgs() == 0) {
Chris Lattner6953a072008-06-26 18:38:35 +0000644 // FIXME: This should be the target specific maximum alignment.
645 // (For now we just use 128 bits which is the maximum on X86.
646 Align = 128;
647 return;
Chris Lattner6953a072008-06-26 18:38:35 +0000648 }
Chris Lattnerb0011ca2008-06-28 23:50:44 +0000649
650 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
651 llvm::APSInt Alignment(32);
652 if (!alignmentExpr->isIntegerConstantExpr(Alignment, Context)) {
653 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int,
654 "aligned", alignmentExpr->getSourceRange());
655 return;
656 }
657 d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
Chris Lattner6953a072008-06-26 18:38:35 +0000658}
Chris Lattnerdc789562008-06-27 22:18:37 +0000659
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000660/// HandleModeAttribute - This attribute modifies the width of a decl with
661/// primitive type.
Chris Lattnerdc789562008-06-27 22:18:37 +0000662///
663/// Despite what would be logical, the mode attribute is a decl attribute,
664/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
665/// 'G' be HImode, not an intermediate pointer.
666///
667void Sema::HandleModeAttribute(Decl *D, const AttributeList &Attr) {
668 // This attribute isn't documented, but glibc uses it. It changes
669 // the width of an int or unsigned int to the specified size.
670
671 // Check that there aren't any arguments
672 if (Attr.getNumArgs() != 0) {
673 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
674 std::string("0"));
675 return;
676 }
677
678 IdentifierInfo *Name = Attr.getParameterName();
679 if (!Name) {
680 Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
681 return;
682 }
683 const char *Str = Name->getName();
684 unsigned Len = Name->getLength();
685
686 // Normalize the attribute name, __foo__ becomes foo.
687 if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
688 Str[Len - 2] == '_' && Str[Len - 1] == '_') {
689 Str += 2;
690 Len -= 4;
691 }
692
693 unsigned DestWidth = 0;
694 bool IntegerMode = true;
695 switch (Len) {
696 case 2:
697 if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; }
698 if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
699 if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
700 if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
701 if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
702 if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
703 if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
704 if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
705 if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
706 break;
707 case 4:
708 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
709 // pointer on PIC16 and other embedded platforms.
710 if (!memcmp(Str, "word", 4))
711 DestWidth = Context.Target.getPointerWidth(0);
712 if (!memcmp(Str, "byte", 4))
713 DestWidth = Context.Target.getCharWidth();
714 break;
715 case 7:
716 if (!memcmp(Str, "pointer", 7))
717 DestWidth = Context.Target.getPointerWidth(0);
718 break;
719 }
720
721 QualType OldTy;
722 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
723 OldTy = TD->getUnderlyingType();
724 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
725 OldTy = VD->getType();
726 else {
Chris Lattner8ed14aa2008-06-28 23:48:25 +0000727 Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode",
Chris Lattnerdc789562008-06-27 22:18:37 +0000728 SourceRange(Attr.getLoc(), Attr.getLoc()));
729 return;
730 }
731
732 // FIXME: Need proper fixed-width types
733 QualType NewTy;
734 switch (DestWidth) {
735 case 0:
736 Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName());
737 return;
738 default:
739 Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName());
740 return;
741 case 8:
742 assert(IntegerMode);
743 if (OldTy->isSignedIntegerType())
744 NewTy = Context.SignedCharTy;
745 else
746 NewTy = Context.UnsignedCharTy;
747 break;
748 case 16:
749 assert(IntegerMode);
750 if (OldTy->isSignedIntegerType())
751 NewTy = Context.ShortTy;
752 else
753 NewTy = Context.UnsignedShortTy;
754 break;
755 case 32:
756 if (!IntegerMode)
757 NewTy = Context.FloatTy;
758 else if (OldTy->isSignedIntegerType())
759 NewTy = Context.IntTy;
760 else
761 NewTy = Context.UnsignedIntTy;
762 break;
763 case 64:
764 if (!IntegerMode)
765 NewTy = Context.DoubleTy;
766 else if (OldTy->isSignedIntegerType())
767 NewTy = Context.LongLongTy;
768 else
769 NewTy = Context.UnsignedLongLongTy;
770 break;
771 }
772
773 if (!OldTy->getAsBuiltinType())
774 Diag(Attr.getLoc(), diag::err_mode_not_primitive);
775 else if (!(IntegerMode && OldTy->isIntegerType()) &&
776 !(!IntegerMode && OldTy->isFloatingType())) {
777 Diag(Attr.getLoc(), diag::err_mode_wrong_type);
778 }
779
780 // Install the new type.
781 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
782 TD->setUnderlyingType(NewTy);
783 else
784 cast<ValueDecl>(D)->setType(NewTy);
785}