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 //===----------------------------------------------------------------------===//
14 #include "clang/Sema/SemaInternal.h"
15 #include "TargetAttributesSema.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Sema/DeclSpec.h"
22 #include "clang/Sema/DelayedDiagnostic.h"
23 #include "llvm/ADT/StringExtras.h"
24 using namespace clang;
27 //===----------------------------------------------------------------------===//
29 //===----------------------------------------------------------------------===//
31 static const FunctionType *getFunctionType(const Decl *d,
32 bool blocksToo = true) {
34 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d))
36 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d))
38 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
39 Ty = decl->getUnderlyingType();
43 if (Ty->isFunctionPointerType())
44 Ty = Ty->getAs<PointerType>()->getPointeeType();
45 else if (blocksToo && Ty->isBlockPointerType())
46 Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
48 return Ty->getAs<FunctionType>();
51 // FIXME: We should provide an abstraction around a method or function
52 // to provide the following bits of information.
54 /// isFunction - Return true if the given decl has function
55 /// type (function or function-typed variable).
56 static bool isFunction(const Decl *d) {
57 return getFunctionType(d, false) != NULL;
60 /// isFunctionOrMethod - Return true if the given decl has function
61 /// type (function or function-typed variable) or an Objective-C
63 static bool isFunctionOrMethod(const Decl *d) {
64 return isFunction(d)|| isa<ObjCMethodDecl>(d);
67 /// isFunctionOrMethodOrBlock - Return true if the given decl has function
68 /// type (function or function-typed variable) or an Objective-C
69 /// method or a block.
70 static bool isFunctionOrMethodOrBlock(const Decl *d) {
71 if (isFunctionOrMethod(d))
73 // check for block is more involved.
74 if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
75 QualType Ty = V->getType();
76 return Ty->isBlockPointerType();
78 return isa<BlockDecl>(d);
81 /// Return true if the given decl has a declarator that should have
82 /// been processed by Sema::GetTypeForDeclarator.
83 static bool hasDeclarator(const Decl *d) {
84 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
85 return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefDecl>(d);
88 /// hasFunctionProto - Return true if the given decl has a argument
89 /// information. This decl should have already passed
90 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
91 static bool hasFunctionProto(const Decl *d) {
92 if (const FunctionType *FnTy = getFunctionType(d))
93 return isa<FunctionProtoType>(FnTy);
95 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d));
100 /// getFunctionOrMethodNumArgs - Return number of function or method
101 /// arguments. It is an error to call this on a K&R function (use
102 /// hasFunctionProto first).
103 static unsigned getFunctionOrMethodNumArgs(const Decl *d) {
104 if (const FunctionType *FnTy = getFunctionType(d))
105 return cast<FunctionProtoType>(FnTy)->getNumArgs();
106 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
107 return BD->getNumParams();
108 return cast<ObjCMethodDecl>(d)->param_size();
111 static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) {
112 if (const FunctionType *FnTy = getFunctionType(d))
113 return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
114 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
115 return BD->getParamDecl(Idx)->getType();
117 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
120 static QualType getFunctionOrMethodResultType(const Decl *d) {
121 if (const FunctionType *FnTy = getFunctionType(d))
122 return cast<FunctionProtoType>(FnTy)->getResultType();
123 return cast<ObjCMethodDecl>(d)->getResultType();
126 static bool isFunctionOrMethodVariadic(const Decl *d) {
127 if (const FunctionType *FnTy = getFunctionType(d)) {
128 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
129 return proto->isVariadic();
130 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d))
131 return BD->isVariadic();
133 return cast<ObjCMethodDecl>(d)->isVariadic();
137 static bool isInstanceMethod(const Decl *d) {
138 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d))
139 return MethodDecl->isInstance();
143 static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
144 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
148 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
152 IdentifierInfo* ClsName = Cls->getIdentifier();
154 // FIXME: Should we walk the chain of classes?
155 return ClsName == &Ctx.Idents.get("NSString") ||
156 ClsName == &Ctx.Idents.get("NSMutableString");
159 static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
160 const PointerType *PT = T->getAs<PointerType>();
164 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
168 const RecordDecl *RD = RT->getDecl();
169 if (RD->getTagKind() != TTK_Struct)
172 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
175 //===----------------------------------------------------------------------===//
176 // Attribute Implementations
177 //===----------------------------------------------------------------------===//
179 // FIXME: All this manual attribute parsing code is gross. At the
180 // least add some helper functions to check most argument patterns (#
181 // and types of args).
183 static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
184 const AttributeList &Attr, Sema &S) {
185 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
187 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
191 QualType curType = tDecl->getUnderlyingType();
195 // Special case where the argument is a template id.
196 if (Attr.getParameterName()) {
199 id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
200 sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>();
202 // check the attribute arguments.
203 if (Attr.getNumArgs() != 1) {
204 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
207 sizeExpr = Attr.getArg(0);
210 // Instantiate/Install the vector type, and let Sema build the type for us.
211 // This will run the reguired checks.
212 QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
214 // FIXME: preserve the old source info.
215 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
217 // Remember this typedef decl, we will need it later for diagnostics.
218 S.ExtVectorDecls.push_back(tDecl);
222 static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
223 // check the attribute arguments.
224 if (Attr.getNumArgs() > 0) {
225 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
229 if (TagDecl *TD = dyn_cast<TagDecl>(d))
230 TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
231 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
232 // If the alignment is less than or equal to 8 bits, the packed attribute
234 if (!FD->getType()->isIncompleteType() &&
235 S.Context.getTypeAlign(FD->getType()) <= 8)
236 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
237 << Attr.getName() << FD->getType();
239 FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
241 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
244 static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
245 // check the attribute arguments.
246 if (Attr.getNumArgs() > 0) {
247 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
251 // The IBAction attributes only apply to instance methods.
252 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
253 if (MD->isInstanceMethod()) {
254 d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
258 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
261 static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
262 // check the attribute arguments.
263 if (Attr.getNumArgs() > 0) {
264 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
268 // The IBOutlet attributes only apply to instance variables of
269 // Objective-C classes.
270 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
271 d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
275 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
278 static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
281 // The iboutletcollection attribute can have zero or one arguments.
282 if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
283 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
287 // The IBOutletCollection attributes only apply to instance variables of
288 // Objective-C classes.
289 if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) {
290 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
293 if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
294 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
295 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
296 << VD->getType() << 0;
299 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
300 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
301 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
302 << PD->getType() << 1;
306 IdentifierInfo *II = Attr.getParameterName();
308 II = &S.Context.Idents.get("id");
310 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
311 S.getScopeForContext(d->getDeclContext()->getParent()));
313 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
316 QualType QT = TypeRep.get();
317 // Diagnose use of non-object type in iboutletcollection attribute.
318 // FIXME. Gnu attribute extension ignores use of builtin types in
319 // attributes. So, __attribute__((iboutletcollection(char))) will be
320 // treated as __attribute__((iboutletcollection())).
321 if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
322 !QT->isObjCObjectType()) {
323 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
326 d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
330 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
331 // GCC ignores the nonnull attribute on K&R style function prototypes, so we
333 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
334 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
335 << Attr.getName() << 0 /*function*/;
339 // In C++ the implicit 'this' function parameter also counts, and they are
341 bool HasImplicitThisParam = isInstanceMethod(d);
342 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
344 // The nonnull attribute only applies to pointers.
345 llvm::SmallVector<unsigned, 10> NonNullArgs;
347 for (AttributeList::arg_iterator I=Attr.arg_begin(),
348 E=Attr.arg_end(); I!=E; ++I) {
351 // The argument must be an integer constant expression.
353 llvm::APSInt ArgNum(32);
354 if (Ex->isTypeDependent() || Ex->isValueDependent() ||
355 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
356 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
357 << "nonnull" << Ex->getSourceRange();
361 unsigned x = (unsigned) ArgNum.getZExtValue();
363 if (x < 1 || x > NumArgs) {
364 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
365 << "nonnull" << I.getArgNum() << Ex->getSourceRange();
370 if (HasImplicitThisParam) {
372 S.Diag(Attr.getLoc(),
373 diag::err_attribute_invalid_implicit_this_argument)
374 << "nonnull" << Ex->getSourceRange();
380 // Is the function argument a pointer type?
381 QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
382 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
383 // FIXME: Should also highlight argument in decl.
384 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
385 << "nonnull" << Ex->getSourceRange();
389 NonNullArgs.push_back(x);
392 // If no arguments were specified to __attribute__((nonnull)) then all pointer
393 // arguments have a nonnull attribute.
394 if (NonNullArgs.empty()) {
395 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
396 QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
397 if (T->isAnyPointerType() || T->isBlockPointerType())
398 NonNullArgs.push_back(I);
399 else if (const RecordType *UT = T->getAsUnionType()) {
400 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
401 RecordDecl *UD = UT->getDecl();
402 for (RecordDecl::field_iterator it = UD->field_begin(),
403 itend = UD->field_end(); it != itend; ++it) {
405 if (T->isAnyPointerType() || T->isBlockPointerType()) {
406 NonNullArgs.push_back(I);
414 // No pointer arguments?
415 if (NonNullArgs.empty()) {
416 // Warn the trivial case only if attribute is not coming from a
417 // macro instantiation.
418 if (Attr.getLoc().isFileID())
419 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
424 unsigned* start = &NonNullArgs[0];
425 unsigned size = NonNullArgs.size();
426 llvm::array_pod_sort(start, start + size);
427 d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
431 static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
432 // This attribute must be applied to a function declaration.
433 // The first argument to the attribute must be a string,
434 // the name of the resource, for example "malloc".
435 // The following arguments must be argument indexes, the arguments must be
436 // of integer type for Returns, otherwise of pointer type.
437 // The difference between Holds and Takes is that a pointer may still be used
438 // after being held. free() should be __attribute((ownership_takes)), whereas
439 // a list append function may well be __attribute((ownership_holds)).
441 if (!AL.getParameterName()) {
442 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
443 << AL.getName()->getName() << 1;
446 // Figure out our Kind, and check arguments while we're at it.
447 OwnershipAttr::OwnershipKind K;
448 switch (AL.getKind()) {
449 case AttributeList::AT_ownership_takes:
450 K = OwnershipAttr::Takes;
451 if (AL.getNumArgs() < 1) {
452 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
456 case AttributeList::AT_ownership_holds:
457 K = OwnershipAttr::Holds;
458 if (AL.getNumArgs() < 1) {
459 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
463 case AttributeList::AT_ownership_returns:
464 K = OwnershipAttr::Returns;
465 if (AL.getNumArgs() > 1) {
466 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
467 << AL.getNumArgs() + 1;
472 // This should never happen given how we are called.
473 llvm_unreachable("Unknown ownership attribute");
476 if (!isFunction(d) || !hasFunctionProto(d)) {
477 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
482 // In C++ the implicit 'this' function parameter also counts, and they are
484 bool HasImplicitThisParam = isInstanceMethod(d);
485 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
487 llvm::StringRef Module = AL.getParameterName()->getName();
489 // Normalize the argument, __foo__ becomes foo.
490 if (Module.startswith("__") && Module.endswith("__"))
491 Module = Module.substr(2, Module.size() - 4);
493 llvm::SmallVector<unsigned, 10> OwnershipArgs;
495 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
499 llvm::APSInt ArgNum(32);
500 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
501 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
502 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
503 << AL.getName()->getName() << IdxExpr->getSourceRange();
507 unsigned x = (unsigned) ArgNum.getZExtValue();
509 if (x > NumArgs || x < 1) {
510 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
511 << AL.getName()->getName() << x << IdxExpr->getSourceRange();
515 if (HasImplicitThisParam) {
517 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
518 << "ownership" << IdxExpr->getSourceRange();
525 case OwnershipAttr::Takes:
526 case OwnershipAttr::Holds: {
527 // Is the function argument a pointer type?
528 QualType T = getFunctionOrMethodArgType(d, x);
529 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
530 // FIXME: Should also highlight argument in decl.
531 S.Diag(AL.getLoc(), diag::err_ownership_type)
532 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
534 << IdxExpr->getSourceRange();
539 case OwnershipAttr::Returns: {
540 if (AL.getNumArgs() > 1) {
541 // Is the function argument an integer type?
542 Expr *IdxExpr = AL.getArg(0);
543 llvm::APSInt ArgNum(32);
544 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
545 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
546 S.Diag(AL.getLoc(), diag::err_ownership_type)
547 << "ownership_returns" << "integer"
548 << IdxExpr->getSourceRange();
555 llvm_unreachable("Unknown ownership attribute");
558 // Check we don't have a conflict with another ownership attribute.
559 for (specific_attr_iterator<OwnershipAttr>
560 i = d->specific_attr_begin<OwnershipAttr>(),
561 e = d->specific_attr_end<OwnershipAttr>();
563 if ((*i)->getOwnKind() != K) {
564 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
567 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
568 << AL.getName()->getName() << "ownership_*";
573 OwnershipArgs.push_back(x);
576 unsigned* start = OwnershipArgs.data();
577 unsigned size = OwnershipArgs.size();
578 llvm::array_pod_sort(start, start + size);
580 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
581 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
585 d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
589 /// Whether this declaration has internal linkage for the purposes of
590 /// things that want to complain about things not have internal linkage.
591 static bool hasEffectivelyInternalLinkage(NamedDecl *D) {
592 switch (D->getLinkage()) {
594 case InternalLinkage:
597 // Template instantiations that go from external to unique-external
598 // shouldn't get diagnosed.
599 case UniqueExternalLinkage:
602 case ExternalLinkage:
605 llvm_unreachable("unknown linkage kind!");
609 static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
610 // Check the attribute arguments.
611 if (Attr.getNumArgs() > 1) {
612 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
616 if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
617 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
618 << Attr.getName() << 2 /*variables and functions*/;
622 NamedDecl *nd = cast<NamedDecl>(d);
626 // static int a __attribute__((weakref ("v2")));
627 // static int b() __attribute__((weakref ("f3")));
629 // and ignores the attributes of
631 // static int a __attribute__((weakref ("v2")));
634 const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
635 if (!Ctx->isFileContext()) {
636 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
637 nd->getNameAsString();
641 // The GCC manual says
643 // At present, a declaration to which `weakref' is attached can only
649 // given as an argument to `weakref' or to `alias', `weakref' is
650 // equivalent to `weak'.
652 // gcc 4.4.1 will accept
653 // int a7 __attribute__((weakref));
655 // int a7 __attribute__((weak));
656 // This looks like a bug in gcc. We reject that for now. We should revisit
657 // it if this behaviour is actually used.
659 if (!hasEffectivelyInternalLinkage(nd)) {
660 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
665 // static ((alias ("y"), weakref)).
666 // Should we? How to check that weakref is before or after alias?
668 if (Attr.getNumArgs() == 1) {
669 Expr *Arg = Attr.getArg(0);
670 Arg = Arg->IgnoreParenCasts();
671 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
673 if (Str == 0 || Str->isWide()) {
674 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
678 // GCC will accept anything as the argument of weakref. Should we
679 // check for an existing decl?
680 d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
684 d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
687 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
688 // check the attribute arguments.
689 if (Attr.getNumArgs() != 1) {
690 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
694 Expr *Arg = Attr.getArg(0);
695 Arg = Arg->IgnoreParenCasts();
696 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
698 if (Str == 0 || Str->isWide()) {
699 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
704 if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) {
705 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
709 // FIXME: check if target symbol exists in current file
711 d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
715 static void HandleNakedAttr(Decl *d, const AttributeList &Attr,
717 // Check the attribute arguments.
718 if (Attr.getNumArgs() != 0) {
719 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
723 if (!isa<FunctionDecl>(d)) {
724 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
725 << Attr.getName() << 0 /*function*/;
729 d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
732 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
734 // Check the attribute arguments.
735 if (Attr.getNumArgs() != 0) {
736 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
740 if (!isa<FunctionDecl>(d)) {
741 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
742 << Attr.getName() << 0 /*function*/;
746 d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
749 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
750 // Check the attribute arguments.
751 if (Attr.getNumArgs() != 0) {
752 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
756 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
757 QualType RetTy = FD->getResultType();
758 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
759 d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
764 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
767 static void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
768 // check the attribute arguments.
769 if (Attr.getNumArgs() != 0) {
770 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
774 d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
777 static void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
778 assert(Attr.isInvalid() == false);
780 d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
782 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
783 << Attr.getName() << 12 /* variable */;
786 static void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) {
787 assert(Attr.isInvalid() == false);
789 d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
791 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
792 << Attr.getName() << 12 /* variable */;
795 static void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) {
796 if (hasDeclarator(d)) return;
798 if (S.CheckNoReturnAttr(attr)) return;
800 if (!isa<ObjCMethodDecl>(d)) {
801 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
802 << attr.getName() << 0 /*function*/;
806 d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
809 bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
810 if (attr.getNumArgs() != 0) {
811 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
819 static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
822 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
823 // because 'analyzer_noreturn' does not impact the type.
825 if (Attr.getNumArgs() != 0) {
826 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
830 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
831 ValueDecl *VD = dyn_cast<ValueDecl>(d);
832 if (VD == 0 || (!VD->getType()->isBlockPointerType()
833 && !VD->getType()->isFunctionPointerType())) {
834 S.Diag(Attr.getLoc(),
835 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
836 : diag::warn_attribute_wrong_decl_type)
837 << Attr.getName() << 0 /*function*/;
842 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
846 static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
849 Returning a Vector Class in Registers
851 According to the PPU ABI specifications, a class with a single member of
852 vector type is returned in memory when used as the return value of a function.
853 This results in inefficient code when implementing vector classes. To return
854 the value in a single vector register, add the vecreturn attribute to the
855 class definition. This attribute is also applicable to struct types.
862 } __attribute__((vecreturn));
864 Vector Add(Vector lhs, Vector rhs)
867 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
868 return result; // This will be returned in a register
871 if (!isa<RecordDecl>(d)) {
872 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
873 << Attr.getName() << 9 /*class*/;
877 if (d->getAttr<VecReturnAttr>()) {
878 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
882 RecordDecl *record = cast<RecordDecl>(d);
885 if (!isa<CXXRecordDecl>(record)) {
886 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
890 if (!cast<CXXRecordDecl>(record)->isPOD()) {
891 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
895 for (RecordDecl::field_iterator iter = record->field_begin();
896 iter != record->field_end(); iter++) {
897 if ((count == 1) || !iter->getType()->isVectorType()) {
898 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
904 d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
907 static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
908 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
909 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
910 << Attr.getName() << 8 /*function, method, or parameter*/;
913 // FIXME: Actually store the attribute on the declaration
916 static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
917 // check the attribute arguments.
918 if (Attr.getNumArgs() != 0) {
919 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
923 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) &&
924 !isa<TypeDecl>(d) && !isa<LabelDecl>(d)) {
925 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
926 << Attr.getName() << 14 /*variable, function, labels*/;
930 d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
933 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
934 // check the attribute arguments.
935 if (Attr.getNumArgs() != 0) {
936 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
940 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
941 if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
942 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
945 } else if (!isFunctionOrMethod(d)) {
946 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
947 << Attr.getName() << 2 /*variable and function*/;
951 d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
954 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
955 // check the attribute arguments.
956 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
957 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
962 int priority = 65535; // FIXME: Do not hardcode such constants.
963 if (Attr.getNumArgs() > 0) {
964 Expr *E = Attr.getArg(0);
965 llvm::APSInt Idx(32);
966 if (E->isTypeDependent() || E->isValueDependent() ||
967 !E->isIntegerConstantExpr(Idx, S.Context)) {
968 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
969 << "constructor" << 1 << E->getSourceRange();
972 priority = Idx.getZExtValue();
975 if (!isa<FunctionDecl>(d)) {
976 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
977 << Attr.getName() << 0 /*function*/;
981 d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
985 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
986 // check the attribute arguments.
987 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
988 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
993 int priority = 65535; // FIXME: Do not hardcode such constants.
994 if (Attr.getNumArgs() > 0) {
995 Expr *E = Attr.getArg(0);
996 llvm::APSInt Idx(32);
997 if (E->isTypeDependent() || E->isValueDependent() ||
998 !E->isIntegerConstantExpr(Idx, S.Context)) {
999 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1000 << "destructor" << 1 << E->getSourceRange();
1003 priority = Idx.getZExtValue();
1006 if (!isa<FunctionDecl>(d)) {
1007 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1008 << Attr.getName() << 0 /*function*/;
1012 d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1016 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1017 // check the attribute arguments.
1018 int noArgs = Attr.getNumArgs();
1020 S.Diag(Attr.getLoc(),
1021 diag::err_attribute_wrong_number_arguments) << "0 or 1";
1024 // Handle the case where deprecated attribute has a text message.
1027 Expr *ArgExpr = Attr.getArg(0);
1028 SE = dyn_cast<StringLiteral>(ArgExpr);
1030 S.Diag(ArgExpr->getLocStart(),
1031 diag::err_attribute_not_string) << "deprecated";
1036 SE = StringLiteral::CreateEmpty(S.Context, 1);
1038 d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context,
1042 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1043 // check the attribute arguments.
1044 int noArgs = Attr.getNumArgs();
1046 S.Diag(Attr.getLoc(),
1047 diag::err_attribute_wrong_number_arguments) << "0 or 1";
1050 // Handle the case where unavailable attribute has a text message.
1053 Expr *ArgExpr = Attr.getArg(0);
1054 SE = dyn_cast<StringLiteral>(ArgExpr);
1056 S.Diag(ArgExpr->getLocStart(),
1057 diag::err_attribute_not_string) << "unavailable";
1062 SE = StringLiteral::CreateEmpty(S.Context, 1);
1063 d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context,
1067 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1068 // check the attribute arguments.
1069 if (Attr.getNumArgs() != 1) {
1070 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1074 Expr *Arg = Attr.getArg(0);
1075 Arg = Arg->IgnoreParenCasts();
1076 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1078 if (Str == 0 || Str->isWide()) {
1079 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1080 << "visibility" << 1;
1084 llvm::StringRef TypeStr = Str->getString();
1085 VisibilityAttr::VisibilityType type;
1087 if (TypeStr == "default")
1088 type = VisibilityAttr::Default;
1089 else if (TypeStr == "hidden")
1090 type = VisibilityAttr::Hidden;
1091 else if (TypeStr == "internal")
1092 type = VisibilityAttr::Hidden; // FIXME
1093 else if (TypeStr == "protected")
1094 type = VisibilityAttr::Protected;
1096 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
1100 d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
1103 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
1105 if (Attr.getNumArgs() != 0) {
1106 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1110 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
1112 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1116 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
1119 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
1120 if (Attr.getNumArgs() != 0) {
1121 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1124 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
1125 QualType T = TD->getUnderlyingType();
1126 if (!T->isPointerType() ||
1127 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1128 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1132 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1136 HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1137 if (Attr.getNumArgs() != 0) {
1138 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1142 if (!isa<FunctionDecl>(D)) {
1143 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1147 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1150 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1151 if (!Attr.getParameterName()) {
1152 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1157 if (Attr.getNumArgs() != 0) {
1158 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1162 BlocksAttr::BlockType type;
1163 if (Attr.getParameterName()->isStr("byref"))
1164 type = BlocksAttr::ByRef;
1166 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1167 << "blocks" << Attr.getParameterName();
1171 d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
1174 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1175 // check the attribute arguments.
1176 if (Attr.getNumArgs() > 2) {
1177 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1183 if (Attr.getNumArgs() > 0) {
1184 Expr *E = Attr.getArg(0);
1185 llvm::APSInt Idx(32);
1186 if (E->isTypeDependent() || E->isValueDependent() ||
1187 !E->isIntegerConstantExpr(Idx, S.Context)) {
1188 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1189 << "sentinel" << 1 << E->getSourceRange();
1192 sentinel = Idx.getZExtValue();
1195 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1196 << E->getSourceRange();
1202 if (Attr.getNumArgs() > 1) {
1203 Expr *E = Attr.getArg(1);
1204 llvm::APSInt Idx(32);
1205 if (E->isTypeDependent() || E->isValueDependent() ||
1206 !E->isIntegerConstantExpr(Idx, S.Context)) {
1207 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1208 << "sentinel" << 2 << E->getSourceRange();
1211 nullPos = Idx.getZExtValue();
1213 if (nullPos > 1 || nullPos < 0) {
1214 // FIXME: This error message could be improved, it would be nice
1215 // to say what the bounds actually are.
1216 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1217 << E->getSourceRange();
1222 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
1223 const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1224 assert(FT && "FunctionDecl has non-function type?");
1226 if (isa<FunctionNoProtoType>(FT)) {
1227 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1231 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
1232 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1235 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
1236 if (!MD->isVariadic()) {
1237 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1240 } else if (isa<BlockDecl>(d)) {
1241 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1244 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
1245 QualType Ty = V->getType();
1246 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1247 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
1248 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
1249 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
1250 int m = Ty->isFunctionPointerType() ? 0 : 1;
1251 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
1255 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1256 << Attr.getName() << 6 /*function, method or block */;
1260 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1261 << Attr.getName() << 6 /*function, method or block */;
1264 d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1268 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
1269 // check the attribute arguments.
1270 if (Attr.getNumArgs() != 0) {
1271 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1275 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1276 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1277 << Attr.getName() << 0 /*function*/;
1281 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1282 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1283 << Attr.getName() << 0;
1286 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1287 if (MD->getResultType()->isVoidType()) {
1288 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1289 << Attr.getName() << 1;
1293 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1296 static void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) {
1297 // check the attribute arguments.
1298 if (attr.getNumArgs() != 0) {
1299 S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1303 if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) {
1304 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1305 << attr.getName() << 2 /*variables and functions*/;
1309 NamedDecl *nd = cast<NamedDecl>(d);
1311 // 'weak' only applies to declarations with external linkage.
1312 if (hasEffectivelyInternalLinkage(nd)) {
1313 S.Diag(attr.getLoc(), diag::err_attribute_weak_static);
1317 nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context));
1320 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1321 // check the attribute arguments.
1322 if (Attr.getNumArgs() != 0) {
1323 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1327 // weak_import only applies to variable & function declarations.
1329 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
1330 isDef = (!VD->hasExternalStorage() || VD->getInit());
1331 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1332 isDef = FD->hasBody();
1333 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
1334 // We ignore weak import on properties and methods
1336 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) {
1337 // Don't issue the warning for darwin as target; yet, ignore the attribute.
1338 if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin ||
1339 !isa<ObjCInterfaceDecl>(D))
1340 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1341 << Attr.getName() << 2 /*variable and function*/;
1345 // Merge should handle any subsequent violations.
1347 S.Diag(Attr.getLoc(),
1348 diag::warn_attribute_weak_import_invalid_on_definition)
1349 << "weak_import" << 2 /*variable and function*/;
1353 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
1356 static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
1358 // Attribute has 3 arguments.
1359 if (Attr.getNumArgs() != 3) {
1360 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1365 for (unsigned i = 0; i < 3; ++i) {
1366 Expr *E = Attr.getArg(i);
1367 llvm::APSInt ArgNum(32);
1368 if (E->isTypeDependent() || E->isValueDependent() ||
1369 !E->isIntegerConstantExpr(ArgNum, S.Context)) {
1370 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1371 << "reqd_work_group_size" << E->getSourceRange();
1374 WGSize[i] = (unsigned) ArgNum.getZExtValue();
1376 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1377 WGSize[0], WGSize[1],
1381 static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1382 // Attribute has no arguments.
1383 if (Attr.getNumArgs() != 1) {
1384 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1388 // Make sure that there is a string literal as the sections's single
1390 Expr *ArgExpr = Attr.getArg(0);
1391 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1393 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
1397 // If the target wants to validate the section specifier, make it happen.
1398 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1399 if (!Error.empty()) {
1400 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1405 // This attribute cannot be applied to local variables.
1406 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1407 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1411 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1416 static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1417 // check the attribute arguments.
1418 if (Attr.getNumArgs() != 0) {
1419 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1423 d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1426 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1427 // check the attribute arguments.
1428 if (Attr.getNumArgs() != 0) {
1429 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1433 d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1436 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1437 // check the attribute arguments.
1438 if (Attr.getNumArgs() != 0) {
1439 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1443 d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1446 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1447 if (!Attr.getParameterName()) {
1448 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1452 if (Attr.getNumArgs() != 0) {
1453 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1457 VarDecl *VD = dyn_cast<VarDecl>(d);
1459 if (!VD || !VD->hasLocalStorage()) {
1460 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1464 // Look up the function
1465 // FIXME: Lookup probably isn't looking in the right place
1466 NamedDecl *CleanupDecl
1467 = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1468 Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1470 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1471 Attr.getParameterName();
1475 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1477 S.Diag(Attr.getParameterLoc(),
1478 diag::err_attribute_cleanup_arg_not_function)
1479 << Attr.getParameterName();
1483 if (FD->getNumParams() != 1) {
1484 S.Diag(Attr.getParameterLoc(),
1485 diag::err_attribute_cleanup_func_must_take_one_arg)
1486 << Attr.getParameterName();
1490 // We're currently more strict than GCC about what function types we accept.
1491 // If this ever proves to be a problem it should be easy to fix.
1492 QualType Ty = S.Context.getPointerType(VD->getType());
1493 QualType ParamTy = FD->getParamDecl(0)->getType();
1494 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1495 ParamTy, Ty) != Sema::Compatible) {
1496 S.Diag(Attr.getParameterLoc(),
1497 diag::err_attribute_cleanup_func_arg_incompatible_type) <<
1498 Attr.getParameterName() << ParamTy << Ty;
1502 d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1503 S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1506 /// Handle __attribute__((format_arg((idx)))) attribute based on
1507 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1508 static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1509 if (Attr.getNumArgs() != 1) {
1510 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1513 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
1514 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1515 << Attr.getName() << 0 /*function*/;
1519 // In C++ the implicit 'this' function parameter also counts, and they are
1520 // counted from one.
1521 bool HasImplicitThisParam = isInstanceMethod(d);
1522 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
1523 unsigned FirstIdx = 1;
1525 // checks for the 2nd argument
1526 Expr *IdxExpr = Attr.getArg(0);
1527 llvm::APSInt Idx(32);
1528 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1529 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1530 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1531 << "format" << 2 << IdxExpr->getSourceRange();
1535 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1536 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1537 << "format" << 2 << IdxExpr->getSourceRange();
1541 unsigned ArgIdx = Idx.getZExtValue() - 1;
1543 if (HasImplicitThisParam) {
1545 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
1546 << "format_arg" << IdxExpr->getSourceRange();
1552 // make sure the format string is really a string
1553 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1555 bool not_nsstring_type = !isNSStringType(Ty, S.Context);
1556 if (not_nsstring_type &&
1557 !isCFStringType(Ty, S.Context) &&
1558 (!Ty->isPointerType() ||
1559 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
1560 // FIXME: Should highlight the actual expression that has the wrong type.
1561 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1562 << (not_nsstring_type ? "a string type" : "an NSString")
1563 << IdxExpr->getSourceRange();
1566 Ty = getFunctionOrMethodResultType(d);
1567 if (!isNSStringType(Ty, S.Context) &&
1568 !isCFStringType(Ty, S.Context) &&
1569 (!Ty->isPointerType() ||
1570 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
1571 // FIXME: Should highlight the actual expression that has the wrong type.
1572 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1573 << (not_nsstring_type ? "string type" : "NSString")
1574 << IdxExpr->getSourceRange();
1578 d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
1579 Idx.getZExtValue()));
1582 enum FormatAttrKind {
1591 /// getFormatAttrKind - Map from format attribute names to supported format
1593 static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
1594 // Check for formats that get handled specially.
1595 if (Format == "NSString")
1596 return NSStringFormat;
1597 if (Format == "CFString")
1598 return CFStringFormat;
1599 if (Format == "strftime")
1600 return StrftimeFormat;
1602 // Otherwise, check for supported formats.
1603 if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
1604 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
1605 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1606 Format == "zcmn_err" ||
1607 Format == "kprintf") // OpenBSD.
1608 return SupportedFormat;
1610 if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1611 Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
1612 return IgnoredFormat;
1614 return InvalidFormat;
1617 /// Handle __attribute__((init_priority(priority))) attributes based on
1618 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1619 static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
1621 if (!S.getLangOptions().CPlusPlus) {
1622 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1626 if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) {
1627 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1631 QualType T = dyn_cast<VarDecl>(d)->getType();
1632 if (S.Context.getAsArrayType(T))
1633 T = S.Context.getBaseElementType(T);
1634 if (!T->getAs<RecordType>()) {
1635 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1640 if (Attr.getNumArgs() != 1) {
1641 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1645 Expr *priorityExpr = Attr.getArg(0);
1647 llvm::APSInt priority(32);
1648 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1649 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1650 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1651 << "init_priority" << priorityExpr->getSourceRange();
1655 unsigned prioritynum = priority.getZExtValue();
1656 if (prioritynum < 101 || prioritynum > 65535) {
1657 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1658 << priorityExpr->getSourceRange();
1662 d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1666 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1667 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1668 static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1670 if (!Attr.getParameterName()) {
1671 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1676 if (Attr.getNumArgs() != 2) {
1677 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1681 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1682 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1683 << Attr.getName() << 0 /*function*/;
1687 // In C++ the implicit 'this' function parameter also counts, and they are
1688 // counted from one.
1689 bool HasImplicitThisParam = isInstanceMethod(d);
1690 unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam;
1691 unsigned FirstIdx = 1;
1693 llvm::StringRef Format = Attr.getParameterName()->getName();
1695 // Normalize the argument, __foo__ becomes foo.
1696 if (Format.startswith("__") && Format.endswith("__"))
1697 Format = Format.substr(2, Format.size() - 4);
1699 // Check for supported formats.
1700 FormatAttrKind Kind = getFormatAttrKind(Format);
1702 if (Kind == IgnoredFormat)
1705 if (Kind == InvalidFormat) {
1706 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1707 << "format" << Attr.getParameterName()->getName();
1711 // checks for the 2nd argument
1712 Expr *IdxExpr = Attr.getArg(0);
1713 llvm::APSInt Idx(32);
1714 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1715 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1716 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1717 << "format" << 2 << IdxExpr->getSourceRange();
1721 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1722 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1723 << "format" << 2 << IdxExpr->getSourceRange();
1727 // FIXME: Do we need to bounds check?
1728 unsigned ArgIdx = Idx.getZExtValue() - 1;
1730 if (HasImplicitThisParam) {
1732 S.Diag(Attr.getLoc(),
1733 diag::err_format_attribute_implicit_this_format_string)
1734 << IdxExpr->getSourceRange();
1740 // make sure the format string is really a string
1741 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
1743 if (Kind == CFStringFormat) {
1744 if (!isCFStringType(Ty, S.Context)) {
1745 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1746 << "a CFString" << IdxExpr->getSourceRange();
1749 } else if (Kind == NSStringFormat) {
1750 // FIXME: do we need to check if the type is NSString*? What are the
1752 if (!isNSStringType(Ty, S.Context)) {
1753 // FIXME: Should highlight the actual expression that has the wrong type.
1754 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1755 << "an NSString" << IdxExpr->getSourceRange();
1758 } else if (!Ty->isPointerType() ||
1759 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1760 // FIXME: Should highlight the actual expression that has the wrong type.
1761 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1762 << "a string type" << IdxExpr->getSourceRange();
1766 // check the 3rd argument
1767 Expr *FirstArgExpr = Attr.getArg(1);
1768 llvm::APSInt FirstArg(32);
1769 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1770 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1771 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1772 << "format" << 3 << FirstArgExpr->getSourceRange();
1776 // check if the function is variadic if the 3rd argument non-zero
1777 if (FirstArg != 0) {
1778 if (isFunctionOrMethodVariadic(d)) {
1779 ++NumArgs; // +1 for ...
1781 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
1786 // strftime requires FirstArg to be 0 because it doesn't read from any
1787 // variable the input is just the current time + the format string.
1788 if (Kind == StrftimeFormat) {
1789 if (FirstArg != 0) {
1790 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1791 << FirstArgExpr->getSourceRange();
1794 // if 0 it disables parameter checking (to use with e.g. va_list)
1795 } else if (FirstArg != 0 && FirstArg != NumArgs) {
1796 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1797 << "format" << 3 << FirstArgExpr->getSourceRange();
1801 d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1803 FirstArg.getZExtValue()));
1806 static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
1808 // check the attribute arguments.
1809 if (Attr.getNumArgs() != 0) {
1810 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1814 // Try to find the underlying union declaration.
1816 TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1817 if (TD && TD->getUnderlyingType()->isUnionType())
1818 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1820 RD = dyn_cast<RecordDecl>(d);
1822 if (!RD || !RD->isUnion()) {
1823 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1824 << Attr.getName() << 1 /*union*/;
1828 if (!RD->isDefinition()) {
1829 S.Diag(Attr.getLoc(),
1830 diag::warn_transparent_union_attribute_not_definition);
1834 RecordDecl::field_iterator Field = RD->field_begin(),
1835 FieldEnd = RD->field_end();
1836 if (Field == FieldEnd) {
1837 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
1841 FieldDecl *FirstField = *Field;
1842 QualType FirstType = FirstField->getType();
1843 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1844 S.Diag(FirstField->getLocation(),
1845 diag::warn_transparent_union_attribute_floating)
1846 << FirstType->isVectorType() << FirstType;
1850 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
1851 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
1852 for (; Field != FieldEnd; ++Field) {
1853 QualType FieldType = Field->getType();
1854 if (S.Context.getTypeSize(FieldType) != FirstSize ||
1855 S.Context.getTypeAlign(FieldType) != FirstAlign) {
1856 // Warn if we drop the attribute.
1857 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
1858 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
1859 : S.Context.getTypeAlign(FieldType);
1860 S.Diag(Field->getLocation(),
1861 diag::warn_transparent_union_attribute_field_size_align)
1862 << isSize << Field->getDeclName() << FieldBits;
1863 unsigned FirstBits = isSize? FirstSize : FirstAlign;
1864 S.Diag(FirstField->getLocation(),
1865 diag::note_transparent_union_first_field_size_align)
1866 << isSize << FirstBits;
1871 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
1874 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1875 // check the attribute arguments.
1876 if (Attr.getNumArgs() != 1) {
1877 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1880 Expr *ArgExpr = Attr.getArg(0);
1881 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1883 // Make sure that there is a string literal as the annotation's single
1886 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
1889 d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
1893 static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1894 // check the attribute arguments.
1895 if (Attr.getNumArgs() > 1) {
1896 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1900 //FIXME: The C++0x version of this attribute has more limited applicabilty
1901 // than GNU's, and should error out when it is used to specify a
1902 // weaker alignment, rather than being silently ignored.
1904 if (Attr.getNumArgs() == 0) {
1905 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
1909 S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
1912 void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
1913 if (E->isTypeDependent() || E->isValueDependent()) {
1914 // Save dependent expressions in the AST to be instantiated.
1915 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
1919 // FIXME: Cache the number on the Attr object?
1920 llvm::APSInt Alignment(32);
1921 if (!E->isIntegerConstantExpr(Alignment, Context)) {
1922 Diag(AttrLoc, diag::err_attribute_argument_not_int)
1923 << "aligned" << E->getSourceRange();
1926 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1927 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
1928 << E->getSourceRange();
1932 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
1935 void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
1936 // FIXME: Cache the number on the Attr object if non-dependent?
1937 // FIXME: Perform checking of type validity
1938 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
1942 /// HandleModeAttr - This attribute modifies the width of a decl with primitive
1945 /// Despite what would be logical, the mode attribute is a decl attribute, not a
1946 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1947 /// HImode, not an intermediate pointer.
1948 static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1949 // This attribute isn't documented, but glibc uses it. It changes
1950 // the width of an int or unsigned int to the specified size.
1952 // Check that there aren't any arguments
1953 if (Attr.getNumArgs() != 0) {
1954 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1958 IdentifierInfo *Name = Attr.getParameterName();
1960 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1964 llvm::StringRef Str = Attr.getParameterName()->getName();
1966 // Normalize the attribute name, __foo__ becomes foo.
1967 if (Str.startswith("__") && Str.endswith("__"))
1968 Str = Str.substr(2, Str.size() - 4);
1970 unsigned DestWidth = 0;
1971 bool IntegerMode = true;
1972 bool ComplexMode = false;
1973 switch (Str.size()) {
1976 case 'Q': DestWidth = 8; break;
1977 case 'H': DestWidth = 16; break;
1978 case 'S': DestWidth = 32; break;
1979 case 'D': DestWidth = 64; break;
1980 case 'X': DestWidth = 96; break;
1981 case 'T': DestWidth = 128; break;
1983 if (Str[1] == 'F') {
1984 IntegerMode = false;
1985 } else if (Str[1] == 'C') {
1986 IntegerMode = false;
1988 } else if (Str[1] != 'I') {
1993 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1994 // pointer on PIC16 and other embedded platforms.
1996 DestWidth = S.Context.Target.getPointerWidth(0);
1997 else if (Str == "byte")
1998 DestWidth = S.Context.Target.getCharWidth();
2001 if (Str == "pointer")
2002 DestWidth = S.Context.Target.getPointerWidth(0);
2007 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
2008 OldTy = TD->getUnderlyingType();
2009 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2010 OldTy = VD->getType();
2012 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2013 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2017 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
2018 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
2019 else if (IntegerMode) {
2020 if (!OldTy->isIntegralOrEnumerationType())
2021 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2022 } else if (ComplexMode) {
2023 if (!OldTy->isComplexType())
2024 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2026 if (!OldTy->isFloatingType())
2027 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2030 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2031 // and friends, at least with glibc.
2032 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2033 // width on unusual platforms.
2034 // FIXME: Make sure floating-point mappings are accurate
2035 // FIXME: Support XF and TF types
2037 switch (DestWidth) {
2039 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2042 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2046 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2049 if (OldTy->isSignedIntegerType())
2050 NewTy = S.Context.SignedCharTy;
2052 NewTy = S.Context.UnsignedCharTy;
2056 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2059 if (OldTy->isSignedIntegerType())
2060 NewTy = S.Context.ShortTy;
2062 NewTy = S.Context.UnsignedShortTy;
2066 NewTy = S.Context.FloatTy;
2067 else if (OldTy->isSignedIntegerType())
2068 NewTy = S.Context.IntTy;
2070 NewTy = S.Context.UnsignedIntTy;
2074 NewTy = S.Context.DoubleTy;
2075 else if (OldTy->isSignedIntegerType())
2076 if (S.Context.Target.getLongWidth() == 64)
2077 NewTy = S.Context.LongTy;
2079 NewTy = S.Context.LongLongTy;
2081 if (S.Context.Target.getLongWidth() == 64)
2082 NewTy = S.Context.UnsignedLongTy;
2084 NewTy = S.Context.UnsignedLongLongTy;
2087 NewTy = S.Context.LongDoubleTy;
2091 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2094 if (OldTy->isSignedIntegerType())
2095 NewTy = S.Context.Int128Ty;
2097 NewTy = S.Context.UnsignedInt128Ty;
2102 NewTy = S.Context.getComplexType(NewTy);
2105 // Install the new type.
2106 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
2107 // FIXME: preserve existing source info.
2108 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2110 cast<ValueDecl>(D)->setType(NewTy);
2113 static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2114 // check the attribute arguments.
2115 if (Attr.getNumArgs() > 0) {
2116 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2120 if (!isFunctionOrMethod(d)) {
2121 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2122 << Attr.getName() << 0 /*function*/;
2126 d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2129 static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2130 // check the attribute arguments.
2131 if (Attr.getNumArgs() != 0) {
2132 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2136 if (!isa<FunctionDecl>(d)) {
2137 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2138 << Attr.getName() << 0 /*function*/;
2142 d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
2145 static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
2147 // check the attribute arguments.
2148 if (Attr.getNumArgs() != 0) {
2149 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2153 if (!isa<FunctionDecl>(d)) {
2154 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2155 << Attr.getName() << 0 /*function*/;
2159 d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2163 static void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2164 if (S.LangOpts.CUDA) {
2165 // check the attribute arguments.
2166 if (Attr.getNumArgs() != 0) {
2167 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2171 if (!isa<VarDecl>(d)) {
2172 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2173 << Attr.getName() << 12 /*variable*/;
2177 d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2179 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2183 static void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2184 if (S.LangOpts.CUDA) {
2185 // check the attribute arguments.
2186 if (Attr.getNumArgs() != 0) {
2187 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2191 if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) {
2192 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2193 << Attr.getName() << 2 /*variable and function*/;
2197 d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2199 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2203 static void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2204 if (S.LangOpts.CUDA) {
2205 // check the attribute arguments.
2206 if (Attr.getNumArgs() != 0) {
2207 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2211 if (!isa<FunctionDecl>(d)) {
2212 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2213 << Attr.getName() << 0 /*function*/;
2217 FunctionDecl *FD = cast<FunctionDecl>(d);
2218 if (!FD->getResultType()->isVoidType()) {
2219 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
2220 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
2221 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2223 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
2226 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2232 d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2234 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2238 static void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2239 if (S.LangOpts.CUDA) {
2240 // check the attribute arguments.
2241 if (Attr.getNumArgs() != 0) {
2242 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2246 if (!isa<FunctionDecl>(d)) {
2247 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2248 << Attr.getName() << 0 /*function*/;
2252 d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2254 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2258 static void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2259 if (S.LangOpts.CUDA) {
2260 // check the attribute arguments.
2261 if (Attr.getNumArgs() != 0) {
2262 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2266 if (!isa<VarDecl>(d)) {
2267 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2268 << Attr.getName() << 12 /*variable*/;
2272 d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2274 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2278 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2279 // check the attribute arguments.
2280 if (Attr.getNumArgs() != 0) {
2281 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2285 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
2287 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2288 << Attr.getName() << 0 /*function*/;
2292 if (!Fn->isInlineSpecified()) {
2293 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2297 d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
2300 static void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) {
2301 if (hasDeclarator(d)) return;
2303 // Diagnostic is emitted elsewhere: here we store the (valid) attr
2304 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2306 if (S.CheckCallingConvAttr(attr, CC))
2309 if (!isa<ObjCMethodDecl>(d)) {
2310 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2311 << attr.getName() << 0 /*function*/;
2315 switch (attr.getKind()) {
2316 case AttributeList::AT_fastcall:
2317 d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context));
2319 case AttributeList::AT_stdcall:
2320 d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context));
2322 case AttributeList::AT_thiscall:
2323 d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context));
2325 case AttributeList::AT_cdecl:
2326 d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context));
2328 case AttributeList::AT_pascal:
2329 d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context));
2332 llvm_unreachable("unexpected attribute kind");
2337 static void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){
2338 assert(Attr.isInvalid() == false);
2339 d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2342 bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2343 if (attr.isInvalid())
2346 if (attr.getNumArgs() != 0) {
2347 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2352 // TODO: diagnose uses of these conventions on the wrong target.
2353 switch (attr.getKind()) {
2354 case AttributeList::AT_cdecl: CC = CC_C; break;
2355 case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2356 case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2357 case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2358 case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2359 default: llvm_unreachable("unexpected attribute kind"); return true;
2365 static void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) {
2366 if (hasDeclarator(d)) return;
2369 if (S.CheckRegparmAttr(attr, numParams))
2372 if (!isa<ObjCMethodDecl>(d)) {
2373 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2374 << attr.getName() << 0 /*function*/;
2378 d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams));
2381 /// Checks a regparm attribute, returning true if it is ill-formed and
2382 /// otherwise setting numParams to the appropriate value.
2383 bool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) {
2384 if (attr.isInvalid())
2387 if (attr.getNumArgs() != 1) {
2388 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2393 Expr *NumParamsExpr = attr.getArg(0);
2394 llvm::APSInt NumParams(32);
2395 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2396 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
2397 Diag(attr.getLoc(), diag::err_attribute_argument_not_int)
2398 << "regparm" << NumParamsExpr->getSourceRange();
2403 if (Context.Target.getRegParmMax() == 0) {
2404 Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
2405 << NumParamsExpr->getSourceRange();
2410 numParams = NumParams.getZExtValue();
2411 if (numParams > Context.Target.getRegParmMax()) {
2412 Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2413 << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
2421 static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
2422 if (S.LangOpts.CUDA) {
2423 // check the attribute arguments.
2424 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2425 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
2430 if (!isFunctionOrMethod(d)) {
2431 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2432 << Attr.getName() << 0 /*function*/;
2436 Expr *MaxThreadsExpr = Attr.getArg(0);
2437 llvm::APSInt MaxThreads(32);
2438 if (MaxThreadsExpr->isTypeDependent() ||
2439 MaxThreadsExpr->isValueDependent() ||
2440 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
2441 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
2442 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
2446 llvm::APSInt MinBlocks(32);
2447 if (Attr.getNumArgs() > 1) {
2448 Expr *MinBlocksExpr = Attr.getArg(1);
2449 if (MinBlocksExpr->isTypeDependent() ||
2450 MinBlocksExpr->isValueDependent() ||
2451 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
2452 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
2453 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
2458 d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
2459 MaxThreads.getZExtValue(),
2460 MinBlocks.getZExtValue()));
2462 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
2466 //===----------------------------------------------------------------------===//
2467 // Checker-specific attribute handlers.
2468 //===----------------------------------------------------------------------===//
2470 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2471 return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2473 static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2474 return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2477 static void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) {
2478 ParmVarDecl *param = dyn_cast<ParmVarDecl>(d);
2480 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2481 << SourceRange(attr.getLoc()) << attr.getName() << 4 /*parameter*/;
2486 if (attr.getKind() == AttributeList::AT_ns_consumed) {
2487 typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2490 typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2495 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
2496 << SourceRange(attr.getLoc()) << attr.getName() << cf;
2501 param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context));
2503 param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context));
2506 static void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr,
2508 if (!isa<ObjCMethodDecl>(d)) {
2509 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2510 << SourceRange(attr.getLoc()) << attr.getName() << 13 /*method*/;
2514 d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context));
2517 static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr,
2520 QualType returnType;
2522 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
2523 returnType = MD->getResultType();
2524 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
2525 returnType = FD->getResultType();
2527 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type)
2528 << SourceRange(attr.getLoc()) << attr.getName()
2529 << 3 /* function or method */;
2535 switch (attr.getKind()) {
2536 default: llvm_unreachable("invalid ownership attribute"); return;
2537 case AttributeList::AT_ns_returns_autoreleased:
2538 case AttributeList::AT_ns_returns_retained:
2539 case AttributeList::AT_ns_returns_not_retained:
2540 typeOK = isValidSubjectOfNSAttribute(S, returnType);
2544 case AttributeList::AT_cf_returns_retained:
2545 case AttributeList::AT_cf_returns_not_retained:
2546 typeOK = isValidSubjectOfCFAttribute(S, returnType);
2552 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2553 << SourceRange(attr.getLoc())
2554 << attr.getName() << isa<ObjCMethodDecl>(d) << cf;
2558 switch (attr.getKind()) {
2560 assert(0 && "invalid ownership attribute");
2562 case AttributeList::AT_ns_returns_autoreleased:
2563 d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(),
2566 case AttributeList::AT_cf_returns_not_retained:
2567 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(),
2570 case AttributeList::AT_ns_returns_not_retained:
2571 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(),
2574 case AttributeList::AT_cf_returns_retained:
2575 d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(),
2578 case AttributeList::AT_ns_returns_retained:
2579 d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(),
2585 static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2586 return Attr.getKind() == AttributeList::AT_dllimport ||
2587 Attr.getKind() == AttributeList::AT_dllexport ||
2588 Attr.getKind() == AttributeList::AT_uuid;
2591 //===----------------------------------------------------------------------===//
2592 // Microsoft specific attribute handlers.
2593 //===----------------------------------------------------------------------===//
2595 static void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2596 if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
2597 // check the attribute arguments.
2598 if (Attr.getNumArgs() != 1) {
2599 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2602 Expr *Arg = Attr.getArg(0);
2603 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2604 if (Str == 0 || Str->isWide()) {
2605 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2610 llvm::StringRef StrRef = Str->getString();
2612 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2613 StrRef.back() == '}';
2615 // Validate GUID length.
2616 if (IsCurly && StrRef.size() != 38) {
2617 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2620 if (!IsCurly && StrRef.size() != 36) {
2621 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2625 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2626 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2627 llvm::StringRef::iterator I = StrRef.begin();
2628 if (IsCurly) // Skip the optional '{'
2631 for (int i = 0; i < 36; ++i) {
2632 if (i == 8 || i == 13 || i == 18 || i == 23) {
2634 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2637 } else if (!isxdigit(*I)) {
2638 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2644 d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
2647 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2650 //===----------------------------------------------------------------------===//
2651 // Top Level Sema Entry Points
2652 //===----------------------------------------------------------------------===//
2654 static void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D,
2655 const AttributeList &Attr, Sema &S) {
2656 switch (Attr.getKind()) {
2657 case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break;
2658 case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break;
2659 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
2665 static void ProcessInheritableDeclAttr(Scope *scope, Decl *D,
2666 const AttributeList &Attr, Sema &S) {
2667 switch (Attr.getKind()) {
2668 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break;
2669 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break;
2670 case AttributeList::AT_IBOutletCollection:
2671 HandleIBOutletCollection(D, Attr, S); break;
2672 case AttributeList::AT_address_space:
2673 case AttributeList::AT_objc_gc:
2674 case AttributeList::AT_vector_size:
2675 case AttributeList::AT_neon_vector_type:
2676 case AttributeList::AT_neon_polyvector_type:
2677 // Ignore these, these are type attributes, handled by
2678 // ProcessTypeAttributes.
2680 case AttributeList::AT_device:
2681 case AttributeList::AT_host:
2682 case AttributeList::AT_overloadable:
2683 // Ignore, this is a non-inheritable attribute, handled
2684 // by ProcessNonInheritableDeclAttr.
2686 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
2687 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
2688 case AttributeList::AT_always_inline:
2689 HandleAlwaysInlineAttr (D, Attr, S); break;
2690 case AttributeList::AT_analyzer_noreturn:
2691 HandleAnalyzerNoReturnAttr (D, Attr, S); break;
2692 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
2693 case AttributeList::AT_carries_dependency:
2694 HandleDependencyAttr (D, Attr, S); break;
2695 case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break;
2696 case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break;
2697 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
2698 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break;
2699 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break;
2700 case AttributeList::AT_ext_vector_type:
2701 HandleExtVectorTypeAttr(scope, D, Attr, S);
2703 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
2704 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
2705 case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break;
2706 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break;
2707 case AttributeList::AT_launch_bounds:
2708 HandleLaunchBoundsAttr(D, Attr, S);
2710 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
2711 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
2712 case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break;
2713 case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break;
2714 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
2715 case AttributeList::AT_ownership_returns:
2716 case AttributeList::AT_ownership_takes:
2717 case AttributeList::AT_ownership_holds:
2718 HandleOwnershipAttr (D, Attr, S); break;
2719 case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break;
2720 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
2721 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
2722 case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break;
2723 case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break;
2725 // Checker-specific.
2726 case AttributeList::AT_cf_consumed:
2727 case AttributeList::AT_ns_consumed: HandleNSConsumedAttr (D, Attr, S); break;
2728 case AttributeList::AT_ns_consumes_self:
2729 HandleNSConsumesSelfAttr(D, Attr, S); break;
2731 case AttributeList::AT_ns_returns_autoreleased:
2732 case AttributeList::AT_ns_returns_not_retained:
2733 case AttributeList::AT_cf_returns_not_retained:
2734 case AttributeList::AT_ns_returns_retained:
2735 case AttributeList::AT_cf_returns_retained:
2736 HandleNSReturnsRetainedAttr(D, Attr, S); break;
2738 case AttributeList::AT_reqd_wg_size:
2739 HandleReqdWorkGroupSize(D, Attr, S); break;
2741 case AttributeList::AT_init_priority:
2742 HandleInitPriorityAttr(D, Attr, S); break;
2744 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
2745 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
2746 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
2747 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
2748 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break;
2749 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break;
2750 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
2752 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
2753 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break;
2754 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break;
2755 case AttributeList::AT_transparent_union:
2756 HandleTransparentUnionAttr(D, Attr, S);
2758 case AttributeList::AT_objc_exception:
2759 HandleObjCExceptionAttr(D, Attr, S);
2761 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
2762 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
2763 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
2764 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
2765 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
2766 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break;
2767 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break;
2768 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break;
2769 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break;
2770 case AttributeList::IgnoredAttribute:
2773 case AttributeList::AT_no_instrument_function: // Interacts with -pg.
2774 HandleNoInstrumentFunctionAttr(D, Attr, S);
2776 case AttributeList::AT_stdcall:
2777 case AttributeList::AT_cdecl:
2778 case AttributeList::AT_fastcall:
2779 case AttributeList::AT_thiscall:
2780 case AttributeList::AT_pascal:
2781 HandleCallConvAttr(D, Attr, S);
2783 case AttributeList::AT_opencl_kernel_function:
2784 HandleOpenCLKernelAttr(D, Attr, S);
2786 case AttributeList::AT_uuid:
2787 HandleUuidAttr(D, Attr, S);
2790 // Ask target about the attribute.
2791 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
2792 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
2793 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
2799 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
2800 /// the attribute applies to decls. If the attribute is a type attribute, just
2801 /// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
2802 /// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
2803 static void ProcessDeclAttribute(Scope *scope, Decl *D,
2804 const AttributeList &Attr, Sema &S,
2805 bool NonInheritable, bool Inheritable) {
2806 if (Attr.isInvalid())
2809 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
2810 // FIXME: Try to deal with other __declspec attributes!
2814 ProcessNonInheritableDeclAttr(scope, D, Attr, S);
2817 ProcessInheritableDeclAttr(scope, D, Attr, S);
2820 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2821 /// attribute list to the specified decl, ignoring any type attributes.
2822 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
2823 const AttributeList *AttrList,
2824 bool NonInheritable, bool Inheritable) {
2825 for (const AttributeList* l = AttrList; l; l = l->getNext()) {
2826 ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable);
2830 // static int a9 __attribute__((weakref));
2831 // but that looks really pointless. We reject it.
2832 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
2833 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
2834 dyn_cast<NamedDecl>(D)->getNameAsString();
2839 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
2840 /// #pragma weak needs a non-definition decl and source may not have one
2841 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
2842 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
2843 NamedDecl *NewD = 0;
2844 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
2845 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
2846 FD->getLocation(), DeclarationName(II),
2847 FD->getType(), FD->getTypeSourceInfo());
2848 if (FD->getQualifier()) {
2849 FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
2850 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
2852 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
2853 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
2854 VD->getLocation(), II,
2855 VD->getType(), VD->getTypeSourceInfo(),
2856 VD->getStorageClass(),
2857 VD->getStorageClassAsWritten());
2858 if (VD->getQualifier()) {
2859 VarDecl *NewVD = cast<VarDecl>(NewD);
2860 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
2866 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2867 /// applied to it, possibly with an alias.
2868 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
2869 if (W.getUsed()) return; // only do this once
2871 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2872 IdentifierInfo *NDId = ND->getIdentifier();
2873 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
2874 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
2876 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2877 WeakTopLevelDecl.push_back(NewD);
2878 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2879 // to insert Decl at TU scope, sorry.
2880 DeclContext *SavedContext = CurContext;
2881 CurContext = Context.getTranslationUnitDecl();
2882 PushOnScopeChains(NewD, S);
2883 CurContext = SavedContext;
2884 } else { // just add weak to existing
2885 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
2889 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
2890 /// it, apply them to D. This is a bit tricky because PD can have attributes
2891 /// specified in many different places, and we need to find and apply them all.
2892 void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
2893 bool NonInheritable, bool Inheritable) {
2894 // It's valid to "forward-declare" #pragma weak, in which case we
2896 if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
2897 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
2898 if (IdentifierInfo *Id = ND->getIdentifier()) {
2899 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
2900 = WeakUndeclaredIdentifiers.find(Id);
2901 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
2902 WeakInfo W = I->second;
2903 DeclApplyPragmaWeak(S, ND, W);
2904 WeakUndeclaredIdentifiers[Id] = W;
2910 // Apply decl attributes from the DeclSpec if present.
2911 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
2912 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
2914 // Walk the declarator structure, applying decl attributes that were in a type
2915 // position to the decl itself. This handles cases like:
2916 // int *__attr__(x)** D;
2917 // when X is a decl attribute.
2918 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
2919 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
2920 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
2922 // Finally, apply any attributes on the decl itself.
2923 if (const AttributeList *Attrs = PD.getAttributes())
2924 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
2927 // This duplicates a vector push_back but hides the need to know the
2928 // size of the type.
2929 void Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
2930 assert(StackSize <= StackCapacity);
2932 // Grow the stack if necessary.
2933 if (StackSize == StackCapacity) {
2934 unsigned newCapacity = 2 * StackCapacity + 2;
2935 char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
2936 const char *oldBuffer = (const char*) Stack;
2939 memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
2942 Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
2943 StackCapacity = newCapacity;
2946 assert(StackSize < StackCapacity);
2947 new (&Stack[StackSize++]) DelayedDiagnostic(diag);
2950 void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
2952 DelayedDiagnostics &DD = S.DelayedDiagnostics;
2954 // Check the invariants.
2955 assert(DD.StackSize >= state.SavedStackSize);
2956 assert(state.SavedStackSize >= DD.ActiveStackBase);
2957 assert(DD.ParsingDepth > 0);
2959 // Drop the parsing depth.
2962 // If there are no active diagnostics, we're done.
2963 if (DD.StackSize == DD.ActiveStackBase)
2966 // We only want to actually emit delayed diagnostics when we
2967 // successfully parsed a decl.
2969 // We emit all the active diagnostics, not just those starting
2970 // from the saved state. The idea is this: we get one push for a
2971 // decl spec and another for each declarator; in a decl group like:
2972 // deprecated_typedef foo, *bar, baz();
2973 // only the declarator pops will be passed decls. This is correct;
2974 // we really do need to consider delayed diagnostics from the decl spec
2975 // for each of the different declarations.
2976 for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
2977 DelayedDiagnostic &diag = DD.Stack[i];
2981 switch (diag.Kind) {
2982 case DelayedDiagnostic::Deprecation:
2983 S.HandleDelayedDeprecationCheck(diag, decl);
2986 case DelayedDiagnostic::Access:
2987 S.HandleDelayedAccessCheck(diag, decl);
2993 // Destroy all the delayed diagnostics we're about to pop off.
2994 for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
2995 DD.Stack[i].destroy();
2997 DD.StackSize = state.SavedStackSize;
3000 static bool isDeclDeprecated(Decl *D) {
3002 if (D->hasAttr<DeprecatedAttr>())
3004 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
3008 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
3010 if (isDeclDeprecated(Ctx))
3013 DD.Triggered = true;
3014 if (!DD.getDeprecationMessage().empty())
3015 Diag(DD.Loc, diag::warn_deprecated_message)
3016 << DD.getDeprecationDecl()->getDeclName()
3017 << DD.getDeprecationMessage();
3019 Diag(DD.Loc, diag::warn_deprecated)
3020 << DD.getDeprecationDecl()->getDeclName();
3023 void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
3025 bool UnknownObjCClass) {
3026 // Delay if we're currently parsing a declaration.
3027 if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3028 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
3032 // Otherwise, don't warn if our current context is deprecated.
3033 if (isDeclDeprecated(cast<Decl>(CurContext)))
3035 if (!Message.empty())
3036 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3039 if (!UnknownObjCClass)
3040 Diag(Loc, diag::warn_deprecated) << D->getDeclName();
3042 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();