1 //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements decl-related attribute processing.
12 //===----------------------------------------------------------------------===//
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/Basic/TargetInfo.h"
19 #include "clang/Parse/DeclSpec.h"
20 #include "llvm/ADT/StringExtras.h"
21 using namespace clang;
23 //===----------------------------------------------------------------------===//
25 //===----------------------------------------------------------------------===//
27 static const FunctionType *getFunctionType(const Decl *d,
28 bool blocksToo = true) {
30 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
32 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
34 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
35 Ty = decl->getUnderlyingType();
39 if (Ty->isFunctionPointerType())
40 Ty = Ty->getAs<PointerType>()->getPointeeType();
41 else if (blocksToo && Ty->isBlockPointerType())
42 Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
44 return Ty->getAs<FunctionType>();
47 // FIXME: We should provide an abstraction around a method or function
48 // to provide the following bits of information.
50 /// isFunctionOrMethod - Return true if the given decl has function
51 /// type (function or function-typed variable).
52 static bool isFunction(const Decl *d) {
53 return getFunctionType(d, false) != NULL;
56 /// isFunctionOrMethod - Return true if the given decl has function
57 /// type (function or function-typed variable) or an Objective-C
59 static bool isFunctionOrMethod(const Decl *d) {
60 return isFunction(d)|| isa<ObjCMethodDecl>(d);
63 /// isFunctionOrMethodOrBlock - Return true if the given decl has function
64 /// type (function or function-typed variable) or an Objective-C
65 /// method or a block.
66 static bool isFunctionOrMethodOrBlock(const Decl *d) {
67 if (isFunctionOrMethod(d))
69 // check for block is more involved.
70 if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
71 QualType Ty = V->getType();
72 return Ty->isBlockPointerType();
74 return isa<BlockDecl>(d);
77 /// hasFunctionProto - Return true if the given decl has a argument
78 /// information. This decl should have already passed
79 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
80 static bool hasFunctionProto(const Decl *d) {
81 if (const FunctionType *FnTy = getFunctionType(d))
82 return isa<FunctionProtoType>(FnTy);
84 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
89 /// getFunctionOrMethodNumArgs - Return number of function or method
90 /// arguments. It is an error to call this on a K&R function (use
91 /// hasFunctionProto first).
92 static unsigned getFunctionOrMethodNumArgs(const Decl *d) {
93 if (const FunctionType *FnTy = getFunctionType(d))
94 return cast<FunctionProtoType>(FnTy)->getNumArgs();
95 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
96 return BD->getNumParams();
97 return cast<ObjCMethodDecl>(d)->param_size();
100 static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
101 if (const FunctionType *FnTy = getFunctionType(d))
102 return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
103 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
104 return BD->getParamDecl(Idx)->getType();
106 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
109 static QualType getFunctionOrMethodResultType(const Decl *d) {
110 if (const FunctionType *FnTy = getFunctionType(d))
111 return cast<FunctionProtoType>(FnTy)->getResultType();
112 return cast<ObjCMethodDecl>(d)->getResultType();
115 static bool isFunctionOrMethodVariadic(const Decl *d) {
116 if (const FunctionType *FnTy = getFunctionType(d)) {
117 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
118 return proto->isVariadic();
119 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
120 return BD->IsVariadic();
122 return cast<ObjCMethodDecl>(d)->isVariadic();
126 static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
127 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
131 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>();
135 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
137 // FIXME: Should we walk the chain of classes?
138 return ClsName == &Ctx.Idents.get("NSString") ||
139 ClsName == &Ctx.Idents.get("NSMutableString");
142 static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
143 const PointerType *PT = T->getAs<PointerType>();
147 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
151 const RecordDecl *RD = RT->getDecl();
152 if (RD->getTagKind() != TagDecl::TK_struct)
155 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
158 //===----------------------------------------------------------------------===//
159 // Attribute Implementations
160 //===----------------------------------------------------------------------===//
162 // FIXME: All this manual attribute parsing code is gross. At the
163 // least add some helper functions to check most argument patterns (#
164 // and types of args).
166 static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
167 const AttributeList &Attr, Sema &S) {
168 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
170 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
174 QualType curType = tDecl->getUnderlyingType();
178 // Special case where the argument is a template id.
179 if (Attr.getParameterName()) {
180 sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(),
181 Attr.getParameterName(),
182 false, 0, false).takeAs<Expr>();
184 // check the attribute arguments.
185 if (Attr.getNumArgs() != 1) {
186 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
189 sizeExpr = static_cast<Expr *>(Attr.getArg(0));
192 // Instantiate/Install the vector type, and let Sema build the type for us.
193 // This will run the reguired checks.
194 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
196 // FIXME: preserve the old source info.
197 tDecl->setTypeDeclaratorInfo(S.Context.getTrivialDeclaratorInfo(T));
199 // Remember this typedef decl, we will need it later for diagnostics.
200 S.ExtVectorDecls.push_back(tDecl);
205 /// HandleVectorSizeAttribute - this attribute is only applicable to integral
206 /// and float scalars, although arrays, pointers, and function return values are
207 /// allowed in conjunction with this construct. Aggregates with this attribute
208 /// are invalid, even if they are of the same size as a corresponding scalar.
209 /// The raw attribute should contain precisely 1 argument, the vector size for
210 /// the variable, measured in bytes. If curType and rawAttr are well formed,
211 /// this routine will return a new vector type.
212 static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
214 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
215 CurType = VD->getType();
216 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
217 CurType = TD->getUnderlyingType();
219 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
220 << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
224 // Check the attribute arugments.
225 if (Attr.getNumArgs() != 1) {
226 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
229 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
230 llvm::APSInt vecSize(32);
231 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
232 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
233 << "vector_size" << sizeExpr->getSourceRange();
236 // navigate to the base type - we need to provide for vector pointers, vector
237 // arrays, and functions returning vectors.
238 if (CurType->isPointerType() || CurType->isArrayType() ||
239 CurType->isFunctionType()) {
240 S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType;
242 /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
244 if (PointerType *PT = dyn_cast<PointerType>(canonType))
245 canonType = PT->getPointeeType().getTypePtr();
246 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
247 canonType = AT->getElementType().getTypePtr();
248 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
249 canonType = FT->getResultType().getTypePtr();
250 } while (canonType->isPointerType() || canonType->isArrayType() ||
251 canonType->isFunctionType());
254 // the base type must be integer or float, and can't already be a vector.
255 if (CurType->isVectorType() ||
256 (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
257 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
260 unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
261 // vecSize is specified in bytes - convert to bits.
262 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
264 // the vector size needs to be an integral multiple of the type size.
265 if (vectorSize % typeSize) {
266 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
267 << sizeExpr->getSourceRange();
270 if (vectorSize == 0) {
271 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
272 << sizeExpr->getSourceRange();
276 // Success! Instantiate the vector type, the number of elements is > 0, and
277 // not required to be a power of 2, unlike GCC.
278 CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
280 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
281 VD->setType(CurType);
283 // FIXME: preserve existing source info.
284 DeclaratorInfo *DInfo = S.Context.getTrivialDeclaratorInfo(CurType);
285 cast<TypedefDecl>(D)->setTypeDeclaratorInfo(DInfo);
289 static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
290 // check the attribute arguments.
291 if (Attr.getNumArgs() > 0) {
292 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
296 if (TagDecl *TD = dyn_cast<TagDecl>(d))
297 TD->addAttr(::new (S.Context) PackedAttr);
298 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
299 // If the alignment is less than or equal to 8 bits, the packed attribute
301 if (!FD->getType()->isIncompleteType() &&
302 S.Context.getTypeAlign(FD->getType()) <= 8)
303 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
304 << Attr.getName() << FD->getType();
306 FD->addAttr(::new (S.Context) PackedAttr);
308 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
311 static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
312 // check the attribute arguments.
313 if (Attr.getNumArgs() > 0) {
314 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
318 // The IBOutlet attribute only applies to instance variables of Objective-C
320 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
321 d->addAttr(::new (S.Context) IBOutletAttr());
323 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
326 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
327 // GCC ignores the nonnull attribute on K&R style function prototypes, so we
329 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
330 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
331 << Attr.getName() << 0 /*function*/;
335 unsigned NumArgs = getFunctionOrMethodNumArgs(d);
337 // The nonnull attribute only applies to pointers.
338 llvm::SmallVector<unsigned, 10> NonNullArgs;
340 for (AttributeList::arg_iterator I=Attr.arg_begin(),
341 E=Attr.arg_end(); I!=E; ++I) {
344 // The argument must be an integer constant expression.
345 Expr *Ex = static_cast<Expr *>(*I);
346 llvm::APSInt ArgNum(32);
347 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
348 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
349 << "nonnull" << Ex->getSourceRange();
353 unsigned x = (unsigned) ArgNum.getZExtValue();
355 if (x < 1 || x > NumArgs) {
356 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
357 << "nonnull" << I.getArgNum() << Ex->getSourceRange();
363 // Is the function argument a pointer type?
364 QualType T = getFunctionOrMethodArgType(d, x);
365 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
366 // FIXME: Should also highlight argument in decl.
367 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
368 << "nonnull" << Ex->getSourceRange();
372 NonNullArgs.push_back(x);
375 // If no arguments were specified to __attribute__((nonnull)) then all pointer
376 // arguments have a nonnull attribute.
377 if (NonNullArgs.empty()) {
378 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
379 QualType T = getFunctionOrMethodArgType(d, I);
380 if (T->isAnyPointerType() || T->isBlockPointerType())
381 NonNullArgs.push_back(I);
384 if (NonNullArgs.empty()) {
385 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
390 unsigned* start = &NonNullArgs[0];
391 unsigned size = NonNullArgs.size();
392 std::sort(start, start + size);
393 d->addAttr(::new (S.Context) NonNullAttr(start, size));
396 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
397 // check the attribute arguments.
398 if (Attr.getNumArgs() != 1) {
399 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
403 Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
404 Arg = Arg->IgnoreParenCasts();
405 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
407 if (Str == 0 || Str->isWide()) {
408 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
413 const char *Alias = Str->getStrData();
414 unsigned AliasLen = Str->getByteLength();
416 // FIXME: check if target symbol exists in current file
418 d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
421 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
423 // check the attribute arguments.
424 if (Attr.getNumArgs() != 0) {
425 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
429 if (!isa<FunctionDecl>(d)) {
430 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
431 << Attr.getName() << 0 /*function*/;
435 d->addAttr(::new (S.Context) AlwaysInlineAttr());
438 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
439 // check the attribute arguments.
440 if (Attr.getNumArgs() != 0) {
441 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
445 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
446 QualType RetTy = FD->getResultType();
447 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
448 d->addAttr(::new (S.Context) MallocAttr());
453 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
456 static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
458 // check the attribute arguments.
459 if (Attr.getNumArgs() != 0) {
460 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
464 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
465 ValueDecl *VD = dyn_cast<ValueDecl>(d);
466 if (VD == 0 || !VD->getType()->isBlockPointerType()) {
467 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
468 << Attr.getName() << 0 /*function*/;
476 static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
477 if (HandleCommonNoReturnAttr(d, Attr, S))
478 d->addAttr(::new (S.Context) NoReturnAttr());
481 static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
483 if (HandleCommonNoReturnAttr(d, Attr, S))
484 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
487 static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
488 // check the attribute arguments.
489 if (Attr.getNumArgs() != 0) {
490 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
494 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
495 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
496 << Attr.getName() << 2 /*variable and function*/;
500 d->addAttr(::new (S.Context) UnusedAttr());
503 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
504 // check the attribute arguments.
505 if (Attr.getNumArgs() != 0) {
506 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
510 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
511 if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
512 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
515 } else if (!isFunctionOrMethod(d)) {
516 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
517 << Attr.getName() << 2 /*variable and function*/;
521 d->addAttr(::new (S.Context) UsedAttr());
524 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
525 // check the attribute arguments.
526 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
527 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
532 int priority = 65535; // FIXME: Do not hardcode such constants.
533 if (Attr.getNumArgs() > 0) {
534 Expr *E = static_cast<Expr *>(Attr.getArg(0));
535 llvm::APSInt Idx(32);
536 if (!E->isIntegerConstantExpr(Idx, S.Context)) {
537 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
538 << "constructor" << 1 << E->getSourceRange();
541 priority = Idx.getZExtValue();
544 if (!isa<FunctionDecl>(d)) {
545 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
546 << Attr.getName() << 0 /*function*/;
550 d->addAttr(::new (S.Context) ConstructorAttr(priority));
553 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
554 // check the attribute arguments.
555 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
556 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
561 int priority = 65535; // FIXME: Do not hardcode such constants.
562 if (Attr.getNumArgs() > 0) {
563 Expr *E = static_cast<Expr *>(Attr.getArg(0));
564 llvm::APSInt Idx(32);
565 if (!E->isIntegerConstantExpr(Idx, S.Context)) {
566 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
567 << "destructor" << 1 << E->getSourceRange();
570 priority = Idx.getZExtValue();
573 if (!isa<FunctionDecl>(d)) {
574 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
575 << Attr.getName() << 0 /*function*/;
579 d->addAttr(::new (S.Context) DestructorAttr(priority));
582 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
583 // check the attribute arguments.
584 if (Attr.getNumArgs() != 0) {
585 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
589 d->addAttr(::new (S.Context) DeprecatedAttr());
592 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
593 // check the attribute arguments.
594 if (Attr.getNumArgs() != 0) {
595 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
599 d->addAttr(::new (S.Context) UnavailableAttr());
602 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
603 // check the attribute arguments.
604 if (Attr.getNumArgs() != 1) {
605 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
609 Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
610 Arg = Arg->IgnoreParenCasts();
611 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
613 if (Str == 0 || Str->isWide()) {
614 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
615 << "visibility" << 1;
619 const char *TypeStr = Str->getStrData();
620 unsigned TypeLen = Str->getByteLength();
621 VisibilityAttr::VisibilityTypes type;
623 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
624 type = VisibilityAttr::DefaultVisibility;
625 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
626 type = VisibilityAttr::HiddenVisibility;
627 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
628 type = VisibilityAttr::HiddenVisibility; // FIXME
629 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
630 type = VisibilityAttr::ProtectedVisibility;
632 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
636 d->addAttr(::new (S.Context) VisibilityAttr(type));
639 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
641 if (Attr.getNumArgs() != 0) {
642 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
646 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
648 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
652 D->addAttr(::new (S.Context) ObjCExceptionAttr());
655 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
656 if (Attr.getNumArgs() != 0) {
657 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
660 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
661 QualType T = TD->getUnderlyingType();
662 if (!T->isPointerType() ||
663 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
664 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
668 D->addAttr(::new (S.Context) ObjCNSObjectAttr());
672 HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
673 if (Attr.getNumArgs() != 0) {
674 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
678 if (!isa<FunctionDecl>(D)) {
679 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
683 D->addAttr(::new (S.Context) OverloadableAttr());
686 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
687 if (!Attr.getParameterName()) {
688 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
693 if (Attr.getNumArgs() != 0) {
694 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
698 BlocksAttr::BlocksAttrTypes type;
699 if (Attr.getParameterName()->isStr("byref"))
700 type = BlocksAttr::ByRef;
702 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
703 << "blocks" << Attr.getParameterName();
707 d->addAttr(::new (S.Context) BlocksAttr(type));
710 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
711 // check the attribute arguments.
712 if (Attr.getNumArgs() > 2) {
713 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
719 if (Attr.getNumArgs() > 0) {
720 Expr *E = static_cast<Expr *>(Attr.getArg(0));
721 llvm::APSInt Idx(32);
722 if (!E->isIntegerConstantExpr(Idx, S.Context)) {
723 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
724 << "sentinel" << 1 << E->getSourceRange();
727 sentinel = Idx.getZExtValue();
730 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
731 << E->getSourceRange();
737 if (Attr.getNumArgs() > 1) {
738 Expr *E = static_cast<Expr *>(Attr.getArg(1));
739 llvm::APSInt Idx(32);
740 if (!E->isIntegerConstantExpr(Idx, S.Context)) {
741 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
742 << "sentinel" << 2 << E->getSourceRange();
745 nullPos = Idx.getZExtValue();
747 if (nullPos > 1 || nullPos < 0) {
748 // FIXME: This error message could be improved, it would be nice
749 // to say what the bounds actually are.
750 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
751 << E->getSourceRange();
756 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
757 const FunctionType *FT = FD->getType()->getAs<FunctionType>();
758 assert(FT && "FunctionDecl has non-function type?");
760 if (isa<FunctionNoProtoType>(FT)) {
761 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
765 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
766 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
769 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
770 if (!MD->isVariadic()) {
771 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
774 } else if (isa<BlockDecl>(d)) {
775 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
778 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
779 QualType Ty = V->getType();
780 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
781 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
782 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
783 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
784 int m = Ty->isFunctionPointerType() ? 0 : 1;
785 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
789 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
790 << Attr.getName() << 6 /*function, method or block */;
794 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
795 << Attr.getName() << 6 /*function, method or block */;
798 d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
801 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
802 // check the attribute arguments.
803 if (Attr.getNumArgs() != 0) {
804 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
808 // TODO: could also be applied to methods?
809 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
811 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
812 << Attr.getName() << 0 /*function*/;
816 Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
819 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
820 // check the attribute arguments.
821 if (Attr.getNumArgs() != 0) {
822 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
826 /* weak only applies to non-static declarations */
827 bool isStatic = false;
828 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
829 isStatic = VD->getStorageClass() == VarDecl::Static;
830 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
831 isStatic = FD->getStorageClass() == FunctionDecl::Static;
834 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) <<
835 dyn_cast<NamedDecl>(D)->getNameAsString();
839 // TODO: could also be applied to methods?
840 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
841 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
842 << Attr.getName() << 2 /*variable and function*/;
846 D->addAttr(::new (S.Context) WeakAttr());
849 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
850 // check the attribute arguments.
851 if (Attr.getNumArgs() != 0) {
852 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
856 // weak_import only applies to variable & function declarations.
858 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
859 isDef = (!VD->hasExternalStorage() || VD->getInit());
860 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
861 isDef = FD->getBody();
862 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
863 // We ignore weak import on properties and methods
866 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
867 << Attr.getName() << 2 /*variable and function*/;
871 // Merge should handle any subsequent violations.
873 S.Diag(Attr.getLoc(),
874 diag::warn_attribute_weak_import_invalid_on_definition)
875 << "weak_import" << 2 /*variable and function*/;
879 D->addAttr(::new (S.Context) WeakImportAttr());
882 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
883 // check the attribute arguments.
884 if (Attr.getNumArgs() != 0) {
885 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
889 // Attribute can be applied only to functions or variables.
890 if (isa<VarDecl>(D)) {
891 D->addAttr(::new (S.Context) DLLImportAttr());
895 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
897 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
898 << Attr.getName() << 2 /*variable and function*/;
902 // Currently, the dllimport attribute is ignored for inlined functions.
903 // Warning is emitted.
904 if (FD->isInlineSpecified()) {
905 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
909 // The attribute is also overridden by a subsequent declaration as dllexport.
910 // Warning is emitted.
911 for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
912 nextAttr = nextAttr->getNext()) {
913 if (nextAttr->getKind() == AttributeList::AT_dllexport) {
914 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
919 if (D->getAttr<DLLExportAttr>()) {
920 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
924 D->addAttr(::new (S.Context) DLLImportAttr());
927 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
928 // check the attribute arguments.
929 if (Attr.getNumArgs() != 0) {
930 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
934 // Attribute can be applied only to functions or variables.
935 if (isa<VarDecl>(D)) {
936 D->addAttr(::new (S.Context) DLLExportAttr());
940 FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
942 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
943 << Attr.getName() << 2 /*variable and function*/;
947 // Currently, the dllexport attribute is ignored for inlined functions, unless
948 // the -fkeep-inline-functions flag has been used. Warning is emitted;
949 if (FD->isInlineSpecified()) {
950 // FIXME: ... unless the -fkeep-inline-functions flag has been used.
951 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
955 D->addAttr(::new (S.Context) DLLExportAttr());
958 static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
960 // Attribute has 3 arguments.
961 if (Attr.getNumArgs() != 3) {
962 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
967 for (unsigned i = 0; i < 3; ++i) {
968 Expr *E = static_cast<Expr *>(Attr.getArg(i));
969 llvm::APSInt ArgNum(32);
970 if (!E->isIntegerConstantExpr(ArgNum, S.Context)) {
971 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
972 << "reqd_work_group_size" << E->getSourceRange();
975 WGSize[i] = (unsigned) ArgNum.getZExtValue();
977 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
981 static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
982 // Attribute has no arguments.
983 if (Attr.getNumArgs() != 1) {
984 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
988 // Make sure that there is a string literal as the sections's single
990 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
991 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
993 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
997 std::string SectionStr(SE->getStrData(), SE->getByteLength());
999 // If the target wants to validate the section specifier, make it happen.
1000 std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr);
1001 if (Error.empty()) {
1002 D->addAttr(::new (S.Context) SectionAttr(SectionStr));
1006 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1011 static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1012 // Attribute has no arguments.
1013 if (Attr.getNumArgs() != 0) {
1014 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1018 // Attribute can be applied only to functions.
1019 if (!isa<FunctionDecl>(d)) {
1020 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1021 << Attr.getName() << 0 /*function*/;
1025 // stdcall and fastcall attributes are mutually incompatible.
1026 if (d->getAttr<FastCallAttr>()) {
1027 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1028 << "stdcall" << "fastcall";
1032 d->addAttr(::new (S.Context) StdCallAttr());
1035 /// Diagnose the use of a non-standard calling convention on the given
1037 static void DiagnoseCConv(FunctionDecl *D, const char *CConv,
1038 SourceLocation Loc, Sema &S) {
1039 if (!D->hasPrototype()) {
1040 S.Diag(Loc, diag::err_cconv_knr) << CConv;
1044 const FunctionProtoType *T = D->getType()->getAs<FunctionProtoType>();
1045 if (T->isVariadic()) {
1046 S.Diag(Loc, diag::err_cconv_varargs) << CConv;
1051 static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1052 // Attribute has no arguments.
1053 if (Attr.getNumArgs() != 0) {
1054 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1058 if (!isa<FunctionDecl>(d)) {
1059 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1060 << Attr.getName() << 0 /*function*/;
1064 DiagnoseCConv(cast<FunctionDecl>(d), "fastcall", Attr.getLoc(), S);
1066 // stdcall and fastcall attributes are mutually incompatible.
1067 if (d->getAttr<StdCallAttr>()) {
1068 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1069 << "fastcall" << "stdcall";
1073 d->addAttr(::new (S.Context) FastCallAttr());
1076 static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1077 // check the attribute arguments.
1078 if (Attr.getNumArgs() != 0) {
1079 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1083 d->addAttr(::new (S.Context) NoThrowAttr());
1086 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1087 // check the attribute arguments.
1088 if (Attr.getNumArgs() != 0) {
1089 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1093 d->addAttr(::new (S.Context) ConstAttr());
1096 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1097 // check the attribute arguments.
1098 if (Attr.getNumArgs() != 0) {
1099 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1103 d->addAttr(::new (S.Context) PureAttr());
1106 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1107 // Match gcc which ignores cleanup attrs when compiling C++.
1108 if (S.getLangOptions().CPlusPlus)
1111 if (!Attr.getParameterName()) {
1112 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1116 if (Attr.getNumArgs() != 0) {
1117 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1121 VarDecl *VD = dyn_cast<VarDecl>(d);
1123 if (!VD || !VD->hasLocalStorage()) {
1124 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1128 // Look up the function
1129 NamedDecl *CleanupDecl
1130 = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1131 Sema::LookupOrdinaryName);
1133 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1134 Attr.getParameterName();
1138 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1140 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1141 Attr.getParameterName();
1145 if (FD->getNumParams() != 1) {
1146 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1147 Attr.getParameterName();
1151 // We're currently more strict than GCC about what function types we accept.
1152 // If this ever proves to be a problem it should be easy to fix.
1153 QualType Ty = S.Context.getPointerType(VD->getType());
1154 QualType ParamTy = FD->getParamDecl(0)->getType();
1155 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
1156 S.Diag(Attr.getLoc(),
1157 diag::err_attribute_cleanup_func_arg_incompatible_type) <<
1158 Attr.getParameterName() << ParamTy << Ty;
1162 d->addAttr(::new (S.Context) CleanupAttr(FD));
1165 /// Handle __attribute__((format_arg((idx)))) attribute based on
1166 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1167 static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1168 if (Attr.getNumArgs() != 1) {
1169 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1172 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
1173 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1174 << Attr.getName() << 0 /*function*/;
1177 // FIXME: in C++ the implicit 'this' function parameter also counts. this is
1178 // needed in order to be compatible with GCC the index must start with 1.
1179 unsigned NumArgs = getFunctionOrMethodNumArgs(d);
1180 unsigned FirstIdx = 1;
1181 // checks for the 2nd argument
1182 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1183 llvm::APSInt Idx(32);
1184 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1185 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1186 << "format" << 2 << IdxExpr->getSourceRange();
1190 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1191 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1192 << "format" << 2 << IdxExpr->getSourceRange();
1196 unsigned ArgIdx = Idx.getZExtValue() - 1;
1198 // make sure the format string is really a string
1199 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1201 bool not_nsstring_type = !isNSStringType(Ty, S.Context);
1202 if (not_nsstring_type &&
1203 !isCFStringType(Ty, S.Context) &&
1204 (!Ty->isPointerType() ||
1205 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
1206 // FIXME: Should highlight the actual expression that has the wrong type.
1207 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1208 << (not_nsstring_type ? "a string type" : "an NSString")
1209 << IdxExpr->getSourceRange();
1212 Ty = getFunctionOrMethodResultType(d);
1213 if (!isNSStringType(Ty, S.Context) &&
1214 !isCFStringType(Ty, S.Context) &&
1215 (!Ty->isPointerType() ||
1216 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
1217 // FIXME: Should highlight the actual expression that has the wrong type.
1218 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1219 << (not_nsstring_type ? "string type" : "NSString")
1220 << IdxExpr->getSourceRange();
1224 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
1227 enum FormatAttrKind {
1235 /// getFormatAttrKind - Map from format attribute names to supported format
1237 static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
1238 // Check for formats that get handled specially.
1239 if (Format == "NSString")
1240 return NSStringFormat;
1241 if (Format == "CFString")
1242 return CFStringFormat;
1243 if (Format == "strftime")
1244 return StrftimeFormat;
1246 // Otherwise, check for supported formats.
1247 if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
1248 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
1249 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1250 Format == "zcmn_err")
1251 return SupportedFormat;
1253 return InvalidFormat;
1256 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1257 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1258 static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1260 if (!Attr.getParameterName()) {
1261 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1266 if (Attr.getNumArgs() != 2) {
1267 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1271 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1272 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1273 << Attr.getName() << 0 /*function*/;
1277 unsigned NumArgs = getFunctionOrMethodNumArgs(d);
1278 unsigned FirstIdx = 1;
1280 llvm::StringRef Format = Attr.getParameterName()->getName();
1282 // Normalize the argument, __foo__ becomes foo.
1283 if (Format.startswith("__") && Format.endswith("__"))
1284 Format = Format.substr(2, Format.size() - 4);
1286 // Check for supported formats.
1287 FormatAttrKind Kind = getFormatAttrKind(Format);
1288 if (Kind == InvalidFormat) {
1289 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1290 << "format" << Attr.getParameterName()->getName();
1294 // checks for the 2nd argument
1295 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1296 llvm::APSInt Idx(32);
1297 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1298 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1299 << "format" << 2 << IdxExpr->getSourceRange();
1303 // FIXME: We should handle the implicit 'this' parameter in a more generic
1304 // way that can be used for other arguments.
1305 bool HasImplicitThisParam = false;
1306 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) {
1307 if (MD->isInstance()) {
1308 HasImplicitThisParam = true;
1313 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1314 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1315 << "format" << 2 << IdxExpr->getSourceRange();
1319 // FIXME: Do we need to bounds check?
1320 unsigned ArgIdx = Idx.getZExtValue() - 1;
1322 if (HasImplicitThisParam) ArgIdx--;
1324 // make sure the format string is really a string
1325 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1327 if (Kind == CFStringFormat) {
1328 if (!isCFStringType(Ty, S.Context)) {
1329 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1330 << "a CFString" << IdxExpr->getSourceRange();
1333 } else if (Kind == NSStringFormat) {
1334 // FIXME: do we need to check if the type is NSString*? What are the
1336 if (!isNSStringType(Ty, S.Context)) {
1337 // FIXME: Should highlight the actual expression that has the wrong type.
1338 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1339 << "an NSString" << IdxExpr->getSourceRange();
1342 } else if (!Ty->isPointerType() ||
1343 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1344 // FIXME: Should highlight the actual expression that has the wrong type.
1345 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1346 << "a string type" << IdxExpr->getSourceRange();
1350 // check the 3rd argument
1351 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1352 llvm::APSInt FirstArg(32);
1353 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1354 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1355 << "format" << 3 << FirstArgExpr->getSourceRange();
1359 // check if the function is variadic if the 3rd argument non-zero
1360 if (FirstArg != 0) {
1361 if (isFunctionOrMethodVariadic(d)) {
1362 ++NumArgs; // +1 for ...
1364 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1369 // strftime requires FirstArg to be 0 because it doesn't read from any
1370 // variable the input is just the current time + the format string.
1371 if (Kind == StrftimeFormat) {
1372 if (FirstArg != 0) {
1373 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1374 << FirstArgExpr->getSourceRange();
1377 // if 0 it disables parameter checking (to use with e.g. va_list)
1378 } else if (FirstArg != 0 && FirstArg != NumArgs) {
1379 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1380 << "format" << 3 << FirstArgExpr->getSourceRange();
1384 d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(),
1385 FirstArg.getZExtValue()));
1388 static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1390 // check the attribute arguments.
1391 if (Attr.getNumArgs() != 0) {
1392 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1396 // Try to find the underlying union declaration.
1398 TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1399 if (TD && TD->getUnderlyingType()->isUnionType())
1400 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1402 RD = dyn_cast<RecordDecl>(d);
1404 if (!RD || !RD->isUnion()) {
1405 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1406 << Attr.getName() << 1 /*union*/;
1410 if (!RD->isDefinition()) {
1411 S.Diag(Attr.getLoc(),
1412 diag::warn_transparent_union_attribute_not_definition);
1416 RecordDecl::field_iterator Field = RD->field_begin(),
1417 FieldEnd = RD->field_end();
1418 if (Field == FieldEnd) {
1419 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
1423 FieldDecl *FirstField = *Field;
1424 QualType FirstType = FirstField->getType();
1425 if (FirstType->isFloatingType() || FirstType->isVectorType()) {
1426 S.Diag(FirstField->getLocation(),
1427 diag::warn_transparent_union_attribute_floating);
1431 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
1432 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
1433 for (; Field != FieldEnd; ++Field) {
1434 QualType FieldType = Field->getType();
1435 if (S.Context.getTypeSize(FieldType) != FirstSize ||
1436 S.Context.getTypeAlign(FieldType) != FirstAlign) {
1437 // Warn if we drop the attribute.
1438 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1439 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
1440 : S.Context.getTypeAlign(FieldType);
1441 S.Diag(Field->getLocation(),
1442 diag::warn_transparent_union_attribute_field_size_align)
1443 << isSize << Field->getDeclName() << FieldBits;
1444 unsigned FirstBits = isSize? FirstSize : FirstAlign;
1445 S.Diag(FirstField->getLocation(),
1446 diag::note_transparent_union_first_field_size_align)
1447 << isSize << FirstBits;
1452 RD->addAttr(::new (S.Context) TransparentUnionAttr());
1455 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1456 // check the attribute arguments.
1457 if (Attr.getNumArgs() != 1) {
1458 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1461 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0));
1462 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1464 // Make sure that there is a string literal as the annotation's single
1467 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
1470 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
1471 SE->getByteLength())));
1474 static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1475 // check the attribute arguments.
1476 if (Attr.getNumArgs() > 1) {
1477 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1482 if (Attr.getNumArgs() == 0) {
1483 // FIXME: This should be the target specific maximum alignment.
1484 // (For now we just use 128 bits which is the maximum on X86).
1486 d->addAttr(::new (S.Context) AlignedAttr(Align));
1490 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
1491 llvm::APSInt Alignment(32);
1492 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1493 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1494 << "aligned" << alignmentExpr->getSourceRange();
1497 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1498 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1499 << alignmentExpr->getSourceRange();
1503 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
1506 /// HandleModeAttr - This attribute modifies the width of a decl with primitive
1509 /// Despite what would be logical, the mode attribute is a decl attribute, not a
1510 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1511 /// HImode, not an intermediate pointer.
1512 static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1513 // This attribute isn't documented, but glibc uses it. It changes
1514 // the width of an int or unsigned int to the specified size.
1516 // Check that there aren't any arguments
1517 if (Attr.getNumArgs() != 0) {
1518 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1522 IdentifierInfo *Name = Attr.getParameterName();
1524 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1528 llvm::StringRef Str = Attr.getParameterName()->getName();
1530 // Normalize the attribute name, __foo__ becomes foo.
1531 if (Str.startswith("__") && Str.endswith("__"))
1532 Str = Str.substr(2, Str.size() - 4);
1534 unsigned DestWidth = 0;
1535 bool IntegerMode = true;
1536 bool ComplexMode = false;
1537 switch (Str.size()) {
1540 case 'Q': DestWidth = 8; break;
1541 case 'H': DestWidth = 16; break;
1542 case 'S': DestWidth = 32; break;
1543 case 'D': DestWidth = 64; break;
1544 case 'X': DestWidth = 96; break;
1545 case 'T': DestWidth = 128; break;
1547 if (Str[1] == 'F') {
1548 IntegerMode = false;
1549 } else if (Str[1] == 'C') {
1550 IntegerMode = false;
1552 } else if (Str[1] != 'I') {
1557 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1558 // pointer on PIC16 and other embedded platforms.
1560 DestWidth = S.Context.Target.getPointerWidth(0);
1561 else if (Str == "byte")
1562 DestWidth = S.Context.Target.getCharWidth();
1565 if (Str == "pointer")
1566 DestWidth = S.Context.Target.getPointerWidth(0);
1571 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1572 OldTy = TD->getUnderlyingType();
1573 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1574 OldTy = VD->getType();
1576 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1577 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1581 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
1582 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1583 else if (IntegerMode) {
1584 if (!OldTy->isIntegralType())
1585 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1586 } else if (ComplexMode) {
1587 if (!OldTy->isComplexType())
1588 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1590 if (!OldTy->isFloatingType())
1591 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1594 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1595 // and friends, at least with glibc.
1596 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1597 // width on unusual platforms.
1598 // FIXME: Make sure floating-point mappings are accurate
1599 // FIXME: Support XF and TF types
1601 switch (DestWidth) {
1603 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1606 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1610 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1613 if (OldTy->isSignedIntegerType())
1614 NewTy = S.Context.SignedCharTy;
1616 NewTy = S.Context.UnsignedCharTy;
1620 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1623 if (OldTy->isSignedIntegerType())
1624 NewTy = S.Context.ShortTy;
1626 NewTy = S.Context.UnsignedShortTy;
1630 NewTy = S.Context.FloatTy;
1631 else if (OldTy->isSignedIntegerType())
1632 NewTy = S.Context.IntTy;
1634 NewTy = S.Context.UnsignedIntTy;
1638 NewTy = S.Context.DoubleTy;
1639 else if (OldTy->isSignedIntegerType())
1640 NewTy = S.Context.LongLongTy;
1642 NewTy = S.Context.UnsignedLongLongTy;
1645 NewTy = S.Context.LongDoubleTy;
1649 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1652 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1657 NewTy = S.Context.getComplexType(NewTy);
1660 // Install the new type.
1661 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1662 // FIXME: preserve existing source info.
1663 TD->setTypeDeclaratorInfo(S.Context.getTrivialDeclaratorInfo(NewTy));
1665 cast<ValueDecl>(D)->setType(NewTy);
1668 static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1669 // check the attribute arguments.
1670 if (Attr.getNumArgs() > 0) {
1671 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1675 if (!isFunctionOrMethod(d)) {
1676 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1677 << Attr.getName() << 0 /*function*/;
1681 d->addAttr(::new (S.Context) NoDebugAttr());
1684 static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1685 // check the attribute arguments.
1686 if (Attr.getNumArgs() != 0) {
1687 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1691 if (!isa<FunctionDecl>(d)) {
1692 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1693 << Attr.getName() << 0 /*function*/;
1697 d->addAttr(::new (S.Context) NoInlineAttr());
1700 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1701 // check the attribute arguments.
1702 if (Attr.getNumArgs() != 0) {
1703 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1707 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1709 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1710 << Attr.getName() << 0 /*function*/;
1714 if (!Fn->isInlineSpecified()) {
1715 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1719 d->addAttr(::new (S.Context) GNUInlineAttr());
1722 static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1723 // check the attribute arguments.
1724 if (Attr.getNumArgs() != 1) {
1725 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1729 if (!isFunctionOrMethod(d)) {
1730 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1731 << Attr.getName() << 0 /*function*/;
1735 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
1736 llvm::APSInt NumParams(32);
1737 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
1738 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1739 << "regparm" << NumParamsExpr->getSourceRange();
1743 if (S.Context.Target.getRegParmMax() == 0) {
1744 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
1745 << NumParamsExpr->getSourceRange();
1749 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1750 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1751 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
1755 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1758 //===----------------------------------------------------------------------===//
1759 // Checker-specific attribute handlers.
1760 //===----------------------------------------------------------------------===//
1762 static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1767 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
1768 RetTy = MD->getResultType();
1769 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
1770 RetTy = FD->getResultType();
1772 SourceLocation L = Attr.getLoc();
1773 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
1774 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */;
1778 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>()
1779 || RetTy->getAs<ObjCObjectPointerType>())) {
1780 SourceLocation L = Attr.getLoc();
1781 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
1782 << SourceRange(L, L) << Attr.getName();
1786 switch (Attr.getKind()) {
1788 assert(0 && "invalid ownership attribute");
1790 case AttributeList::AT_cf_returns_retained:
1791 d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1793 case AttributeList::AT_ns_returns_retained:
1794 d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1799 //===----------------------------------------------------------------------===//
1800 // Top Level Sema Entry Points
1801 //===----------------------------------------------------------------------===//
1803 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1804 /// the attribute applies to decls. If the attribute is a type attribute, just
1805 /// silently ignore it.
1806 static void ProcessDeclAttribute(Scope *scope, Decl *D,
1807 const AttributeList &Attr, Sema &S) {
1808 if (Attr.isDeclspecAttribute())
1809 // FIXME: Try to deal with __declspec attributes!
1811 switch (Attr.getKind()) {
1812 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break;
1813 case AttributeList::AT_address_space:
1814 case AttributeList::AT_objc_gc:
1815 // Ignore these, these are type attributes, handled by
1816 // ProcessTypeAttributes.
1818 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
1819 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
1820 case AttributeList::AT_always_inline:
1821 HandleAlwaysInlineAttr (D, Attr, S); break;
1822 case AttributeList::AT_analyzer_noreturn:
1823 HandleAnalyzerNoReturnAttr (D, Attr, S); break;
1824 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
1825 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1826 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break;
1827 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break;
1828 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
1829 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
1830 case AttributeList::AT_ext_vector_type:
1831 HandleExtVectorTypeAttr(scope, D, Attr, S);
1833 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break;
1834 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
1835 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
1836 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break;
1837 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
1838 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
1839 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
1840 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
1841 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
1843 // Checker-specific.
1844 case AttributeList::AT_ns_returns_retained:
1845 case AttributeList::AT_cf_returns_retained:
1846 HandleNSReturnsRetainedAttr(D, Attr, S); break;
1848 case AttributeList::AT_reqd_wg_size:
1849 HandleReqdWorkGroupSize(D, Attr, S); break;
1851 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
1852 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
1853 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
1854 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
1855 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
1856 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break;
1857 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
1858 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
1859 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1861 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
1862 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1863 case AttributeList::AT_transparent_union:
1864 HandleTransparentUnionAttr(D, Attr, S);
1866 case AttributeList::AT_objc_exception:
1867 HandleObjCExceptionAttr(D, Attr, S);
1869 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1870 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
1871 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
1872 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
1873 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
1874 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
1875 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break;
1876 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break;
1877 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break;
1878 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break;
1879 case AttributeList::IgnoredAttribute:
1880 case AttributeList::AT_no_instrument_function: // Interacts with -pg.
1884 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1889 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1890 /// attribute list to the specified decl, ignoring any type attributes.
1891 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) {
1893 ProcessDeclAttribute(S, D, *AttrList, *this);
1894 AttrList = AttrList->getNext();
1898 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
1899 /// #pragma weak needs a non-definition decl and source may not have one
1900 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
1901 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
1902 NamedDecl *NewD = 0;
1903 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
1904 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
1905 FD->getLocation(), DeclarationName(II),
1906 FD->getType(), FD->getDeclaratorInfo());
1907 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1908 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
1909 VD->getLocation(), II,
1910 VD->getType(), VD->getDeclaratorInfo(),
1911 VD->getStorageClass());
1916 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
1917 /// applied to it, possibly with an alias.
1918 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
1919 if (W.getUsed()) return; // only do this once
1921 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
1922 IdentifierInfo *NDId = ND->getIdentifier();
1923 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
1924 NewD->addAttr(::new (Context) AliasAttr(NDId->getName()));
1925 NewD->addAttr(::new (Context) WeakAttr());
1926 WeakTopLevelDecl.push_back(NewD);
1927 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
1928 // to insert Decl at TU scope, sorry.
1929 DeclContext *SavedContext = CurContext;
1930 CurContext = Context.getTranslationUnitDecl();
1931 PushOnScopeChains(NewD, S);
1932 CurContext = SavedContext;
1933 } else { // just add weak to existing
1934 ND->addAttr(::new (Context) WeakAttr());
1938 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
1939 /// it, apply them to D. This is a bit tricky because PD can have attributes
1940 /// specified in many different places, and we need to find and apply them all.
1941 void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
1942 // Handle #pragma weak
1943 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
1944 if (ND->hasLinkage()) {
1945 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
1946 if (W != WeakInfo()) {
1947 // Identifier referenced by #pragma weak before it was declared
1948 DeclApplyPragmaWeak(S, ND, W);
1949 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
1954 // Apply decl attributes from the DeclSpec if present.
1955 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
1956 ProcessDeclAttributeList(S, D, Attrs);
1958 // Walk the declarator structure, applying decl attributes that were in a type
1959 // position to the decl itself. This handles cases like:
1960 // int *__attr__(x)** D;
1961 // when X is a decl attribute.
1962 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
1963 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
1964 ProcessDeclAttributeList(S, D, Attrs);
1966 // Finally, apply any attributes on the decl itself.
1967 if (const AttributeList *Attrs = PD.getAttributes())
1968 ProcessDeclAttributeList(S, D, Attrs);
1971 /// PushParsingDeclaration - Enter a new "scope" of deprecation
1974 /// The state token we use is the start index of this scope
1975 /// on the warning stack.
1976 Action::ParsingDeclStackState Sema::PushParsingDeclaration() {
1978 return (ParsingDeclStackState) DelayedDeprecationWarnings.size();
1981 static bool isDeclDeprecated(Decl *D) {
1983 if (D->hasAttr<DeprecatedAttr>())
1985 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
1989 void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
1990 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
1993 if (DelayedDeprecationWarnings.empty())
1996 unsigned SavedIndex = (unsigned) S;
1997 assert(SavedIndex <= DelayedDeprecationWarnings.size() &&
1998 "saved index is out of bounds");
2000 if (Ctx && !isDeclDeprecated(Ctx.getAs<Decl>())) {
2001 for (unsigned I = 0, E = DelayedDeprecationWarnings.size(); I != E; ++I) {
2002 SourceLocation Loc = DelayedDeprecationWarnings[I].first;
2003 NamedDecl *&ND = DelayedDeprecationWarnings[I].second;
2005 Diag(Loc, diag::warn_deprecated) << ND->getDeclName();
2007 // Prevent this from triggering multiple times.
2013 DelayedDeprecationWarnings.set_size(SavedIndex);
2016 void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) {
2017 // Delay if we're currently parsing a declaration.
2018 if (ParsingDeclDepth) {
2019 DelayedDeprecationWarnings.push_back(std::make_pair(Loc, D));
2023 // Otherwise, don't warn if our current context is deprecated.
2024 if (isDeclDeprecated(cast<Decl>(CurContext)))
2027 Diag(Loc, diag::warn_deprecated) << D->getDeclName();