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/SourceManager.h"
21 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Sema/DeclSpec.h"
23 #include "clang/Sema/DelayedDiagnostic.h"
24 #include "llvm/ADT/StringExtras.h"
25 using namespace clang;
28 /// These constants match the enumerated choices of
29 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
33 ExpectedVariableOrFunction,
34 ExpectedFunctionOrMethod,
36 ExpectedParameterOrMethod,
37 ExpectedFunctionMethodOrBlock,
38 ExpectedClassOrVirtualMethod,
39 ExpectedFunctionMethodOrParameter,
41 ExpectedVirtualMethod,
45 ExpectedVariableFunctionOrLabel
48 //===----------------------------------------------------------------------===//
50 //===----------------------------------------------------------------------===//
52 static const FunctionType *getFunctionType(const Decl *D,
53 bool blocksToo = true) {
55 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
57 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
59 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
60 Ty = decl->getUnderlyingType();
64 if (Ty->isFunctionPointerType())
65 Ty = Ty->getAs<PointerType>()->getPointeeType();
66 else if (blocksToo && Ty->isBlockPointerType())
67 Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
69 return Ty->getAs<FunctionType>();
72 // FIXME: We should provide an abstraction around a method or function
73 // to provide the following bits of information.
75 /// isFunction - Return true if the given decl has function
76 /// type (function or function-typed variable).
77 static bool isFunction(const Decl *D) {
78 return getFunctionType(D, false) != NULL;
81 /// isFunctionOrMethod - Return true if the given decl has function
82 /// type (function or function-typed variable) or an Objective-C
84 static bool isFunctionOrMethod(const Decl *D) {
85 return isFunction(D)|| isa<ObjCMethodDecl>(D);
88 /// isFunctionOrMethodOrBlock - Return true if the given decl has function
89 /// type (function or function-typed variable) or an Objective-C
90 /// method or a block.
91 static bool isFunctionOrMethodOrBlock(const Decl *D) {
92 if (isFunctionOrMethod(D))
94 // check for block is more involved.
95 if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
96 QualType Ty = V->getType();
97 return Ty->isBlockPointerType();
99 return isa<BlockDecl>(D);
102 /// Return true if the given decl has a declarator that should have
103 /// been processed by Sema::GetTypeForDeclarator.
104 static bool hasDeclarator(const Decl *D) {
105 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
106 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
107 isa<ObjCPropertyDecl>(D);
110 /// hasFunctionProto - Return true if the given decl has a argument
111 /// information. This decl should have already passed
112 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
113 static bool hasFunctionProto(const Decl *D) {
114 if (const FunctionType *FnTy = getFunctionType(D))
115 return isa<FunctionProtoType>(FnTy);
117 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
122 /// getFunctionOrMethodNumArgs - Return number of function or method
123 /// arguments. It is an error to call this on a K&R function (use
124 /// hasFunctionProto first).
125 static unsigned getFunctionOrMethodNumArgs(const Decl *D) {
126 if (const FunctionType *FnTy = getFunctionType(D))
127 return cast<FunctionProtoType>(FnTy)->getNumArgs();
128 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
129 return BD->getNumParams();
130 return cast<ObjCMethodDecl>(D)->param_size();
133 static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
134 if (const FunctionType *FnTy = getFunctionType(D))
135 return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
136 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
137 return BD->getParamDecl(Idx)->getType();
139 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
142 static QualType getFunctionOrMethodResultType(const Decl *D) {
143 if (const FunctionType *FnTy = getFunctionType(D))
144 return cast<FunctionProtoType>(FnTy)->getResultType();
145 return cast<ObjCMethodDecl>(D)->getResultType();
148 static bool isFunctionOrMethodVariadic(const Decl *D) {
149 if (const FunctionType *FnTy = getFunctionType(D)) {
150 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
151 return proto->isVariadic();
152 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
153 return BD->isVariadic();
155 return cast<ObjCMethodDecl>(D)->isVariadic();
159 static bool isInstanceMethod(const Decl *D) {
160 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
161 return MethodDecl->isInstance();
165 static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
166 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
170 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
174 IdentifierInfo* ClsName = Cls->getIdentifier();
176 // FIXME: Should we walk the chain of classes?
177 return ClsName == &Ctx.Idents.get("NSString") ||
178 ClsName == &Ctx.Idents.get("NSMutableString");
181 static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
182 const PointerType *PT = T->getAs<PointerType>();
186 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
190 const RecordDecl *RD = RT->getDecl();
191 if (RD->getTagKind() != TTK_Struct)
194 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
197 static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
199 if (Attr.getNumArgs() != Num) {
200 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
207 //===----------------------------------------------------------------------===//
208 // Attribute Implementations
209 //===----------------------------------------------------------------------===//
211 // FIXME: All this manual attribute parsing code is gross. At the
212 // least add some helper functions to check most argument patterns (#
213 // and types of args).
215 static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
216 const AttributeList &Attr) {
217 TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
219 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
223 QualType curType = tDecl->getUnderlyingType();
227 // Special case where the argument is a template id.
228 if (Attr.getParameterName()) {
231 id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
233 ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
234 if (Size.isInvalid())
237 sizeExpr = Size.get();
239 // check the attribute arguments.
240 if (!checkAttributeNumArgs(S, Attr, 1))
243 sizeExpr = Attr.getArg(0);
246 // Instantiate/Install the vector type, and let Sema build the type for us.
247 // This will run the reguired checks.
248 QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
250 // FIXME: preserve the old source info.
251 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
253 // Remember this typedef decl, we will need it later for diagnostics.
254 S.ExtVectorDecls.push_back(tDecl);
258 static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
259 // check the attribute arguments.
260 if (!checkAttributeNumArgs(S, Attr, 0))
263 if (TagDecl *TD = dyn_cast<TagDecl>(D))
264 TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
265 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
266 // If the alignment is less than or equal to 8 bits, the packed attribute
268 if (!FD->getType()->isIncompleteType() &&
269 S.Context.getTypeAlign(FD->getType()) <= 8)
270 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
271 << Attr.getName() << FD->getType();
273 FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
275 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
278 static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
279 if (TagDecl *TD = dyn_cast<TagDecl>(D))
280 TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context));
282 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
285 static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
286 // check the attribute arguments.
287 if (!checkAttributeNumArgs(S, Attr, 0))
290 // The IBAction attributes only apply to instance methods.
291 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
292 if (MD->isInstanceMethod()) {
293 D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
297 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
300 static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
301 // check the attribute arguments.
302 if (!checkAttributeNumArgs(S, Attr, 0))
305 // The IBOutlet attributes only apply to instance variables of
306 // Objective-C classes.
307 if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) {
308 D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
312 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
315 static void handleIBOutletCollection(Sema &S, Decl *D,
316 const AttributeList &Attr) {
318 // The iboutletcollection attribute can have zero or one arguments.
319 if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
320 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
324 // The IBOutletCollection attributes only apply to instance variables of
325 // Objective-C classes.
326 if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
327 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
330 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
331 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
332 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
333 << VD->getType() << 0;
336 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
337 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
338 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type)
339 << PD->getType() << 1;
343 IdentifierInfo *II = Attr.getParameterName();
345 II = &S.Context.Idents.get("id");
347 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
348 S.getScopeForContext(D->getDeclContext()->getParent()));
350 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
353 QualType QT = TypeRep.get();
354 // Diagnose use of non-object type in iboutletcollection attribute.
355 // FIXME. Gnu attribute extension ignores use of builtin types in
356 // attributes. So, __attribute__((iboutletcollection(char))) will be
357 // treated as __attribute__((iboutletcollection())).
358 if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
359 !QT->isObjCObjectType()) {
360 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
363 D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
367 static void possibleTransparentUnionPointerType(QualType &T) {
368 if (const RecordType *UT = T->getAsUnionType())
369 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
370 RecordDecl *UD = UT->getDecl();
371 for (RecordDecl::field_iterator it = UD->field_begin(),
372 itend = UD->field_end(); it != itend; ++it) {
373 QualType QT = it->getType();
374 if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
382 static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
383 // GCC ignores the nonnull attribute on K&R style function prototypes, so we
385 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
386 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
387 << Attr.getName() << ExpectedFunction;
391 // In C++ the implicit 'this' function parameter also counts, and they are
393 bool HasImplicitThisParam = isInstanceMethod(D);
394 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
396 // The nonnull attribute only applies to pointers.
397 llvm::SmallVector<unsigned, 10> NonNullArgs;
399 for (AttributeList::arg_iterator I=Attr.arg_begin(),
400 E=Attr.arg_end(); I!=E; ++I) {
403 // The argument must be an integer constant expression.
405 llvm::APSInt ArgNum(32);
406 if (Ex->isTypeDependent() || Ex->isValueDependent() ||
407 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
408 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
409 << "nonnull" << Ex->getSourceRange();
413 unsigned x = (unsigned) ArgNum.getZExtValue();
415 if (x < 1 || x > NumArgs) {
416 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
417 << "nonnull" << I.getArgNum() << Ex->getSourceRange();
422 if (HasImplicitThisParam) {
424 S.Diag(Attr.getLoc(),
425 diag::err_attribute_invalid_implicit_this_argument)
426 << "nonnull" << Ex->getSourceRange();
432 // Is the function argument a pointer type?
433 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
434 possibleTransparentUnionPointerType(T);
436 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
437 // FIXME: Should also highlight argument in decl.
438 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
439 << "nonnull" << Ex->getSourceRange();
443 NonNullArgs.push_back(x);
446 // If no arguments were specified to __attribute__((nonnull)) then all pointer
447 // arguments have a nonnull attribute.
448 if (NonNullArgs.empty()) {
449 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) {
450 QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType();
451 possibleTransparentUnionPointerType(T);
452 if (T->isAnyPointerType() || T->isBlockPointerType())
453 NonNullArgs.push_back(I);
456 // No pointer arguments?
457 if (NonNullArgs.empty()) {
458 // Warn the trivial case only if attribute is not coming from a
459 // macro instantiation.
460 if (Attr.getLoc().isFileID())
461 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
466 unsigned* start = &NonNullArgs[0];
467 unsigned size = NonNullArgs.size();
468 llvm::array_pod_sort(start, start + size);
469 D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
473 static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
474 // This attribute must be applied to a function declaration.
475 // The first argument to the attribute must be a string,
476 // the name of the resource, for example "malloc".
477 // The following arguments must be argument indexes, the arguments must be
478 // of integer type for Returns, otherwise of pointer type.
479 // The difference between Holds and Takes is that a pointer may still be used
480 // after being held. free() should be __attribute((ownership_takes)), whereas
481 // a list append function may well be __attribute((ownership_holds)).
483 if (!AL.getParameterName()) {
484 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
485 << AL.getName()->getName() << 1;
488 // Figure out our Kind, and check arguments while we're at it.
489 OwnershipAttr::OwnershipKind K;
490 switch (AL.getKind()) {
491 case AttributeList::AT_ownership_takes:
492 K = OwnershipAttr::Takes;
493 if (AL.getNumArgs() < 1) {
494 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
498 case AttributeList::AT_ownership_holds:
499 K = OwnershipAttr::Holds;
500 if (AL.getNumArgs() < 1) {
501 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
505 case AttributeList::AT_ownership_returns:
506 K = OwnershipAttr::Returns;
507 if (AL.getNumArgs() > 1) {
508 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
509 << AL.getNumArgs() + 1;
514 // This should never happen given how we are called.
515 llvm_unreachable("Unknown ownership attribute");
518 if (!isFunction(D) || !hasFunctionProto(D)) {
519 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
520 << AL.getName() << ExpectedFunction;
524 // In C++ the implicit 'this' function parameter also counts, and they are
526 bool HasImplicitThisParam = isInstanceMethod(D);
527 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
529 llvm::StringRef Module = AL.getParameterName()->getName();
531 // Normalize the argument, __foo__ becomes foo.
532 if (Module.startswith("__") && Module.endswith("__"))
533 Module = Module.substr(2, Module.size() - 4);
535 llvm::SmallVector<unsigned, 10> OwnershipArgs;
537 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
541 llvm::APSInt ArgNum(32);
542 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
543 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
544 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
545 << AL.getName()->getName() << IdxExpr->getSourceRange();
549 unsigned x = (unsigned) ArgNum.getZExtValue();
551 if (x > NumArgs || x < 1) {
552 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
553 << AL.getName()->getName() << x << IdxExpr->getSourceRange();
557 if (HasImplicitThisParam) {
559 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
560 << "ownership" << IdxExpr->getSourceRange();
567 case OwnershipAttr::Takes:
568 case OwnershipAttr::Holds: {
569 // Is the function argument a pointer type?
570 QualType T = getFunctionOrMethodArgType(D, x);
571 if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
572 // FIXME: Should also highlight argument in decl.
573 S.Diag(AL.getLoc(), diag::err_ownership_type)
574 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
576 << IdxExpr->getSourceRange();
581 case OwnershipAttr::Returns: {
582 if (AL.getNumArgs() > 1) {
583 // Is the function argument an integer type?
584 Expr *IdxExpr = AL.getArg(0);
585 llvm::APSInt ArgNum(32);
586 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
587 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
588 S.Diag(AL.getLoc(), diag::err_ownership_type)
589 << "ownership_returns" << "integer"
590 << IdxExpr->getSourceRange();
597 llvm_unreachable("Unknown ownership attribute");
600 // Check we don't have a conflict with another ownership attribute.
601 for (specific_attr_iterator<OwnershipAttr>
602 i = D->specific_attr_begin<OwnershipAttr>(),
603 e = D->specific_attr_end<OwnershipAttr>();
605 if ((*i)->getOwnKind() != K) {
606 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
609 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
610 << AL.getName()->getName() << "ownership_*";
615 OwnershipArgs.push_back(x);
618 unsigned* start = OwnershipArgs.data();
619 unsigned size = OwnershipArgs.size();
620 llvm::array_pod_sort(start, start + size);
622 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
623 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
627 D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
631 /// Whether this declaration has internal linkage for the purposes of
632 /// things that want to complain about things not have internal linkage.
633 static bool hasEffectivelyInternalLinkage(NamedDecl *D) {
634 switch (D->getLinkage()) {
636 case InternalLinkage:
639 // Template instantiations that go from external to unique-external
640 // shouldn't get diagnosed.
641 case UniqueExternalLinkage:
644 case ExternalLinkage:
647 llvm_unreachable("unknown linkage kind!");
651 static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
652 // Check the attribute arguments.
653 if (Attr.getNumArgs() > 1) {
654 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
658 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
659 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
660 << Attr.getName() << ExpectedVariableOrFunction;
664 NamedDecl *nd = cast<NamedDecl>(D);
668 // static int a __attribute__((weakref ("v2")));
669 // static int b() __attribute__((weakref ("f3")));
671 // and ignores the attributes of
673 // static int a __attribute__((weakref ("v2")));
676 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
677 if (!Ctx->isFileContext()) {
678 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
679 nd->getNameAsString();
683 // The GCC manual says
685 // At present, a declaration to which `weakref' is attached can only
691 // given as an argument to `weakref' or to `alias', `weakref' is
692 // equivalent to `weak'.
694 // gcc 4.4.1 will accept
695 // int a7 __attribute__((weakref));
697 // int a7 __attribute__((weak));
698 // This looks like a bug in gcc. We reject that for now. We should revisit
699 // it if this behaviour is actually used.
701 if (!hasEffectivelyInternalLinkage(nd)) {
702 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
707 // static ((alias ("y"), weakref)).
708 // Should we? How to check that weakref is before or after alias?
710 if (Attr.getNumArgs() == 1) {
711 Expr *Arg = Attr.getArg(0);
712 Arg = Arg->IgnoreParenCasts();
713 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
715 if (Str == 0 || Str->isWide()) {
716 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
720 // GCC will accept anything as the argument of weakref. Should we
721 // check for an existing decl?
722 D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
726 D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
729 static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
730 // check the attribute arguments.
731 if (Attr.getNumArgs() != 1) {
732 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
736 Expr *Arg = Attr.getArg(0);
737 Arg = Arg->IgnoreParenCasts();
738 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
740 if (Str == 0 || Str->isWide()) {
741 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
746 if (S.Context.Target.getTriple().isOSDarwin()) {
747 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
751 // FIXME: check if target symbol exists in current file
753 D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
757 static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
758 // Check the attribute arguments.
759 if (!checkAttributeNumArgs(S, Attr, 0))
762 if (!isa<FunctionDecl>(D)) {
763 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
764 << Attr.getName() << ExpectedFunction;
768 D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
771 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
772 const AttributeList &Attr) {
773 // Check the attribute arguments.
774 if (Attr.hasParameterOrArguments()) {
775 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
779 if (!isa<FunctionDecl>(D)) {
780 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
781 << Attr.getName() << ExpectedFunction;
785 D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
788 static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
789 // Check the attribute arguments.
790 if (Attr.hasParameterOrArguments()) {
791 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
795 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
796 QualType RetTy = FD->getResultType();
797 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
798 D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
803 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
806 static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
807 // check the attribute arguments.
808 if (!checkAttributeNumArgs(S, Attr, 0))
811 D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
814 static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
815 assert(!Attr.isInvalid());
817 D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
819 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
820 << Attr.getName() << ExpectedVariable;
823 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
824 assert(!Attr.isInvalid());
826 D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
828 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
829 << Attr.getName() << ExpectedVariable;
832 static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
833 if (hasDeclarator(D)) return;
835 if (S.CheckNoReturnAttr(attr)) return;
837 if (!isa<ObjCMethodDecl>(D)) {
838 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
839 << attr.getName() << ExpectedFunctionOrMethod;
843 D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
846 bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
847 if (attr.hasParameterOrArguments()) {
848 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
856 static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
857 const AttributeList &Attr) {
859 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
860 // because 'analyzer_noreturn' does not impact the type.
862 if(!checkAttributeNumArgs(S, Attr, 0))
865 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
866 ValueDecl *VD = dyn_cast<ValueDecl>(D);
867 if (VD == 0 || (!VD->getType()->isBlockPointerType()
868 && !VD->getType()->isFunctionPointerType())) {
869 S.Diag(Attr.getLoc(),
870 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
871 : diag::warn_attribute_wrong_decl_type)
872 << Attr.getName() << ExpectedFunctionMethodOrBlock;
877 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
881 static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
883 Returning a Vector Class in Registers
885 According to the PPU ABI specifications, a class with a single member of
886 vector type is returned in memory when used as the return value of a function.
887 This results in inefficient code when implementing vector classes. To return
888 the value in a single vector register, add the vecreturn attribute to the
889 class definition. This attribute is also applicable to struct types.
896 } __attribute__((vecreturn));
898 Vector Add(Vector lhs, Vector rhs)
901 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
902 return result; // This will be returned in a register
905 if (!isa<RecordDecl>(D)) {
906 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
907 << Attr.getName() << ExpectedClass;
911 if (D->getAttr<VecReturnAttr>()) {
912 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
916 RecordDecl *record = cast<RecordDecl>(D);
919 if (!isa<CXXRecordDecl>(record)) {
920 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
924 if (!cast<CXXRecordDecl>(record)->isPOD()) {
925 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
929 for (RecordDecl::field_iterator iter = record->field_begin();
930 iter != record->field_end(); iter++) {
931 if ((count == 1) || !iter->getType()->isVectorType()) {
932 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
938 D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
941 static void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
942 if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) {
943 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
944 << Attr.getName() << ExpectedFunctionMethodOrParameter;
947 // FIXME: Actually store the attribute on the declaration
950 static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
951 // check the attribute arguments.
952 if (Attr.hasParameterOrArguments()) {
953 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
957 if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
958 !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) {
959 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
960 << Attr.getName() << ExpectedVariableFunctionOrLabel;
964 D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
967 static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
968 // check the attribute arguments.
969 if (Attr.hasParameterOrArguments()) {
970 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
974 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
975 if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
976 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
979 } else if (!isFunctionOrMethod(D)) {
980 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
981 << Attr.getName() << ExpectedVariableOrFunction;
985 D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
988 static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
989 // check the attribute arguments.
990 if (Attr.getNumArgs() > 1) {
991 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
995 int priority = 65535; // FIXME: Do not hardcode such constants.
996 if (Attr.getNumArgs() > 0) {
997 Expr *E = Attr.getArg(0);
998 llvm::APSInt Idx(32);
999 if (E->isTypeDependent() || E->isValueDependent() ||
1000 !E->isIntegerConstantExpr(Idx, S.Context)) {
1001 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1002 << "constructor" << 1 << E->getSourceRange();
1005 priority = Idx.getZExtValue();
1008 if (!isa<FunctionDecl>(D)) {
1009 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1010 << Attr.getName() << ExpectedFunction;
1014 D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1018 static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1019 // check the attribute arguments.
1020 if (Attr.getNumArgs() > 1) {
1021 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1025 int priority = 65535; // FIXME: Do not hardcode such constants.
1026 if (Attr.getNumArgs() > 0) {
1027 Expr *E = Attr.getArg(0);
1028 llvm::APSInt Idx(32);
1029 if (E->isTypeDependent() || E->isValueDependent() ||
1030 !E->isIntegerConstantExpr(Idx, S.Context)) {
1031 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1032 << "destructor" << 1 << E->getSourceRange();
1035 priority = Idx.getZExtValue();
1038 if (!isa<FunctionDecl>(D)) {
1039 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1040 << Attr.getName() << ExpectedFunction;
1044 D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1048 static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1049 unsigned NumArgs = Attr.getNumArgs();
1051 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1055 // Handle the case where deprecated attribute has a text message.
1056 llvm::StringRef Str;
1058 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1060 S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1064 Str = SE->getString();
1067 D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
1070 static void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1071 unsigned NumArgs = Attr.getNumArgs();
1073 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1077 // Handle the case where unavailable attribute has a text message.
1078 llvm::StringRef Str;
1080 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1082 S.Diag(Attr.getArg(0)->getLocStart(),
1083 diag::err_attribute_not_string) << "unavailable";
1086 Str = SE->getString();
1088 D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1091 static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1092 const AttributeList &Attr) {
1093 unsigned NumArgs = Attr.getNumArgs();
1095 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1099 D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1100 Attr.getLoc(), S.Context));
1103 static void handleAvailabilityAttr(Sema &S, Decl *D,
1104 const AttributeList &Attr) {
1105 IdentifierInfo *Platform = Attr.getParameterName();
1106 SourceLocation PlatformLoc = Attr.getParameterLoc();
1108 llvm::StringRef PlatformName
1109 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
1110 if (PlatformName.empty()) {
1111 S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
1114 PlatformName = Platform->getName();
1117 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
1118 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
1119 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1120 bool IsUnavailable = Attr.getUnavailableLoc().isValid();
1122 // Ensure that Introduced < Deprecated < Obsoleted (although not all
1123 // of these steps are needed).
1124 if (Introduced.isValid() && Deprecated.isValid() &&
1125 !(Introduced.Version < Deprecated.Version)) {
1126 S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
1127 << 1 << PlatformName << Deprecated.Version.getAsString()
1128 << 0 << Introduced.Version.getAsString();
1132 if (Introduced.isValid() && Obsoleted.isValid() &&
1133 !(Introduced.Version < Obsoleted.Version)) {
1134 S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering)
1135 << 2 << PlatformName << Obsoleted.Version.getAsString()
1136 << 0 << Introduced.Version.getAsString();
1140 if (Deprecated.isValid() && Obsoleted.isValid() &&
1141 !(Deprecated.Version < Obsoleted.Version)) {
1142 S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering)
1143 << 2 << PlatformName << Obsoleted.Version.getAsString()
1144 << 1 << Deprecated.Version.getAsString();
1148 D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
1156 static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1157 // check the attribute arguments.
1158 if(!checkAttributeNumArgs(S, Attr, 1))
1161 Expr *Arg = Attr.getArg(0);
1162 Arg = Arg->IgnoreParenCasts();
1163 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1165 if (Str == 0 || Str->isWide()) {
1166 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1167 << "visibility" << 1;
1171 llvm::StringRef TypeStr = Str->getString();
1172 VisibilityAttr::VisibilityType type;
1174 if (TypeStr == "default")
1175 type = VisibilityAttr::Default;
1176 else if (TypeStr == "hidden")
1177 type = VisibilityAttr::Hidden;
1178 else if (TypeStr == "internal")
1179 type = VisibilityAttr::Hidden; // FIXME
1180 else if (TypeStr == "protected")
1181 type = VisibilityAttr::Protected;
1183 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
1187 D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
1190 static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
1191 const AttributeList &Attr) {
1192 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1194 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1199 if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) {
1200 if (!Attr.getParameterName() && Attr.getNumArgs() == 1) {
1201 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1202 << "objc_method_family" << 1;
1204 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1210 llvm::StringRef param = Attr.getParameterName()->getName();
1211 ObjCMethodFamilyAttr::FamilyKind family;
1212 if (param == "none")
1213 family = ObjCMethodFamilyAttr::OMF_None;
1214 else if (param == "alloc")
1215 family = ObjCMethodFamilyAttr::OMF_alloc;
1216 else if (param == "copy")
1217 family = ObjCMethodFamilyAttr::OMF_copy;
1218 else if (param == "init")
1219 family = ObjCMethodFamilyAttr::OMF_init;
1220 else if (param == "mutableCopy")
1221 family = ObjCMethodFamilyAttr::OMF_mutableCopy;
1222 else if (param == "new")
1223 family = ObjCMethodFamilyAttr::OMF_new;
1225 // Just warn and ignore it. This is future-proof against new
1226 // families being used in system headers.
1227 S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family);
1231 if (family == ObjCMethodFamilyAttr::OMF_init &&
1232 !method->getResultType()->isObjCObjectPointerType()) {
1233 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
1234 << method->getResultType();
1235 // Ignore the attribute.
1239 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1240 S.Context, family));
1243 static void handleObjCExceptionAttr(Sema &S, Decl *D,
1244 const AttributeList &Attr) {
1245 if (!checkAttributeNumArgs(S, Attr, 0))
1248 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
1250 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1254 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
1257 static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
1258 if (Attr.getNumArgs() != 0) {
1259 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1262 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
1263 QualType T = TD->getUnderlyingType();
1264 if (!T->isPointerType() ||
1265 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) {
1266 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
1270 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1274 handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1275 if (Attr.getNumArgs() != 0) {
1276 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1280 if (!isa<FunctionDecl>(D)) {
1281 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1285 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1288 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1289 if (!Attr.getParameterName()) {
1290 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1295 if (Attr.getNumArgs() != 0) {
1296 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1300 BlocksAttr::BlockType type;
1301 if (Attr.getParameterName()->isStr("byref"))
1302 type = BlocksAttr::ByRef;
1304 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1305 << "blocks" << Attr.getParameterName();
1309 D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
1312 static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1313 // check the attribute arguments.
1314 if (Attr.getNumArgs() > 2) {
1315 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
1320 if (Attr.getNumArgs() > 0) {
1321 Expr *E = Attr.getArg(0);
1322 llvm::APSInt Idx(32);
1323 if (E->isTypeDependent() || E->isValueDependent() ||
1324 !E->isIntegerConstantExpr(Idx, S.Context)) {
1325 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1326 << "sentinel" << 1 << E->getSourceRange();
1329 sentinel = Idx.getZExtValue();
1332 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1333 << E->getSourceRange();
1339 if (Attr.getNumArgs() > 1) {
1340 Expr *E = Attr.getArg(1);
1341 llvm::APSInt Idx(32);
1342 if (E->isTypeDependent() || E->isValueDependent() ||
1343 !E->isIntegerConstantExpr(Idx, S.Context)) {
1344 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1345 << "sentinel" << 2 << E->getSourceRange();
1348 nullPos = Idx.getZExtValue();
1350 if (nullPos > 1 || nullPos < 0) {
1351 // FIXME: This error message could be improved, it would be nice
1352 // to say what the bounds actually are.
1353 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
1354 << E->getSourceRange();
1359 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1360 const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1361 assert(FT && "FunctionDecl has non-function type?");
1363 if (isa<FunctionNoProtoType>(FT)) {
1364 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1368 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
1369 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1372 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
1373 if (!MD->isVariadic()) {
1374 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1377 } else if (isa<BlockDecl>(D)) {
1378 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1381 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
1382 QualType Ty = V->getType();
1383 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
1384 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
1385 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
1386 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
1387 int m = Ty->isFunctionPointerType() ? 0 : 1;
1388 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
1392 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1393 << Attr.getName() << ExpectedFunctionMethodOrBlock;
1397 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1398 << Attr.getName() << ExpectedFunctionMethodOrBlock;
1401 D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1405 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1406 // check the attribute arguments.
1407 if (!checkAttributeNumArgs(S, Attr, 0))
1410 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1411 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1412 << Attr.getName() << ExpectedFunctionOrMethod;
1416 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1417 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1418 << Attr.getName() << 0;
1421 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1422 if (MD->getResultType()->isVoidType()) {
1423 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1424 << Attr.getName() << 1;
1428 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1431 static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1432 // check the attribute arguments.
1433 if (Attr.hasParameterOrArguments()) {
1434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1438 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1439 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1440 << Attr.getName() << ExpectedVariableOrFunction;
1444 NamedDecl *nd = cast<NamedDecl>(D);
1446 // 'weak' only applies to declarations with external linkage.
1447 if (hasEffectivelyInternalLinkage(nd)) {
1448 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
1452 nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
1455 static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1456 // check the attribute arguments.
1457 if (!checkAttributeNumArgs(S, Attr, 0))
1461 // weak_import only applies to variable & function declarations.
1463 if (!D->canBeWeakImported(isDef)) {
1465 S.Diag(Attr.getLoc(),
1466 diag::warn_attribute_weak_import_invalid_on_definition)
1467 << "weak_import" << 2 /*variable and function*/;
1468 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
1469 (S.Context.Target.getTriple().isOSDarwin() &&
1470 isa<ObjCInterfaceDecl>(D))) {
1471 // Nothing to warn about here.
1473 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1474 << Attr.getName() << ExpectedVariableOrFunction;
1479 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
1482 static void handleReqdWorkGroupSize(Sema &S, Decl *D,
1483 const AttributeList &Attr) {
1484 // Attribute has 3 arguments.
1485 if (!checkAttributeNumArgs(S, Attr, 3))
1489 for (unsigned i = 0; i < 3; ++i) {
1490 Expr *E = Attr.getArg(i);
1491 llvm::APSInt ArgNum(32);
1492 if (E->isTypeDependent() || E->isValueDependent() ||
1493 !E->isIntegerConstantExpr(ArgNum, S.Context)) {
1494 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1495 << "reqd_work_group_size" << E->getSourceRange();
1498 WGSize[i] = (unsigned) ArgNum.getZExtValue();
1500 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1501 WGSize[0], WGSize[1],
1505 static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1506 // Attribute has no arguments.
1507 if (!checkAttributeNumArgs(S, Attr, 1))
1510 // Make sure that there is a string literal as the sections's single
1512 Expr *ArgExpr = Attr.getArg(0);
1513 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1515 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
1519 // If the target wants to validate the section specifier, make it happen.
1520 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString());
1521 if (!Error.empty()) {
1522 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target)
1527 // This attribute cannot be applied to local variables.
1528 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
1529 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
1533 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1538 static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1539 // check the attribute arguments.
1540 if (Attr.hasParameterOrArguments()) {
1541 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1545 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1546 if (Existing->getLocation().isInvalid())
1547 Existing->setLocation(Attr.getLoc());
1549 D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1553 static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1554 // check the attribute arguments.
1555 if (Attr.hasParameterOrArguments()) {
1556 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1560 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1561 if (Existing->getLocation().isInvalid())
1562 Existing->setLocation(Attr.getLoc());
1564 D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1568 static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1569 // check the attribute arguments.
1570 if (!checkAttributeNumArgs(S, Attr, 0))
1573 D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1576 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1577 if (!Attr.getParameterName()) {
1578 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1582 if (Attr.getNumArgs() != 0) {
1583 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1587 VarDecl *VD = dyn_cast<VarDecl>(D);
1589 if (!VD || !VD->hasLocalStorage()) {
1590 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1594 // Look up the function
1595 // FIXME: Lookup probably isn't looking in the right place
1596 NamedDecl *CleanupDecl
1597 = S.LookupSingleName(S.TUScope, Attr.getParameterName(),
1598 Attr.getParameterLoc(), Sema::LookupOrdinaryName);
1600 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1601 Attr.getParameterName();
1605 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1607 S.Diag(Attr.getParameterLoc(),
1608 diag::err_attribute_cleanup_arg_not_function)
1609 << Attr.getParameterName();
1613 if (FD->getNumParams() != 1) {
1614 S.Diag(Attr.getParameterLoc(),
1615 diag::err_attribute_cleanup_func_must_take_one_arg)
1616 << Attr.getParameterName();
1620 // We're currently more strict than GCC about what function types we accept.
1621 // If this ever proves to be a problem it should be easy to fix.
1622 QualType Ty = S.Context.getPointerType(VD->getType());
1623 QualType ParamTy = FD->getParamDecl(0)->getType();
1624 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
1625 ParamTy, Ty) != Sema::Compatible) {
1626 S.Diag(Attr.getParameterLoc(),
1627 diag::err_attribute_cleanup_func_arg_incompatible_type) <<
1628 Attr.getParameterName() << ParamTy << Ty;
1632 D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1633 S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1636 /// Handle __attribute__((format_arg((idx)))) attribute based on
1637 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1638 static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1639 if (!checkAttributeNumArgs(S, Attr, 1))
1642 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
1643 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1644 << Attr.getName() << ExpectedFunction;
1648 // In C++ the implicit 'this' function parameter also counts, and they are
1649 // counted from one.
1650 bool HasImplicitThisParam = isInstanceMethod(D);
1651 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1652 unsigned FirstIdx = 1;
1654 // checks for the 2nd argument
1655 Expr *IdxExpr = Attr.getArg(0);
1656 llvm::APSInt Idx(32);
1657 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1658 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1659 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1660 << "format" << 2 << IdxExpr->getSourceRange();
1664 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1665 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1666 << "format" << 2 << IdxExpr->getSourceRange();
1670 unsigned ArgIdx = Idx.getZExtValue() - 1;
1672 if (HasImplicitThisParam) {
1674 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
1675 << "format_arg" << IdxExpr->getSourceRange();
1681 // make sure the format string is really a string
1682 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1684 bool not_nsstring_type = !isNSStringType(Ty, S.Context);
1685 if (not_nsstring_type &&
1686 !isCFStringType(Ty, S.Context) &&
1687 (!Ty->isPointerType() ||
1688 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
1689 // FIXME: Should highlight the actual expression that has the wrong type.
1690 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1691 << (not_nsstring_type ? "a string type" : "an NSString")
1692 << IdxExpr->getSourceRange();
1695 Ty = getFunctionOrMethodResultType(D);
1696 if (!isNSStringType(Ty, S.Context) &&
1697 !isCFStringType(Ty, S.Context) &&
1698 (!Ty->isPointerType() ||
1699 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
1700 // FIXME: Should highlight the actual expression that has the wrong type.
1701 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
1702 << (not_nsstring_type ? "string type" : "NSString")
1703 << IdxExpr->getSourceRange();
1707 D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
1708 Idx.getZExtValue()));
1711 enum FormatAttrKind {
1720 /// getFormatAttrKind - Map from format attribute names to supported format
1722 static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
1723 // Check for formats that get handled specially.
1724 if (Format == "NSString")
1725 return NSStringFormat;
1726 if (Format == "CFString")
1727 return CFStringFormat;
1728 if (Format == "strftime")
1729 return StrftimeFormat;
1731 // Otherwise, check for supported formats.
1732 if (Format == "scanf" || Format == "printf" || Format == "printf0" ||
1733 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" ||
1734 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" ||
1735 Format == "zcmn_err" ||
1736 Format == "kprintf") // OpenBSD.
1737 return SupportedFormat;
1739 if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1740 Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
1741 return IgnoredFormat;
1743 return InvalidFormat;
1746 /// Handle __attribute__((init_priority(priority))) attributes based on
1747 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1748 static void handleInitPriorityAttr(Sema &S, Decl *D,
1749 const AttributeList &Attr) {
1750 if (!S.getLangOptions().CPlusPlus) {
1751 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1755 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
1756 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1760 QualType T = dyn_cast<VarDecl>(D)->getType();
1761 if (S.Context.getAsArrayType(T))
1762 T = S.Context.getBaseElementType(T);
1763 if (!T->getAs<RecordType>()) {
1764 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1769 if (Attr.getNumArgs() != 1) {
1770 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1774 Expr *priorityExpr = Attr.getArg(0);
1776 llvm::APSInt priority(32);
1777 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
1778 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
1779 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1780 << "init_priority" << priorityExpr->getSourceRange();
1784 unsigned prioritynum = priority.getZExtValue();
1785 if (prioritynum < 101 || prioritynum > 65535) {
1786 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
1787 << priorityExpr->getSourceRange();
1791 D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1795 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1796 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1797 static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1799 if (!Attr.getParameterName()) {
1800 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1805 if (Attr.getNumArgs() != 2) {
1806 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1810 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
1811 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1812 << Attr.getName() << ExpectedFunction;
1816 // In C++ the implicit 'this' function parameter also counts, and they are
1817 // counted from one.
1818 bool HasImplicitThisParam = isInstanceMethod(D);
1819 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
1820 unsigned FirstIdx = 1;
1822 llvm::StringRef Format = Attr.getParameterName()->getName();
1824 // Normalize the argument, __foo__ becomes foo.
1825 if (Format.startswith("__") && Format.endswith("__"))
1826 Format = Format.substr(2, Format.size() - 4);
1828 // Check for supported formats.
1829 FormatAttrKind Kind = getFormatAttrKind(Format);
1831 if (Kind == IgnoredFormat)
1834 if (Kind == InvalidFormat) {
1835 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1836 << "format" << Attr.getParameterName()->getName();
1840 // checks for the 2nd argument
1841 Expr *IdxExpr = Attr.getArg(0);
1842 llvm::APSInt Idx(32);
1843 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
1844 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1845 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1846 << "format" << 2 << IdxExpr->getSourceRange();
1850 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1851 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1852 << "format" << 2 << IdxExpr->getSourceRange();
1856 // FIXME: Do we need to bounds check?
1857 unsigned ArgIdx = Idx.getZExtValue() - 1;
1859 if (HasImplicitThisParam) {
1861 S.Diag(Attr.getLoc(),
1862 diag::err_format_attribute_implicit_this_format_string)
1863 << IdxExpr->getSourceRange();
1869 // make sure the format string is really a string
1870 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1872 if (Kind == CFStringFormat) {
1873 if (!isCFStringType(Ty, S.Context)) {
1874 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1875 << "a CFString" << IdxExpr->getSourceRange();
1878 } else if (Kind == NSStringFormat) {
1879 // FIXME: do we need to check if the type is NSString*? What are the
1881 if (!isNSStringType(Ty, S.Context)) {
1882 // FIXME: Should highlight the actual expression that has the wrong type.
1883 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1884 << "an NSString" << IdxExpr->getSourceRange();
1887 } else if (!Ty->isPointerType() ||
1888 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
1889 // FIXME: Should highlight the actual expression that has the wrong type.
1890 S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1891 << "a string type" << IdxExpr->getSourceRange();
1895 // check the 3rd argument
1896 Expr *FirstArgExpr = Attr.getArg(1);
1897 llvm::APSInt FirstArg(32);
1898 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
1899 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1900 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
1901 << "format" << 3 << FirstArgExpr->getSourceRange();
1905 // check if the function is variadic if the 3rd argument non-zero
1906 if (FirstArg != 0) {
1907 if (isFunctionOrMethodVariadic(D)) {
1908 ++NumArgs; // +1 for ...
1910 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
1915 // strftime requires FirstArg to be 0 because it doesn't read from any
1916 // variable the input is just the current time + the format string.
1917 if (Kind == StrftimeFormat) {
1918 if (FirstArg != 0) {
1919 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1920 << FirstArgExpr->getSourceRange();
1923 // if 0 it disables parameter checking (to use with e.g. va_list)
1924 } else if (FirstArg != 0 && FirstArg != NumArgs) {
1925 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
1926 << "format" << 3 << FirstArgExpr->getSourceRange();
1930 // Check whether we already have an equivalent format attribute.
1931 for (specific_attr_iterator<FormatAttr>
1932 i = D->specific_attr_begin<FormatAttr>(),
1933 e = D->specific_attr_end<FormatAttr>();
1936 if (f->getType() == Format &&
1937 f->getFormatIdx() == (int)Idx.getZExtValue() &&
1938 f->getFirstArg() == (int)FirstArg.getZExtValue()) {
1939 // If we don't have a valid location for this attribute, adopt the
1941 if (f->getLocation().isInvalid())
1942 f->setLocation(Attr.getLoc());
1947 D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1949 FirstArg.getZExtValue()));
1952 static void handleTransparentUnionAttr(Sema &S, Decl *D,
1953 const AttributeList &Attr) {
1954 // check the attribute arguments.
1955 if (!checkAttributeNumArgs(S, Attr, 0))
1959 // Try to find the underlying union declaration.
1961 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
1962 if (TD && TD->getUnderlyingType()->isUnionType())
1963 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1965 RD = dyn_cast<RecordDecl>(D);
1967 if (!RD || !RD->isUnion()) {
1968 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1969 << Attr.getName() << ExpectedUnion;
1973 if (!RD->isDefinition()) {
1974 S.Diag(Attr.getLoc(),
1975 diag::warn_transparent_union_attribute_not_definition);
1979 RecordDecl::field_iterator Field = RD->field_begin(),
1980 FieldEnd = RD->field_end();
1981 if (Field == FieldEnd) {
1982 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
1986 FieldDecl *FirstField = *Field;
1987 QualType FirstType = FirstField->getType();
1988 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
1989 S.Diag(FirstField->getLocation(),
1990 diag::warn_transparent_union_attribute_floating)
1991 << FirstType->isVectorType() << FirstType;
1995 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
1996 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
1997 for (; Field != FieldEnd; ++Field) {
1998 QualType FieldType = Field->getType();
1999 if (S.Context.getTypeSize(FieldType) != FirstSize ||
2000 S.Context.getTypeAlign(FieldType) != FirstAlign) {
2001 // Warn if we drop the attribute.
2002 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2003 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
2004 : S.Context.getTypeAlign(FieldType);
2005 S.Diag(Field->getLocation(),
2006 diag::warn_transparent_union_attribute_field_size_align)
2007 << isSize << Field->getDeclName() << FieldBits;
2008 unsigned FirstBits = isSize? FirstSize : FirstAlign;
2009 S.Diag(FirstField->getLocation(),
2010 diag::note_transparent_union_first_field_size_align)
2011 << isSize << FirstBits;
2016 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
2019 static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2020 // check the attribute arguments.
2021 if (!checkAttributeNumArgs(S, Attr, 1))
2024 Expr *ArgExpr = Attr.getArg(0);
2025 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2027 // Make sure that there is a string literal as the annotation's single
2030 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
2033 D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2037 static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2038 // check the attribute arguments.
2039 if (Attr.getNumArgs() > 1) {
2040 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2044 //FIXME: The C++0x version of this attribute has more limited applicabilty
2045 // than GNU's, and should error out when it is used to specify a
2046 // weaker alignment, rather than being silently ignored.
2048 if (Attr.getNumArgs() == 0) {
2049 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
2053 S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
2056 void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
2057 if (E->isTypeDependent() || E->isValueDependent()) {
2058 // Save dependent expressions in the AST to be instantiated.
2059 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2063 // FIXME: Cache the number on the Attr object?
2064 llvm::APSInt Alignment(32);
2065 if (!E->isIntegerConstantExpr(Alignment, Context)) {
2066 Diag(AttrLoc, diag::err_attribute_argument_not_int)
2067 << "aligned" << E->getSourceRange();
2070 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
2071 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
2072 << E->getSourceRange();
2076 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2079 void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
2080 // FIXME: Cache the number on the Attr object if non-dependent?
2081 // FIXME: Perform checking of type validity
2082 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
2086 /// handleModeAttr - This attribute modifies the width of a decl with primitive
2089 /// Despite what would be logical, the mode attribute is a decl attribute, not a
2090 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
2091 /// HImode, not an intermediate pointer.
2092 static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2093 // This attribute isn't documented, but glibc uses it. It changes
2094 // the width of an int or unsigned int to the specified size.
2096 // Check that there aren't any arguments
2097 if (!checkAttributeNumArgs(S, Attr, 0))
2101 IdentifierInfo *Name = Attr.getParameterName();
2103 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2107 llvm::StringRef Str = Attr.getParameterName()->getName();
2109 // Normalize the attribute name, __foo__ becomes foo.
2110 if (Str.startswith("__") && Str.endswith("__"))
2111 Str = Str.substr(2, Str.size() - 4);
2113 unsigned DestWidth = 0;
2114 bool IntegerMode = true;
2115 bool ComplexMode = false;
2116 switch (Str.size()) {
2119 case 'Q': DestWidth = 8; break;
2120 case 'H': DestWidth = 16; break;
2121 case 'S': DestWidth = 32; break;
2122 case 'D': DestWidth = 64; break;
2123 case 'X': DestWidth = 96; break;
2124 case 'T': DestWidth = 128; break;
2126 if (Str[1] == 'F') {
2127 IntegerMode = false;
2128 } else if (Str[1] == 'C') {
2129 IntegerMode = false;
2131 } else if (Str[1] != 'I') {
2136 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2137 // pointer on PIC16 and other embedded platforms.
2139 DestWidth = S.Context.Target.getPointerWidth(0);
2140 else if (Str == "byte")
2141 DestWidth = S.Context.Target.getCharWidth();
2144 if (Str == "pointer")
2145 DestWidth = S.Context.Target.getPointerWidth(0);
2150 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
2151 OldTy = TD->getUnderlyingType();
2152 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
2153 OldTy = VD->getType();
2155 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2156 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2160 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
2161 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
2162 else if (IntegerMode) {
2163 if (!OldTy->isIntegralOrEnumerationType())
2164 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2165 } else if (ComplexMode) {
2166 if (!OldTy->isComplexType())
2167 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2169 if (!OldTy->isFloatingType())
2170 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2173 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
2174 // and friends, at least with glibc.
2175 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
2176 // width on unusual platforms.
2177 // FIXME: Make sure floating-point mappings are accurate
2178 // FIXME: Support XF and TF types
2180 switch (DestWidth) {
2182 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2185 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2189 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2192 if (OldTy->isSignedIntegerType())
2193 NewTy = S.Context.SignedCharTy;
2195 NewTy = S.Context.UnsignedCharTy;
2199 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2202 if (OldTy->isSignedIntegerType())
2203 NewTy = S.Context.ShortTy;
2205 NewTy = S.Context.UnsignedShortTy;
2209 NewTy = S.Context.FloatTy;
2210 else if (OldTy->isSignedIntegerType())
2211 NewTy = S.Context.IntTy;
2213 NewTy = S.Context.UnsignedIntTy;
2217 NewTy = S.Context.DoubleTy;
2218 else if (OldTy->isSignedIntegerType())
2219 if (S.Context.Target.getLongWidth() == 64)
2220 NewTy = S.Context.LongTy;
2222 NewTy = S.Context.LongLongTy;
2224 if (S.Context.Target.getLongWidth() == 64)
2225 NewTy = S.Context.UnsignedLongTy;
2227 NewTy = S.Context.UnsignedLongLongTy;
2230 NewTy = S.Context.LongDoubleTy;
2234 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2237 if (OldTy->isSignedIntegerType())
2238 NewTy = S.Context.Int128Ty;
2240 NewTy = S.Context.UnsignedInt128Ty;
2245 NewTy = S.Context.getComplexType(NewTy);
2248 // Install the new type.
2249 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2250 // FIXME: preserve existing source info.
2251 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy));
2253 cast<ValueDecl>(D)->setType(NewTy);
2256 static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2257 // check the attribute arguments.
2258 if (!checkAttributeNumArgs(S, Attr, 0))
2261 if (!isFunctionOrMethod(D)) {
2262 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2263 << Attr.getName() << ExpectedFunction;
2267 D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2270 static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2271 // check the attribute arguments.
2272 if (!checkAttributeNumArgs(S, Attr, 0))
2276 if (!isa<FunctionDecl>(D)) {
2277 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2278 << Attr.getName() << ExpectedFunction;
2282 D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
2285 static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
2286 const AttributeList &Attr) {
2287 // check the attribute arguments.
2288 if (!checkAttributeNumArgs(S, Attr, 0))
2292 if (!isa<FunctionDecl>(D)) {
2293 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2294 << Attr.getName() << ExpectedFunction;
2298 D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2302 static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2303 if (S.LangOpts.CUDA) {
2304 // check the attribute arguments.
2305 if (Attr.hasParameterOrArguments()) {
2306 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2310 if (!isa<VarDecl>(D)) {
2311 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2312 << Attr.getName() << ExpectedVariable;
2316 D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2318 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2322 static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2323 if (S.LangOpts.CUDA) {
2324 // check the attribute arguments.
2325 if (Attr.getNumArgs() != 0) {
2326 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2330 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2331 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2332 << Attr.getName() << ExpectedVariableOrFunction;
2336 D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2338 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2342 static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2343 if (S.LangOpts.CUDA) {
2344 // check the attribute arguments.
2345 if (!checkAttributeNumArgs(S, Attr, 0))
2348 if (!isa<FunctionDecl>(D)) {
2349 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2350 << Attr.getName() << ExpectedFunction;
2354 FunctionDecl *FD = cast<FunctionDecl>(D);
2355 if (!FD->getResultType()->isVoidType()) {
2356 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
2357 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) {
2358 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2360 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
2363 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2369 D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2371 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2375 static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2376 if (S.LangOpts.CUDA) {
2377 // check the attribute arguments.
2378 if (!checkAttributeNumArgs(S, Attr, 0))
2382 if (!isa<FunctionDecl>(D)) {
2383 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2384 << Attr.getName() << ExpectedFunction;
2388 D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2390 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2394 static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2395 if (S.LangOpts.CUDA) {
2396 // check the attribute arguments.
2397 if (!checkAttributeNumArgs(S, Attr, 0))
2401 if (!isa<VarDecl>(D)) {
2402 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2403 << Attr.getName() << ExpectedVariable;
2407 D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2409 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2413 static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2414 // check the attribute arguments.
2415 if (!checkAttributeNumArgs(S, Attr, 0))
2418 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2420 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2421 << Attr.getName() << ExpectedFunction;
2425 if (!Fn->isInlineSpecified()) {
2426 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2430 D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
2433 static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2434 if (hasDeclarator(D)) return;
2436 // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2437 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2439 if (S.CheckCallingConvAttr(Attr, CC))
2442 if (!isa<ObjCMethodDecl>(D)) {
2443 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2444 << Attr.getName() << ExpectedFunctionOrMethod;
2448 switch (Attr.getKind()) {
2449 case AttributeList::AT_fastcall:
2450 D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2452 case AttributeList::AT_stdcall:
2453 D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2455 case AttributeList::AT_thiscall:
2456 D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
2458 case AttributeList::AT_cdecl:
2459 D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2461 case AttributeList::AT_pascal:
2462 D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
2464 case AttributeList::AT_pcs: {
2465 Expr *Arg = Attr.getArg(0);
2466 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2467 if (Str == 0 || Str->isWide()) {
2468 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2474 llvm::StringRef StrRef = Str->getString();
2475 PcsAttr::PCSType PCS;
2476 if (StrRef == "aapcs")
2477 PCS = PcsAttr::AAPCS;
2478 else if (StrRef == "aapcs-vfp")
2479 PCS = PcsAttr::AAPCS_VFP;
2481 S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
2486 D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2489 llvm_unreachable("unexpected attribute kind");
2494 static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
2495 assert(!Attr.isInvalid());
2496 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context));
2499 bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2500 if (attr.isInvalid())
2503 if ((attr.getNumArgs() != 0 &&
2504 !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) ||
2505 attr.getParameterName()) {
2506 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2511 // TODO: diagnose uses of these conventions on the wrong target. Or, better
2512 // move to TargetAttributesSema one day.
2513 switch (attr.getKind()) {
2514 case AttributeList::AT_cdecl: CC = CC_C; break;
2515 case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
2516 case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
2517 case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
2518 case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
2519 case AttributeList::AT_pcs: {
2520 Expr *Arg = attr.getArg(0);
2521 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2522 if (Str == 0 || Str->isWide()) {
2523 Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string)
2529 llvm::StringRef StrRef = Str->getString();
2530 if (StrRef == "aapcs") {
2533 } else if (StrRef == "aapcs-vfp") {
2539 default: llvm_unreachable("unexpected attribute kind"); return true;
2545 static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2546 if (hasDeclarator(D)) return;
2549 if (S.CheckRegparmAttr(Attr, numParams))
2552 if (!isa<ObjCMethodDecl>(D)) {
2553 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2554 << Attr.getName() << ExpectedFunctionOrMethod;
2558 D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2561 /// Checks a regparm attribute, returning true if it is ill-formed and
2562 /// otherwise setting numParams to the appropriate value.
2563 bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
2564 if (Attr.isInvalid())
2567 if (Attr.getNumArgs() != 1) {
2568 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2573 Expr *NumParamsExpr = Attr.getArg(0);
2574 llvm::APSInt NumParams(32);
2575 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
2576 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
2577 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
2578 << "regparm" << NumParamsExpr->getSourceRange();
2583 if (Context.Target.getRegParmMax() == 0) {
2584 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
2585 << NumParamsExpr->getSourceRange();
2590 numParams = NumParams.getZExtValue();
2591 if (numParams > Context.Target.getRegParmMax()) {
2592 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
2593 << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
2601 static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
2602 if (S.LangOpts.CUDA) {
2603 // check the attribute arguments.
2604 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
2605 // FIXME: 0 is not okay.
2606 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
2610 if (!isFunctionOrMethod(D)) {
2611 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2612 << Attr.getName() << ExpectedFunctionOrMethod;
2616 Expr *MaxThreadsExpr = Attr.getArg(0);
2617 llvm::APSInt MaxThreads(32);
2618 if (MaxThreadsExpr->isTypeDependent() ||
2619 MaxThreadsExpr->isValueDependent() ||
2620 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
2621 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
2622 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange();
2626 llvm::APSInt MinBlocks(32);
2627 if (Attr.getNumArgs() > 1) {
2628 Expr *MinBlocksExpr = Attr.getArg(1);
2629 if (MinBlocksExpr->isTypeDependent() ||
2630 MinBlocksExpr->isValueDependent() ||
2631 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
2632 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
2633 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange();
2638 D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
2639 MaxThreads.getZExtValue(),
2640 MinBlocks.getZExtValue()));
2642 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
2646 //===----------------------------------------------------------------------===//
2647 // Checker-specific attribute handlers.
2648 //===----------------------------------------------------------------------===//
2650 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2651 return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2653 static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2654 return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2657 static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2658 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
2660 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
2661 << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
2666 if (Attr.getKind() == AttributeList::AT_ns_consumed) {
2667 typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2670 typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2675 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
2676 << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
2681 param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
2683 param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
2686 static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
2687 const AttributeList &Attr) {
2688 if (!isa<ObjCMethodDecl>(D)) {
2689 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
2690 << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod;
2694 D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
2697 static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
2698 const AttributeList &Attr) {
2700 QualType returnType;
2702 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2703 returnType = MD->getResultType();
2704 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
2705 returnType = PD->getType();
2706 else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) &&
2707 (Attr.getKind() == AttributeList::AT_ns_returns_retained))
2708 return; // ignore: was handled as a type attribute
2709 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
2710 returnType = FD->getResultType();
2712 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
2713 << SourceRange(Attr.getLoc()) << Attr.getName()
2714 << ExpectedFunctionOrMethod;
2720 switch (Attr.getKind()) {
2721 default: llvm_unreachable("invalid ownership attribute"); return;
2722 case AttributeList::AT_ns_returns_autoreleased:
2723 case AttributeList::AT_ns_returns_retained:
2724 case AttributeList::AT_ns_returns_not_retained:
2725 typeOK = isValidSubjectOfNSAttribute(S, returnType);
2729 case AttributeList::AT_cf_returns_retained:
2730 case AttributeList::AT_cf_returns_not_retained:
2731 typeOK = isValidSubjectOfCFAttribute(S, returnType);
2737 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2738 << SourceRange(Attr.getLoc())
2739 << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
2743 switch (Attr.getKind()) {
2745 assert(0 && "invalid ownership attribute");
2747 case AttributeList::AT_ns_returns_autoreleased:
2748 D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
2751 case AttributeList::AT_cf_returns_not_retained:
2752 D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
2755 case AttributeList::AT_ns_returns_not_retained:
2756 D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
2759 case AttributeList::AT_cf_returns_retained:
2760 D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
2763 case AttributeList::AT_ns_returns_retained:
2764 D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
2770 static void handleObjCOwnershipAttr(Sema &S, Decl *D,
2771 const AttributeList &Attr) {
2772 if (hasDeclarator(D)) return;
2774 SourceLocation L = Attr.getLoc();
2775 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
2776 << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2779 static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
2780 const AttributeList &Attr) {
2781 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
2782 SourceLocation L = Attr.getLoc();
2783 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
2784 << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2788 ValueDecl *vd = cast<ValueDecl>(D);
2789 QualType type = vd->getType();
2791 if (!type->isDependentType() &&
2792 !type->isObjCLifetimeType()) {
2793 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
2798 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
2800 // If we have no lifetime yet, check the lifetime we're presumably
2802 if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
2803 lifetime = type->getObjCARCImplicitLifetime();
2806 case Qualifiers::OCL_None:
2807 assert(type->isDependentType() &&
2808 "didn't infer lifetime for non-dependent type?");
2811 case Qualifiers::OCL_Weak: // meaningful
2812 case Qualifiers::OCL_Strong: // meaningful
2815 case Qualifiers::OCL_ExplicitNone:
2816 case Qualifiers::OCL_Autoreleasing:
2817 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
2818 << (lifetime == Qualifiers::OCL_Autoreleasing);
2822 D->addAttr(::new (S.Context)
2823 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
2826 static bool isKnownDeclSpecAttr(const AttributeList &Attr) {
2827 return Attr.getKind() == AttributeList::AT_dllimport ||
2828 Attr.getKind() == AttributeList::AT_dllexport ||
2829 Attr.getKind() == AttributeList::AT_uuid;
2832 //===----------------------------------------------------------------------===//
2833 // Microsoft specific attribute handlers.
2834 //===----------------------------------------------------------------------===//
2836 static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2837 if (S.LangOpts.Microsoft || S.LangOpts.Borland) {
2838 // check the attribute arguments.
2839 if (!checkAttributeNumArgs(S, Attr, 1))
2842 Expr *Arg = Attr.getArg(0);
2843 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
2844 if (Str == 0 || Str->isWide()) {
2845 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
2850 llvm::StringRef StrRef = Str->getString();
2852 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2853 StrRef.back() == '}';
2855 // Validate GUID length.
2856 if (IsCurly && StrRef.size() != 38) {
2857 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2860 if (!IsCurly && StrRef.size() != 36) {
2861 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2865 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
2866 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
2867 llvm::StringRef::iterator I = StrRef.begin();
2868 if (IsCurly) // Skip the optional '{'
2871 for (int i = 0; i < 36; ++i) {
2872 if (i == 8 || i == 13 || i == 18 || i == 23) {
2874 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2877 } else if (!isxdigit(*I)) {
2878 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2884 D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
2887 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2890 //===----------------------------------------------------------------------===//
2891 // Top Level Sema Entry Points
2892 //===----------------------------------------------------------------------===//
2894 static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
2895 const AttributeList &Attr) {
2896 switch (Attr.getKind()) {
2897 case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break;
2898 case AttributeList::AT_host: handleHostAttr (S, D, Attr); break;
2899 case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break;
2905 static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
2906 const AttributeList &Attr) {
2907 switch (Attr.getKind()) {
2908 case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break;
2909 case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
2910 case AttributeList::AT_IBOutletCollection:
2911 handleIBOutletCollection(S, D, Attr); break;
2912 case AttributeList::AT_address_space:
2913 case AttributeList::AT_opencl_image_access:
2914 case AttributeList::AT_objc_gc:
2915 case AttributeList::AT_vector_size:
2916 case AttributeList::AT_neon_vector_type:
2917 case AttributeList::AT_neon_polyvector_type:
2918 // Ignore these, these are type attributes, handled by
2919 // ProcessTypeAttributes.
2921 case AttributeList::AT_device:
2922 case AttributeList::AT_host:
2923 case AttributeList::AT_overloadable:
2924 // Ignore, this is a non-inheritable attribute, handled
2925 // by ProcessNonInheritableDeclAttr.
2927 case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break;
2928 case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break;
2929 case AttributeList::AT_always_inline:
2930 handleAlwaysInlineAttr (S, D, Attr); break;
2931 case AttributeList::AT_analyzer_noreturn:
2932 handleAnalyzerNoReturnAttr (S, D, Attr); break;
2933 case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break;
2934 case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break;
2935 case AttributeList::AT_carries_dependency:
2936 handleDependencyAttr (S, D, Attr); break;
2937 case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break;
2938 case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break;
2939 case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break;
2940 case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break;
2941 case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break;
2942 case AttributeList::AT_ext_vector_type:
2943 handleExtVectorTypeAttr(S, scope, D, Attr);
2945 case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break;
2946 case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break;
2947 case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break;
2948 case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break;
2949 case AttributeList::AT_launch_bounds:
2950 handleLaunchBoundsAttr(S, D, Attr);
2952 case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break;
2953 case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break;
2954 case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break;
2955 case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break;
2956 case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break;
2957 case AttributeList::AT_ownership_returns:
2958 case AttributeList::AT_ownership_takes:
2959 case AttributeList::AT_ownership_holds:
2960 handleOwnershipAttr (S, D, Attr); break;
2961 case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break;
2962 case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break;
2963 case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break;
2964 case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break;
2965 case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break;
2967 case AttributeList::AT_objc_ownership:
2968 handleObjCOwnershipAttr(S, D, Attr); break;
2969 case AttributeList::AT_objc_precise_lifetime:
2970 handleObjCPreciseLifetimeAttr(S, D, Attr); break;
2972 // Checker-specific.
2973 case AttributeList::AT_cf_consumed:
2974 case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break;
2975 case AttributeList::AT_ns_consumes_self:
2976 handleNSConsumesSelfAttr(S, D, Attr); break;
2978 case AttributeList::AT_ns_returns_autoreleased:
2979 case AttributeList::AT_ns_returns_not_retained:
2980 case AttributeList::AT_cf_returns_not_retained:
2981 case AttributeList::AT_ns_returns_retained:
2982 case AttributeList::AT_cf_returns_retained:
2983 handleNSReturnsRetainedAttr(S, D, Attr); break;
2985 case AttributeList::AT_reqd_wg_size:
2986 handleReqdWorkGroupSize(S, D, Attr); break;
2988 case AttributeList::AT_init_priority:
2989 handleInitPriorityAttr(S, D, Attr); break;
2991 case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break;
2992 case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break;
2993 case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break;
2994 case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break;
2995 case AttributeList::AT_arc_weakref_unavailable:
2996 handleArcWeakrefUnavailableAttr (S, D, Attr);
2998 case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break;
2999 case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break;
3000 case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break;
3001 case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr);
3003 case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break;
3004 case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break;
3005 case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break;
3006 case AttributeList::AT_transparent_union:
3007 handleTransparentUnionAttr(S, D, Attr);
3009 case AttributeList::AT_objc_exception:
3010 handleObjCExceptionAttr(S, D, Attr);
3012 case AttributeList::AT_objc_method_family:
3013 handleObjCMethodFamilyAttr(S, D, Attr);
3015 case AttributeList::AT_nsobject: handleObjCNSObject (S, D, Attr); break;
3016 case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break;
3017 case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break;
3018 case AttributeList::AT_const: handleConstAttr (S, D, Attr); break;
3019 case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break;
3020 case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break;
3021 case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break;
3022 case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break;
3023 case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break;
3024 case AttributeList::IgnoredAttribute:
3027 case AttributeList::AT_no_instrument_function: // Interacts with -pg.
3028 handleNoInstrumentFunctionAttr(S, D, Attr);
3030 case AttributeList::AT_stdcall:
3031 case AttributeList::AT_cdecl:
3032 case AttributeList::AT_fastcall:
3033 case AttributeList::AT_thiscall:
3034 case AttributeList::AT_pascal:
3035 case AttributeList::AT_pcs:
3036 handleCallConvAttr(S, D, Attr);
3038 case AttributeList::AT_opencl_kernel_function:
3039 handleOpenCLKernelAttr(S, D, Attr);
3041 case AttributeList::AT_uuid:
3042 handleUuidAttr(S, D, Attr);
3045 // Ask target about the attribute.
3046 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
3047 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
3048 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored)
3054 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
3055 /// the attribute applies to decls. If the attribute is a type attribute, just
3056 /// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
3057 /// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
3058 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
3059 const AttributeList &Attr,
3060 bool NonInheritable, bool Inheritable) {
3061 if (Attr.isInvalid())
3064 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
3065 // FIXME: Try to deal with other __declspec attributes!
3069 ProcessNonInheritableDeclAttr(S, scope, D, Attr);
3072 ProcessInheritableDeclAttr(S, scope, D, Attr);
3075 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3076 /// attribute list to the specified decl, ignoring any type attributes.
3077 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
3078 const AttributeList *AttrList,
3079 bool NonInheritable, bool Inheritable) {
3080 for (const AttributeList* l = AttrList; l; l = l->getNext()) {
3081 ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable);
3085 // static int a9 __attribute__((weakref));
3086 // but that looks really pointless. We reject it.
3087 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
3088 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
3089 dyn_cast<NamedDecl>(D)->getNameAsString();
3094 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
3095 /// #pragma weak needs a non-definition decl and source may not have one
3096 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
3097 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
3098 NamedDecl *NewD = 0;
3099 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
3100 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
3101 FD->getInnerLocStart(),
3102 FD->getLocation(), DeclarationName(II),
3103 FD->getType(), FD->getTypeSourceInfo());
3104 if (FD->getQualifier()) {
3105 FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
3106 NewFD->setQualifierInfo(FD->getQualifierLoc());
3108 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
3109 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
3110 VD->getInnerLocStart(), VD->getLocation(), II,
3111 VD->getType(), VD->getTypeSourceInfo(),
3112 VD->getStorageClass(),
3113 VD->getStorageClassAsWritten());
3114 if (VD->getQualifier()) {
3115 VarDecl *NewVD = cast<VarDecl>(NewD);
3116 NewVD->setQualifierInfo(VD->getQualifierLoc());
3122 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3123 /// applied to it, possibly with an alias.
3124 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3125 if (W.getUsed()) return; // only do this once
3127 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
3128 IdentifierInfo *NDId = ND->getIdentifier();
3129 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
3130 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
3132 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3133 WeakTopLevelDecl.push_back(NewD);
3134 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
3135 // to insert Decl at TU scope, sorry.
3136 DeclContext *SavedContext = CurContext;
3137 CurContext = Context.getTranslationUnitDecl();
3138 PushOnScopeChains(NewD, S);
3139 CurContext = SavedContext;
3140 } else { // just add weak to existing
3141 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
3145 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
3146 /// it, apply them to D. This is a bit tricky because PD can have attributes
3147 /// specified in many different places, and we need to find and apply them all.
3148 void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
3149 bool NonInheritable, bool Inheritable) {
3150 // It's valid to "forward-declare" #pragma weak, in which case we
3152 if (Inheritable && !WeakUndeclaredIdentifiers.empty()) {
3153 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
3154 if (IdentifierInfo *Id = ND->getIdentifier()) {
3155 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
3156 = WeakUndeclaredIdentifiers.find(Id);
3157 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) {
3158 WeakInfo W = I->second;
3159 DeclApplyPragmaWeak(S, ND, W);
3160 WeakUndeclaredIdentifiers[Id] = W;
3166 // Apply decl attributes from the DeclSpec if present.
3167 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
3168 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3170 // Walk the declarator structure, applying decl attributes that were in a type
3171 // position to the decl itself. This handles cases like:
3172 // int *__attr__(x)** D;
3173 // when X is a decl attribute.
3174 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
3175 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
3176 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3178 // Finally, apply any attributes on the decl itself.
3179 if (const AttributeList *Attrs = PD.getAttributes())
3180 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3183 /// Is the given declaration allowed to use a forbidden type?
3184 static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
3185 // Private ivars are always okay. Unfortunately, people don't
3186 // always properly make their ivars private, even in system headers.
3187 // Plus we need to make fields okay, too.
3188 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl))
3191 // Require it to be declared in a system header.
3192 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3195 /// Handle a delayed forbidden-type diagnostic.
3196 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3198 if (decl && isForbiddenTypeAllowed(S, decl)) {
3199 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
3200 "this system declaration uses an unsupported type"));
3204 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3205 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3206 diag.Triggered = true;
3209 // This duplicates a vector push_back but hides the need to know the
3210 // size of the type.
3211 void Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3212 assert(StackSize <= StackCapacity);
3214 // Grow the stack if necessary.
3215 if (StackSize == StackCapacity) {
3216 unsigned newCapacity = 2 * StackCapacity + 2;
3217 char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)];
3218 const char *oldBuffer = (const char*) Stack;
3221 memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3224 Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3225 StackCapacity = newCapacity;
3228 assert(StackSize < StackCapacity);
3229 new (&Stack[StackSize++]) DelayedDiagnostic(diag);
3232 void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3234 DelayedDiagnostics &DD = S.DelayedDiagnostics;
3236 // Check the invariants.
3237 assert(DD.StackSize >= state.SavedStackSize);
3238 assert(state.SavedStackSize >= DD.ActiveStackBase);
3239 assert(DD.ParsingDepth > 0);
3241 // Drop the parsing depth.
3244 // If there are no active diagnostics, we're done.
3245 if (DD.StackSize == DD.ActiveStackBase)
3248 // We only want to actually emit delayed diagnostics when we
3249 // successfully parsed a decl.
3250 if (decl && !decl->isInvalidDecl()) {
3251 // We emit all the active diagnostics, not just those starting
3252 // from the saved state. The idea is this: we get one push for a
3253 // decl spec and another for each declarator; in a decl group like:
3254 // deprecated_typedef foo, *bar, baz();
3255 // only the declarator pops will be passed decls. This is correct;
3256 // we really do need to consider delayed diagnostics from the decl spec
3257 // for each of the different declarations.
3258 for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) {
3259 DelayedDiagnostic &diag = DD.Stack[i];
3263 switch (diag.Kind) {
3264 case DelayedDiagnostic::Deprecation:
3265 S.HandleDelayedDeprecationCheck(diag, decl);
3268 case DelayedDiagnostic::Access:
3269 S.HandleDelayedAccessCheck(diag, decl);
3272 case DelayedDiagnostic::ForbiddenType:
3273 handleDelayedForbiddenType(S, diag, decl);
3279 // Destroy all the delayed diagnostics we're about to pop off.
3280 for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i)
3281 DD.Stack[i].Destroy();
3283 DD.StackSize = state.SavedStackSize;
3286 static bool isDeclDeprecated(Decl *D) {
3288 if (D->isDeprecated())
3290 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
3294 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
3296 if (isDeclDeprecated(Ctx))
3299 DD.Triggered = true;
3300 if (!DD.getDeprecationMessage().empty())
3301 Diag(DD.Loc, diag::warn_deprecated_message)
3302 << DD.getDeprecationDecl()->getDeclName()
3303 << DD.getDeprecationMessage();
3305 Diag(DD.Loc, diag::warn_deprecated)
3306 << DD.getDeprecationDecl()->getDeclName();
3309 void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
3311 const ObjCInterfaceDecl *UnknownObjCClass) {
3312 // Delay if we're currently parsing a declaration.
3313 if (DelayedDiagnostics.shouldDelayDiagnostics()) {
3314 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
3318 // Otherwise, don't warn if our current context is deprecated.
3319 if (isDeclDeprecated(cast<Decl>(CurContext)))
3321 if (!Message.empty())
3322 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3325 if (!UnknownObjCClass)
3326 Diag(Loc, diag::warn_deprecated) << D->getDeclName();
3328 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
3329 Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);