1 //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements decl-related attribute processing.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Sema/SemaInternal.h"
15 #include "TargetAttributesSema.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Sema/DeclSpec.h"
22 #include "clang/Sema/DelayedDiagnostic.h"
23 #include "llvm/ADT/StringExtras.h"
24 using namespace clang
;
27 //===----------------------------------------------------------------------===//
29 //===----------------------------------------------------------------------===//
31 static const FunctionType
*getFunctionType(const Decl
*d
,
32 bool blocksToo
= true) {
34 if (const ValueDecl
*decl
= dyn_cast
<ValueDecl
>(d
))
36 else if (const FieldDecl
*decl
= dyn_cast
<FieldDecl
>(d
))
38 else if (const TypedefDecl
* decl
= dyn_cast
<TypedefDecl
>(d
))
39 Ty
= decl
->getUnderlyingType();
43 if (Ty
->isFunctionPointerType())
44 Ty
= Ty
->getAs
<PointerType
>()->getPointeeType();
45 else if (blocksToo
&& Ty
->isBlockPointerType())
46 Ty
= Ty
->getAs
<BlockPointerType
>()->getPointeeType();
48 return Ty
->getAs
<FunctionType
>();
51 // FIXME: We should provide an abstraction around a method or function
52 // to provide the following bits of information.
54 /// isFunction - Return true if the given decl has function
55 /// type (function or function-typed variable).
56 static bool isFunction(const Decl
*d
) {
57 return getFunctionType(d
, false) != NULL
;
60 /// isFunctionOrMethod - Return true if the given decl has function
61 /// type (function or function-typed variable) or an Objective-C
63 static bool isFunctionOrMethod(const Decl
*d
) {
64 return isFunction(d
)|| isa
<ObjCMethodDecl
>(d
);
67 /// isFunctionOrMethodOrBlock - Return true if the given decl has function
68 /// type (function or function-typed variable) or an Objective-C
69 /// method or a block.
70 static bool isFunctionOrMethodOrBlock(const Decl
*d
) {
71 if (isFunctionOrMethod(d
))
73 // check for block is more involved.
74 if (const VarDecl
*V
= dyn_cast
<VarDecl
>(d
)) {
75 QualType Ty
= V
->getType();
76 return Ty
->isBlockPointerType();
78 return isa
<BlockDecl
>(d
);
81 /// hasFunctionProto - Return true if the given decl has a argument
82 /// information. This decl should have already passed
83 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
84 static bool hasFunctionProto(const Decl
*d
) {
85 if (const FunctionType
*FnTy
= getFunctionType(d
))
86 return isa
<FunctionProtoType
>(FnTy
);
88 assert(isa
<ObjCMethodDecl
>(d
) || isa
<BlockDecl
>(d
));
93 /// getFunctionOrMethodNumArgs - Return number of function or method
94 /// arguments. It is an error to call this on a K&R function (use
95 /// hasFunctionProto first).
96 static unsigned getFunctionOrMethodNumArgs(const Decl
*d
) {
97 if (const FunctionType
*FnTy
= getFunctionType(d
))
98 return cast
<FunctionProtoType
>(FnTy
)->getNumArgs();
99 if (const BlockDecl
*BD
= dyn_cast
<BlockDecl
>(d
))
100 return BD
->getNumParams();
101 return cast
<ObjCMethodDecl
>(d
)->param_size();
104 static QualType
getFunctionOrMethodArgType(const Decl
*d
, unsigned Idx
) {
105 if (const FunctionType
*FnTy
= getFunctionType(d
))
106 return cast
<FunctionProtoType
>(FnTy
)->getArgType(Idx
);
107 if (const BlockDecl
*BD
= dyn_cast
<BlockDecl
>(d
))
108 return BD
->getParamDecl(Idx
)->getType();
110 return cast
<ObjCMethodDecl
>(d
)->param_begin()[Idx
]->getType();
113 static QualType
getFunctionOrMethodResultType(const Decl
*d
) {
114 if (const FunctionType
*FnTy
= getFunctionType(d
))
115 return cast
<FunctionProtoType
>(FnTy
)->getResultType();
116 return cast
<ObjCMethodDecl
>(d
)->getResultType();
119 static bool isFunctionOrMethodVariadic(const Decl
*d
) {
120 if (const FunctionType
*FnTy
= getFunctionType(d
)) {
121 const FunctionProtoType
*proto
= cast
<FunctionProtoType
>(FnTy
);
122 return proto
->isVariadic();
123 } else if (const BlockDecl
*BD
= dyn_cast
<BlockDecl
>(d
))
124 return BD
->isVariadic();
126 return cast
<ObjCMethodDecl
>(d
)->isVariadic();
130 static inline bool isNSStringType(QualType T
, ASTContext
&Ctx
) {
131 const ObjCObjectPointerType
*PT
= T
->getAs
<ObjCObjectPointerType
>();
135 ObjCInterfaceDecl
*Cls
= PT
->getObjectType()->getInterface();
139 IdentifierInfo
* ClsName
= Cls
->getIdentifier();
141 // FIXME: Should we walk the chain of classes?
142 return ClsName
== &Ctx
.Idents
.get("NSString") ||
143 ClsName
== &Ctx
.Idents
.get("NSMutableString");
146 static inline bool isCFStringType(QualType T
, ASTContext
&Ctx
) {
147 const PointerType
*PT
= T
->getAs
<PointerType
>();
151 const RecordType
*RT
= PT
->getPointeeType()->getAs
<RecordType
>();
155 const RecordDecl
*RD
= RT
->getDecl();
156 if (RD
->getTagKind() != TTK_Struct
)
159 return RD
->getIdentifier() == &Ctx
.Idents
.get("__CFString");
162 //===----------------------------------------------------------------------===//
163 // Attribute Implementations
164 //===----------------------------------------------------------------------===//
166 // FIXME: All this manual attribute parsing code is gross. At the
167 // least add some helper functions to check most argument patterns (#
168 // and types of args).
170 static void HandleExtVectorTypeAttr(Scope
*scope
, Decl
*d
,
171 const AttributeList
&Attr
, Sema
&S
) {
172 TypedefDecl
*tDecl
= dyn_cast
<TypedefDecl
>(d
);
174 S
.Diag(Attr
.getLoc(), diag::err_typecheck_ext_vector_not_typedef
);
178 QualType curType
= tDecl
->getUnderlyingType();
182 // Special case where the argument is a template id.
183 if (Attr
.getParameterName()) {
186 id
.setIdentifier(Attr
.getParameterName(), Attr
.getLoc());
187 sizeExpr
= S
.ActOnIdExpression(scope
, SS
, id
, false, false).takeAs
<Expr
>();
189 // check the attribute arguments.
190 if (Attr
.getNumArgs() != 1) {
191 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
194 sizeExpr
= static_cast<Expr
*>(Attr
.getArg(0));
197 // Instantiate/Install the vector type, and let Sema build the type for us.
198 // This will run the reguired checks.
199 QualType T
= S
.BuildExtVectorType(curType
, sizeExpr
, Attr
.getLoc());
201 // FIXME: preserve the old source info.
202 tDecl
->setTypeSourceInfo(S
.Context
.getTrivialTypeSourceInfo(T
));
204 // Remember this typedef decl, we will need it later for diagnostics.
205 S
.ExtVectorDecls
.push_back(tDecl
);
209 static void HandlePackedAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
210 // check the attribute arguments.
211 if (Attr
.getNumArgs() > 0) {
212 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
216 if (TagDecl
*TD
= dyn_cast
<TagDecl
>(d
))
217 TD
->addAttr(::new (S
.Context
) PackedAttr(Attr
.getLoc(), S
.Context
));
218 else if (FieldDecl
*FD
= dyn_cast
<FieldDecl
>(d
)) {
219 // If the alignment is less than or equal to 8 bits, the packed attribute
221 if (!FD
->getType()->isIncompleteType() &&
222 S
.Context
.getTypeAlign(FD
->getType()) <= 8)
223 S
.Diag(Attr
.getLoc(), diag::warn_attribute_ignored_for_field_of_type
)
224 << Attr
.getName() << FD
->getType();
226 FD
->addAttr(::new (S
.Context
) PackedAttr(Attr
.getLoc(), S
.Context
));
228 S
.Diag(Attr
.getLoc(), diag::warn_attribute_ignored
) << Attr
.getName();
231 static void HandleIBAction(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
232 // check the attribute arguments.
233 if (Attr
.getNumArgs() > 0) {
234 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
238 // The IBAction attributes only apply to instance methods.
239 if (ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(d
))
240 if (MD
->isInstanceMethod()) {
241 d
->addAttr(::new (S
.Context
) IBActionAttr(Attr
.getLoc(), S
.Context
));
245 S
.Diag(Attr
.getLoc(), diag::err_attribute_ibaction
) << Attr
.getName();
248 static void HandleIBOutlet(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
249 // check the attribute arguments.
250 if (Attr
.getNumArgs() > 0) {
251 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
255 // The IBOutlet attributes only apply to instance variables of
256 // Objective-C classes.
257 if (isa
<ObjCIvarDecl
>(d
) || isa
<ObjCPropertyDecl
>(d
)) {
258 d
->addAttr(::new (S
.Context
) IBOutletAttr(Attr
.getLoc(), S
.Context
));
262 S
.Diag(Attr
.getLoc(), diag::err_attribute_iboutlet
) << Attr
.getName();
265 static void HandleIBOutletCollection(Decl
*d
, const AttributeList
&Attr
,
268 // The iboutletcollection attribute can have zero or one arguments.
269 if (Attr
.getParameterName() && Attr
.getNumArgs() > 0) {
270 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
274 // The IBOutletCollection attributes only apply to instance variables of
275 // Objective-C classes.
276 if (!(isa
<ObjCIvarDecl
>(d
) || isa
<ObjCPropertyDecl
>(d
))) {
277 S
.Diag(Attr
.getLoc(), diag::err_attribute_iboutlet
) << Attr
.getName();
280 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(d
))
281 if (!VD
->getType()->getAs
<ObjCObjectPointerType
>()) {
282 S
.Diag(Attr
.getLoc(), diag::err_iboutletcollection_object_type
)
283 << VD
->getType() << 0;
286 if (const ObjCPropertyDecl
*PD
= dyn_cast
<ObjCPropertyDecl
>(d
))
287 if (!PD
->getType()->getAs
<ObjCObjectPointerType
>()) {
288 S
.Diag(Attr
.getLoc(), diag::err_iboutletcollection_object_type
)
289 << PD
->getType() << 1;
293 IdentifierInfo
*II
= Attr
.getParameterName();
295 II
= &S
.Context
.Idents
.get("id");
297 ParsedType TypeRep
= S
.getTypeName(*II
, Attr
.getLoc(),
298 S
.getScopeForContext(d
->getDeclContext()->getParent()));
300 S
.Diag(Attr
.getLoc(), diag::err_iboutletcollection_type
) << II
;
303 QualType QT
= TypeRep
.get();
304 // Diagnose use of non-object type in iboutletcollection attribute.
305 // FIXME. Gnu attribute extension ignores use of builtin types in
306 // attributes. So, __attribute__((iboutletcollection(char))) will be
307 // treated as __attribute__((iboutletcollection())).
308 if (!QT
->isObjCIdType() && !QT
->isObjCClassType() &&
309 !QT
->isObjCObjectType()) {
310 S
.Diag(Attr
.getLoc(), diag::err_iboutletcollection_type
) << II
;
313 d
->addAttr(::new (S
.Context
) IBOutletCollectionAttr(Attr
.getLoc(), S
.Context
,
317 static void HandleNonNullAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
318 // GCC ignores the nonnull attribute on K&R style function prototypes, so we
320 if (!isFunctionOrMethod(d
) || !hasFunctionProto(d
)) {
321 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
322 << Attr
.getName() << 0 /*function*/;
326 unsigned NumArgs
= getFunctionOrMethodNumArgs(d
);
328 // The nonnull attribute only applies to pointers.
329 llvm::SmallVector
<unsigned, 10> NonNullArgs
;
331 for (AttributeList::arg_iterator I
=Attr
.arg_begin(),
332 E
=Attr
.arg_end(); I
!=E
; ++I
) {
335 // The argument must be an integer constant expression.
336 Expr
*Ex
= static_cast<Expr
*>(*I
);
337 llvm::APSInt
ArgNum(32);
338 if (Ex
->isTypeDependent() || Ex
->isValueDependent() ||
339 !Ex
->isIntegerConstantExpr(ArgNum
, S
.Context
)) {
340 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_not_int
)
341 << "nonnull" << Ex
->getSourceRange();
345 unsigned x
= (unsigned) ArgNum
.getZExtValue();
347 if (x
< 1 || x
> NumArgs
) {
348 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
349 << "nonnull" << I
.getArgNum() << Ex
->getSourceRange();
355 // Is the function argument a pointer type?
356 QualType T
= getFunctionOrMethodArgType(d
, x
);
357 if (!T
->isAnyPointerType() && !T
->isBlockPointerType()) {
358 // FIXME: Should also highlight argument in decl.
359 S
.Diag(Attr
.getLoc(), diag::warn_nonnull_pointers_only
)
360 << "nonnull" << Ex
->getSourceRange();
364 NonNullArgs
.push_back(x
);
367 // If no arguments were specified to __attribute__((nonnull)) then all pointer
368 // arguments have a nonnull attribute.
369 if (NonNullArgs
.empty()) {
370 for (unsigned I
= 0, E
= getFunctionOrMethodNumArgs(d
); I
!= E
; ++I
) {
371 QualType T
= getFunctionOrMethodArgType(d
, I
);
372 if (T
->isAnyPointerType() || T
->isBlockPointerType())
373 NonNullArgs
.push_back(I
);
376 if (NonNullArgs
.empty()) {
377 S
.Diag(Attr
.getLoc(), diag::warn_attribute_nonnull_no_pointers
);
382 unsigned* start
= &NonNullArgs
[0];
383 unsigned size
= NonNullArgs
.size();
384 llvm::array_pod_sort(start
, start
+ size
);
385 d
->addAttr(::new (S
.Context
) NonNullAttr(Attr
.getLoc(), S
.Context
, start
,
389 static void HandleOwnershipAttr(Decl
*d
, const AttributeList
&AL
, Sema
&S
) {
390 // This attribute must be applied to a function declaration.
391 // The first argument to the attribute must be a string,
392 // the name of the resource, for example "malloc".
393 // The following arguments must be argument indexes, the arguments must be
394 // of integer type for Returns, otherwise of pointer type.
395 // The difference between Holds and Takes is that a pointer may still be used
396 // after being held. free() should be __attribute((ownership_takes)), whereas
397 // a list append function may well be __attribute((ownership_holds)).
399 if (!AL
.getParameterName()) {
400 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_n_not_string
)
401 << AL
.getName()->getName() << 1;
404 // Figure out our Kind, and check arguments while we're at it.
405 OwnershipAttr::OwnershipKind K
;
406 switch (AL
.getKind()) {
407 case AttributeList::AT_ownership_takes
:
408 K
= OwnershipAttr::Takes
;
409 if (AL
.getNumArgs() < 1) {
410 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 2;
414 case AttributeList::AT_ownership_holds
:
415 K
= OwnershipAttr::Holds
;
416 if (AL
.getNumArgs() < 1) {
417 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 2;
421 case AttributeList::AT_ownership_returns
:
422 K
= OwnershipAttr::Returns
;
423 if (AL
.getNumArgs() > 1) {
424 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
)
425 << AL
.getNumArgs() + 1;
430 // This should never happen given how we are called.
431 llvm_unreachable("Unknown ownership attribute");
434 if (!isFunction(d
) || !hasFunctionProto(d
)) {
435 S
.Diag(AL
.getLoc(), diag::warn_attribute_wrong_decl_type
) << AL
.getName()
440 unsigned NumArgs
= getFunctionOrMethodNumArgs(d
);
442 llvm::StringRef Module
= AL
.getParameterName()->getName();
444 // Normalize the argument, __foo__ becomes foo.
445 if (Module
.startswith("__") && Module
.endswith("__"))
446 Module
= Module
.substr(2, Module
.size() - 4);
448 llvm::SmallVector
<unsigned, 10> OwnershipArgs
;
450 for (AttributeList::arg_iterator I
= AL
.arg_begin(), E
= AL
.arg_end(); I
!= E
;
453 Expr
*IdxExpr
= static_cast<Expr
*>(*I
);
454 llvm::APSInt
ArgNum(32);
455 if (IdxExpr
->isTypeDependent() || IdxExpr
->isValueDependent()
456 || !IdxExpr
->isIntegerConstantExpr(ArgNum
, S
.Context
)) {
457 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_not_int
)
458 << AL
.getName()->getName() << IdxExpr
->getSourceRange();
462 unsigned x
= (unsigned) ArgNum
.getZExtValue();
464 if (x
> NumArgs
|| x
< 1) {
465 S
.Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
466 << AL
.getName()->getName() << x
<< IdxExpr
->getSourceRange();
471 case OwnershipAttr::Takes
:
472 case OwnershipAttr::Holds
: {
473 // Is the function argument a pointer type?
474 QualType T
= getFunctionOrMethodArgType(d
, x
);
475 if (!T
->isAnyPointerType() && !T
->isBlockPointerType()) {
476 // FIXME: Should also highlight argument in decl.
477 S
.Diag(AL
.getLoc(), diag::err_ownership_type
)
478 << ((K
==OwnershipAttr::Takes
)?"ownership_takes":"ownership_holds")
480 << IdxExpr
->getSourceRange();
485 case OwnershipAttr::Returns
: {
486 if (AL
.getNumArgs() > 1) {
487 // Is the function argument an integer type?
488 Expr
*IdxExpr
= static_cast<Expr
*>(AL
.getArg(0));
489 llvm::APSInt
ArgNum(32);
490 if (IdxExpr
->isTypeDependent() || IdxExpr
->isValueDependent()
491 || !IdxExpr
->isIntegerConstantExpr(ArgNum
, S
.Context
)) {
492 S
.Diag(AL
.getLoc(), diag::err_ownership_type
)
493 << "ownership_returns" << "integer"
494 << IdxExpr
->getSourceRange();
501 llvm_unreachable("Unknown ownership attribute");
504 // Check we don't have a conflict with another ownership attribute.
505 for (specific_attr_iterator
<OwnershipAttr
>
506 i
= d
->specific_attr_begin
<OwnershipAttr
>(),
507 e
= d
->specific_attr_end
<OwnershipAttr
>();
509 if ((*i
)->getOwnKind() != K
) {
510 for (const unsigned *I
= (*i
)->args_begin(), *E
= (*i
)->args_end();
513 S
.Diag(AL
.getLoc(), diag::err_attributes_are_not_compatible
)
514 << AL
.getName()->getName() << "ownership_*";
519 OwnershipArgs
.push_back(x
);
522 unsigned* start
= OwnershipArgs
.data();
523 unsigned size
= OwnershipArgs
.size();
524 llvm::array_pod_sort(start
, start
+ size
);
526 if (K
!= OwnershipAttr::Returns
&& OwnershipArgs
.empty()) {
527 S
.Diag(AL
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 2;
531 d
->addAttr(::new (S
.Context
) OwnershipAttr(AL
.getLoc(), S
.Context
, K
, Module
,
535 static bool isStaticVarOrStaticFunciton(Decl
*D
) {
536 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(D
))
537 return VD
->getStorageClass() == SC_Static
;
538 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
))
539 return FD
->getStorageClass() == SC_Static
;
543 static void HandleWeakRefAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
544 // Check the attribute arguments.
545 if (Attr
.getNumArgs() > 1) {
546 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
552 // static int a __attribute__((weakref ("v2")));
553 // static int b() __attribute__((weakref ("f3")));
555 // and ignores the attributes of
557 // static int a __attribute__((weakref ("v2")));
560 if (const DeclContext
*Ctx
= d
->getDeclContext()) {
561 Ctx
= Ctx
->getLookupContext();
562 if (!isa
<TranslationUnitDecl
>(Ctx
) && !isa
<NamespaceDecl
>(Ctx
) ) {
563 S
.Diag(Attr
.getLoc(), diag::err_attribute_weakref_not_global_context
) <<
564 dyn_cast
<NamedDecl
>(d
)->getNameAsString();
569 // The GCC manual says
571 // At present, a declaration to which `weakref' is attached can only
577 // given as an argument to `weakref' or to `alias', `weakref' is
578 // equivalent to `weak'.
580 // gcc 4.4.1 will accept
581 // int a7 __attribute__((weakref));
583 // int a7 __attribute__((weak));
584 // This looks like a bug in gcc. We reject that for now. We should revisit
585 // it if this behaviour is actually used.
587 if (!isStaticVarOrStaticFunciton(d
)) {
588 S
.Diag(Attr
.getLoc(), diag::err_attribute_weakref_not_static
) <<
589 dyn_cast
<NamedDecl
>(d
)->getNameAsString();
594 // static ((alias ("y"), weakref)).
595 // Should we? How to check that weakref is before or after alias?
597 if (Attr
.getNumArgs() == 1) {
598 Expr
*Arg
= static_cast<Expr
*>(Attr
.getArg(0));
599 Arg
= Arg
->IgnoreParenCasts();
600 StringLiteral
*Str
= dyn_cast
<StringLiteral
>(Arg
);
602 if (Str
== 0 || Str
->isWide()) {
603 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_string
)
607 // GCC will accept anything as the argument of weakref. Should we
608 // check for an existing decl?
609 d
->addAttr(::new (S
.Context
) AliasAttr(Attr
.getLoc(), S
.Context
, Str
->getString()));
612 d
->addAttr(::new (S
.Context
) WeakRefAttr(Attr
.getLoc(), S
.Context
));
615 static void HandleAliasAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
616 // check the attribute arguments.
617 if (Attr
.getNumArgs() != 1) {
618 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
622 Expr
*Arg
= static_cast<Expr
*>(Attr
.getArg(0));
623 Arg
= Arg
->IgnoreParenCasts();
624 StringLiteral
*Str
= dyn_cast
<StringLiteral
>(Arg
);
626 if (Str
== 0 || Str
->isWide()) {
627 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_string
)
632 // FIXME: check if target symbol exists in current file
634 d
->addAttr(::new (S
.Context
) AliasAttr(Attr
.getLoc(), S
.Context
, Str
->getString()));
637 static void HandleAlwaysInlineAttr(Decl
*d
, const AttributeList
&Attr
,
639 // check the attribute arguments.
640 if (Attr
.getNumArgs() != 0) {
641 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
645 if (!isa
<FunctionDecl
>(d
)) {
646 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
647 << Attr
.getName() << 0 /*function*/;
651 d
->addAttr(::new (S
.Context
) AlwaysInlineAttr(Attr
.getLoc(), S
.Context
));
654 static void HandleMallocAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
655 // check the attribute arguments.
656 if (Attr
.getNumArgs() != 0) {
657 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
661 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(d
)) {
662 QualType RetTy
= FD
->getResultType();
663 if (RetTy
->isAnyPointerType() || RetTy
->isBlockPointerType()) {
664 d
->addAttr(::new (S
.Context
) MallocAttr(Attr
.getLoc(), S
.Context
));
669 S
.Diag(Attr
.getLoc(), diag::warn_attribute_malloc_pointer_only
);
672 static void HandleNoReturnAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
673 /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
674 assert(Attr
.isInvalid() == false);
675 d
->addAttr(::new (S
.Context
) NoReturnAttr(Attr
.getLoc(), S
.Context
));
678 static void HandleAnalyzerNoReturnAttr(Decl
*d
, const AttributeList
&Attr
,
681 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
682 // because 'analyzer_noreturn' does not impact the type.
684 if (Attr
.getNumArgs() != 0) {
685 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
689 if (!isFunctionOrMethod(d
) && !isa
<BlockDecl
>(d
)) {
690 ValueDecl
*VD
= dyn_cast
<ValueDecl
>(d
);
691 if (VD
== 0 || (!VD
->getType()->isBlockPointerType()
692 && !VD
->getType()->isFunctionPointerType())) {
693 S
.Diag(Attr
.getLoc(),
694 Attr
.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
695 : diag::warn_attribute_wrong_decl_type
)
696 << Attr
.getName() << 0 /*function*/;
701 d
->addAttr(::new (S
.Context
) AnalyzerNoReturnAttr(Attr
.getLoc(), S
.Context
));
705 static void HandleVecReturnAttr(Decl
*d
, const AttributeList
&Attr
,
708 Returning a Vector Class in Registers
710 According to the PPU ABI specifications, a class with a single member of vector type is returned in
711 memory when used as the return value of a function. This results in inefficient code when implementing
712 vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
713 definition. This attribute is also applicable to struct types.
720 } __attribute__((vecreturn));
722 Vector Add(Vector lhs, Vector rhs)
725 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
726 return result; // This will be returned in a register
729 if (!isa
<CXXRecordDecl
>(d
)) {
730 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_decl_type
)
731 << Attr
.getName() << 9 /*class*/;
735 if (d
->getAttr
<VecReturnAttr
>()) {
736 S
.Diag(Attr
.getLoc(), diag::err_repeat_attribute
) << "vecreturn";
740 d
->addAttr(::new (S
.Context
) VecReturnAttr(Attr
.getLoc(), S
.Context
));
743 static void HandleDependencyAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
744 if (!isFunctionOrMethod(d
) && !isa
<ParmVarDecl
>(d
)) {
745 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_decl_type
)
746 << Attr
.getName() << 8 /*function, method, or parameter*/;
749 // FIXME: Actually store the attribute on the declaration
752 static void HandleUnusedAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
753 // check the attribute arguments.
754 if (Attr
.getNumArgs() != 0) {
755 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
759 if (!isa
<VarDecl
>(d
) && !isa
<ObjCIvarDecl
>(d
) && !isFunctionOrMethod(d
) &&
761 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
762 << Attr
.getName() << 2 /*variable and function*/;
766 d
->addAttr(::new (S
.Context
) UnusedAttr(Attr
.getLoc(), S
.Context
));
769 static void HandleUsedAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
770 // check the attribute arguments.
771 if (Attr
.getNumArgs() != 0) {
772 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
776 if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(d
)) {
777 if (VD
->hasLocalStorage() || VD
->hasExternalStorage()) {
778 S
.Diag(Attr
.getLoc(), diag::warn_attribute_ignored
) << "used";
781 } else if (!isFunctionOrMethod(d
)) {
782 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
783 << Attr
.getName() << 2 /*variable and function*/;
787 d
->addAttr(::new (S
.Context
) UsedAttr(Attr
.getLoc(), S
.Context
));
790 static void HandleConstructorAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
791 // check the attribute arguments.
792 if (Attr
.getNumArgs() != 0 && Attr
.getNumArgs() != 1) {
793 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
)
798 int priority
= 65535; // FIXME: Do not hardcode such constants.
799 if (Attr
.getNumArgs() > 0) {
800 Expr
*E
= static_cast<Expr
*>(Attr
.getArg(0));
801 llvm::APSInt
Idx(32);
802 if (E
->isTypeDependent() || E
->isValueDependent() ||
803 !E
->isIntegerConstantExpr(Idx
, S
.Context
)) {
804 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
805 << "constructor" << 1 << E
->getSourceRange();
808 priority
= Idx
.getZExtValue();
811 if (!isa
<FunctionDecl
>(d
)) {
812 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
813 << Attr
.getName() << 0 /*function*/;
817 d
->addAttr(::new (S
.Context
) ConstructorAttr(Attr
.getLoc(), S
.Context
, priority
));
820 static void HandleDestructorAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
821 // check the attribute arguments.
822 if (Attr
.getNumArgs() != 0 && Attr
.getNumArgs() != 1) {
823 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
)
828 int priority
= 65535; // FIXME: Do not hardcode such constants.
829 if (Attr
.getNumArgs() > 0) {
830 Expr
*E
= static_cast<Expr
*>(Attr
.getArg(0));
831 llvm::APSInt
Idx(32);
832 if (E
->isTypeDependent() || E
->isValueDependent() ||
833 !E
->isIntegerConstantExpr(Idx
, S
.Context
)) {
834 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
835 << "destructor" << 1 << E
->getSourceRange();
838 priority
= Idx
.getZExtValue();
841 if (!isa
<FunctionDecl
>(d
)) {
842 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
843 << Attr
.getName() << 0 /*function*/;
847 d
->addAttr(::new (S
.Context
) DestructorAttr(Attr
.getLoc(), S
.Context
, priority
));
850 static void HandleDeprecatedAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
851 // check the attribute arguments.
852 if (Attr
.getNumArgs() != 0) {
853 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
857 d
->addAttr(::new (S
.Context
) DeprecatedAttr(Attr
.getLoc(), S
.Context
));
860 static void HandleUnavailableAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
861 // check the attribute arguments.
862 if (Attr
.getNumArgs() != 0) {
863 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
867 d
->addAttr(::new (S
.Context
) UnavailableAttr(Attr
.getLoc(), S
.Context
));
870 static void HandleVisibilityAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
871 // check the attribute arguments.
872 if (Attr
.getNumArgs() != 1) {
873 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
877 Expr
*Arg
= static_cast<Expr
*>(Attr
.getArg(0));
878 Arg
= Arg
->IgnoreParenCasts();
879 StringLiteral
*Str
= dyn_cast
<StringLiteral
>(Arg
);
881 if (Str
== 0 || Str
->isWide()) {
882 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_string
)
883 << "visibility" << 1;
887 llvm::StringRef TypeStr
= Str
->getString();
888 VisibilityAttr::VisibilityType type
;
890 if (TypeStr
== "default")
891 type
= VisibilityAttr::Default
;
892 else if (TypeStr
== "hidden")
893 type
= VisibilityAttr::Hidden
;
894 else if (TypeStr
== "internal")
895 type
= VisibilityAttr::Hidden
; // FIXME
896 else if (TypeStr
== "protected")
897 type
= VisibilityAttr::Protected
;
899 S
.Diag(Attr
.getLoc(), diag::warn_attribute_unknown_visibility
) << TypeStr
;
903 d
->addAttr(::new (S
.Context
) VisibilityAttr(Attr
.getLoc(), S
.Context
, type
));
906 static void HandleObjCExceptionAttr(Decl
*D
, const AttributeList
&Attr
,
908 if (Attr
.getNumArgs() != 0) {
909 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
913 ObjCInterfaceDecl
*OCI
= dyn_cast
<ObjCInterfaceDecl
>(D
);
915 S
.Diag(Attr
.getLoc(), diag::err_attribute_requires_objc_interface
);
919 D
->addAttr(::new (S
.Context
) ObjCExceptionAttr(Attr
.getLoc(), S
.Context
));
922 static void HandleObjCNSObject(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
923 if (Attr
.getNumArgs() != 0) {
924 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
927 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(D
)) {
928 QualType T
= TD
->getUnderlyingType();
929 if (!T
->isPointerType() ||
930 !T
->getAs
<PointerType
>()->getPointeeType()->isRecordType()) {
931 S
.Diag(TD
->getLocation(), diag::err_nsobject_attribute
);
935 D
->addAttr(::new (S
.Context
) ObjCNSObjectAttr(Attr
.getLoc(), S
.Context
));
939 HandleOverloadableAttr(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
940 if (Attr
.getNumArgs() != 0) {
941 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
945 if (!isa
<FunctionDecl
>(D
)) {
946 S
.Diag(Attr
.getLoc(), diag::err_attribute_overloadable_not_function
);
950 D
->addAttr(::new (S
.Context
) OverloadableAttr(Attr
.getLoc(), S
.Context
));
953 static void HandleBlocksAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
954 if (!Attr
.getParameterName()) {
955 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_string
)
960 if (Attr
.getNumArgs() != 0) {
961 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
965 BlocksAttr::BlockType type
;
966 if (Attr
.getParameterName()->isStr("byref"))
967 type
= BlocksAttr::ByRef
;
969 S
.Diag(Attr
.getLoc(), diag::warn_attribute_type_not_supported
)
970 << "blocks" << Attr
.getParameterName();
974 d
->addAttr(::new (S
.Context
) BlocksAttr(Attr
.getLoc(), S
.Context
, type
));
977 static void HandleSentinelAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
978 // check the attribute arguments.
979 if (Attr
.getNumArgs() > 2) {
980 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
)
986 if (Attr
.getNumArgs() > 0) {
987 Expr
*E
= static_cast<Expr
*>(Attr
.getArg(0));
988 llvm::APSInt
Idx(32);
989 if (E
->isTypeDependent() || E
->isValueDependent() ||
990 !E
->isIntegerConstantExpr(Idx
, S
.Context
)) {
991 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
992 << "sentinel" << 1 << E
->getSourceRange();
995 sentinel
= Idx
.getZExtValue();
998 S
.Diag(Attr
.getLoc(), diag::err_attribute_sentinel_less_than_zero
)
999 << E
->getSourceRange();
1005 if (Attr
.getNumArgs() > 1) {
1006 Expr
*E
= static_cast<Expr
*>(Attr
.getArg(1));
1007 llvm::APSInt
Idx(32);
1008 if (E
->isTypeDependent() || E
->isValueDependent() ||
1009 !E
->isIntegerConstantExpr(Idx
, S
.Context
)) {
1010 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
1011 << "sentinel" << 2 << E
->getSourceRange();
1014 nullPos
= Idx
.getZExtValue();
1016 if (nullPos
> 1 || nullPos
< 0) {
1017 // FIXME: This error message could be improved, it would be nice
1018 // to say what the bounds actually are.
1019 S
.Diag(Attr
.getLoc(), diag::err_attribute_sentinel_not_zero_or_one
)
1020 << E
->getSourceRange();
1025 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(d
)) {
1026 const FunctionType
*FT
= FD
->getType()->getAs
<FunctionType
>();
1027 assert(FT
&& "FunctionDecl has non-function type?");
1029 if (isa
<FunctionNoProtoType
>(FT
)) {
1030 S
.Diag(Attr
.getLoc(), diag::warn_attribute_sentinel_named_arguments
);
1034 if (!cast
<FunctionProtoType
>(FT
)->isVariadic()) {
1035 S
.Diag(Attr
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << 0;
1038 } else if (ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(d
)) {
1039 if (!MD
->isVariadic()) {
1040 S
.Diag(Attr
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << 0;
1043 } else if (isa
<BlockDecl
>(d
)) {
1044 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1047 } else if (const VarDecl
*V
= dyn_cast
<VarDecl
>(d
)) {
1048 QualType Ty
= V
->getType();
1049 if (Ty
->isBlockPointerType() || Ty
->isFunctionPointerType()) {
1050 const FunctionType
*FT
= Ty
->isFunctionPointerType() ? getFunctionType(d
)
1051 : Ty
->getAs
<BlockPointerType
>()->getPointeeType()->getAs
<FunctionType
>();
1052 if (!cast
<FunctionProtoType
>(FT
)->isVariadic()) {
1053 int m
= Ty
->isFunctionPointerType() ? 0 : 1;
1054 S
.Diag(Attr
.getLoc(), diag::warn_attribute_sentinel_not_variadic
) << m
;
1058 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1059 << Attr
.getName() << 6 /*function, method or block */;
1063 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1064 << Attr
.getName() << 6 /*function, method or block */;
1067 d
->addAttr(::new (S
.Context
) SentinelAttr(Attr
.getLoc(), S
.Context
, sentinel
, nullPos
));
1070 static void HandleWarnUnusedResult(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
1071 // check the attribute arguments.
1072 if (Attr
.getNumArgs() != 0) {
1073 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1077 if (!isFunction(D
) && !isa
<ObjCMethodDecl
>(D
)) {
1078 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1079 << Attr
.getName() << 0 /*function*/;
1083 if (isFunction(D
) && getFunctionType(D
)->getResultType()->isVoidType()) {
1084 S
.Diag(Attr
.getLoc(), diag::warn_attribute_void_function_method
)
1085 << Attr
.getName() << 0;
1088 if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
))
1089 if (MD
->getResultType()->isVoidType()) {
1090 S
.Diag(Attr
.getLoc(), diag::warn_attribute_void_function_method
)
1091 << Attr
.getName() << 1;
1095 D
->addAttr(::new (S
.Context
) WarnUnusedResultAttr(Attr
.getLoc(), S
.Context
));
1098 static void HandleWeakAttr(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
1099 // check the attribute arguments.
1100 if (Attr
.getNumArgs() != 0) {
1101 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1105 /* weak only applies to non-static declarations */
1106 if (isStaticVarOrStaticFunciton(D
)) {
1107 S
.Diag(Attr
.getLoc(), diag::err_attribute_weak_static
) <<
1108 dyn_cast
<NamedDecl
>(D
)->getNameAsString();
1112 // TODO: could also be applied to methods?
1113 if (!isa
<FunctionDecl
>(D
) && !isa
<VarDecl
>(D
)) {
1114 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1115 << Attr
.getName() << 2 /*variable and function*/;
1119 D
->addAttr(::new (S
.Context
) WeakAttr(Attr
.getLoc(), S
.Context
));
1122 static void HandleWeakImportAttr(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
1123 // check the attribute arguments.
1124 if (Attr
.getNumArgs() != 0) {
1125 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1129 // weak_import only applies to variable & function declarations.
1131 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
1132 isDef
= (!VD
->hasExternalStorage() || VD
->getInit());
1133 } else if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
1134 isDef
= FD
->hasBody();
1135 } else if (isa
<ObjCPropertyDecl
>(D
) || isa
<ObjCMethodDecl
>(D
)) {
1136 // We ignore weak import on properties and methods
1138 } else if (!(S
.LangOpts
.ObjCNonFragileABI
&& isa
<ObjCInterfaceDecl
>(D
))) {
1139 // Don't issue the warning for darwin as target; yet, ignore the attribute.
1140 if (S
.Context
.Target
.getTriple().getOS() != llvm::Triple::Darwin
||
1141 !isa
<ObjCInterfaceDecl
>(D
))
1142 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1143 << Attr
.getName() << 2 /*variable and function*/;
1147 // Merge should handle any subsequent violations.
1149 S
.Diag(Attr
.getLoc(),
1150 diag::warn_attribute_weak_import_invalid_on_definition
)
1151 << "weak_import" << 2 /*variable and function*/;
1155 D
->addAttr(::new (S
.Context
) WeakImportAttr(Attr
.getLoc(), S
.Context
));
1158 static void HandleReqdWorkGroupSize(Decl
*D
, const AttributeList
&Attr
,
1160 // Attribute has 3 arguments.
1161 if (Attr
.getNumArgs() != 3) {
1162 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1167 for (unsigned i
= 0; i
< 3; ++i
) {
1168 Expr
*E
= static_cast<Expr
*>(Attr
.getArg(i
));
1169 llvm::APSInt
ArgNum(32);
1170 if (E
->isTypeDependent() || E
->isValueDependent() ||
1171 !E
->isIntegerConstantExpr(ArgNum
, S
.Context
)) {
1172 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_not_int
)
1173 << "reqd_work_group_size" << E
->getSourceRange();
1176 WGSize
[i
] = (unsigned) ArgNum
.getZExtValue();
1178 D
->addAttr(::new (S
.Context
) ReqdWorkGroupSizeAttr(Attr
.getLoc(), S
.Context
,
1179 WGSize
[0], WGSize
[1],
1183 static void HandleSectionAttr(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
1184 // Attribute has no arguments.
1185 if (Attr
.getNumArgs() != 1) {
1186 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1190 // Make sure that there is a string literal as the sections's single
1192 Expr
*ArgExpr
= static_cast<Expr
*>(Attr
.getArg(0));
1193 StringLiteral
*SE
= dyn_cast
<StringLiteral
>(ArgExpr
);
1195 S
.Diag(ArgExpr
->getLocStart(), diag::err_attribute_not_string
) << "section";
1199 // If the target wants to validate the section specifier, make it happen.
1200 std::string Error
= S
.Context
.Target
.isValidSectionSpecifier(SE
->getString());
1201 if (!Error
.empty()) {
1202 S
.Diag(SE
->getLocStart(), diag::err_attribute_section_invalid_for_target
)
1207 // This attribute cannot be applied to local variables.
1208 if (isa
<VarDecl
>(D
) && cast
<VarDecl
>(D
)->hasLocalStorage()) {
1209 S
.Diag(SE
->getLocStart(), diag::err_attribute_section_local_variable
);
1213 D
->addAttr(::new (S
.Context
) SectionAttr(Attr
.getLoc(), S
.Context
, SE
->getString()));
1217 static void HandleNothrowAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1218 // check the attribute arguments.
1219 if (Attr
.getNumArgs() != 0) {
1220 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1224 d
->addAttr(::new (S
.Context
) NoThrowAttr(Attr
.getLoc(), S
.Context
));
1227 static void HandleConstAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1228 // check the attribute arguments.
1229 if (Attr
.getNumArgs() != 0) {
1230 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1234 d
->addAttr(::new (S
.Context
) ConstAttr(Attr
.getLoc(), S
.Context
));
1237 static void HandlePureAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1238 // check the attribute arguments.
1239 if (Attr
.getNumArgs() != 0) {
1240 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1244 d
->addAttr(::new (S
.Context
) PureAttr(Attr
.getLoc(), S
.Context
));
1247 static void HandleCleanupAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1248 if (!Attr
.getParameterName()) {
1249 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1253 if (Attr
.getNumArgs() != 0) {
1254 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1258 VarDecl
*VD
= dyn_cast
<VarDecl
>(d
);
1260 if (!VD
|| !VD
->hasLocalStorage()) {
1261 S
.Diag(Attr
.getLoc(), diag::warn_attribute_ignored
) << "cleanup";
1265 // Look up the function
1266 // FIXME: Lookup probably isn't looking in the right place
1267 // FIXME: The lookup source location should be in the attribute, not the
1268 // start of the attribute.
1269 NamedDecl
*CleanupDecl
1270 = S
.LookupSingleName(S
.TUScope
, Attr
.getParameterName(), Attr
.getLoc(),
1271 Sema::LookupOrdinaryName
);
1273 S
.Diag(Attr
.getLoc(), diag::err_attribute_cleanup_arg_not_found
) <<
1274 Attr
.getParameterName();
1278 FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(CleanupDecl
);
1280 S
.Diag(Attr
.getLoc(), diag::err_attribute_cleanup_arg_not_function
) <<
1281 Attr
.getParameterName();
1285 if (FD
->getNumParams() != 1) {
1286 S
.Diag(Attr
.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg
) <<
1287 Attr
.getParameterName();
1291 // We're currently more strict than GCC about what function types we accept.
1292 // If this ever proves to be a problem it should be easy to fix.
1293 QualType Ty
= S
.Context
.getPointerType(VD
->getType());
1294 QualType ParamTy
= FD
->getParamDecl(0)->getType();
1295 if (S
.CheckAssignmentConstraints(ParamTy
, Ty
) != Sema::Compatible
) {
1296 S
.Diag(Attr
.getLoc(),
1297 diag::err_attribute_cleanup_func_arg_incompatible_type
) <<
1298 Attr
.getParameterName() << ParamTy
<< Ty
;
1302 d
->addAttr(::new (S
.Context
) CleanupAttr(Attr
.getLoc(), S
.Context
, FD
));
1305 /// Handle __attribute__((format_arg((idx)))) attribute based on
1306 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1307 static void HandleFormatArgAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1308 if (Attr
.getNumArgs() != 1) {
1309 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1312 if (!isFunctionOrMethod(d
) || !hasFunctionProto(d
)) {
1313 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1314 << Attr
.getName() << 0 /*function*/;
1317 // FIXME: in C++ the implicit 'this' function parameter also counts. this is
1318 // needed in order to be compatible with GCC the index must start with 1.
1319 unsigned NumArgs
= getFunctionOrMethodNumArgs(d
);
1320 unsigned FirstIdx
= 1;
1321 // checks for the 2nd argument
1322 Expr
*IdxExpr
= static_cast<Expr
*>(Attr
.getArg(0));
1323 llvm::APSInt
Idx(32);
1324 if (IdxExpr
->isTypeDependent() || IdxExpr
->isValueDependent() ||
1325 !IdxExpr
->isIntegerConstantExpr(Idx
, S
.Context
)) {
1326 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
1327 << "format" << 2 << IdxExpr
->getSourceRange();
1331 if (Idx
.getZExtValue() < FirstIdx
|| Idx
.getZExtValue() > NumArgs
) {
1332 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
1333 << "format" << 2 << IdxExpr
->getSourceRange();
1337 unsigned ArgIdx
= Idx
.getZExtValue() - 1;
1339 // make sure the format string is really a string
1340 QualType Ty
= getFunctionOrMethodArgType(d
, ArgIdx
);
1342 bool not_nsstring_type
= !isNSStringType(Ty
, S
.Context
);
1343 if (not_nsstring_type
&&
1344 !isCFStringType(Ty
, S
.Context
) &&
1345 (!Ty
->isPointerType() ||
1346 !Ty
->getAs
<PointerType
>()->getPointeeType()->isCharType())) {
1347 // FIXME: Should highlight the actual expression that has the wrong type.
1348 S
.Diag(Attr
.getLoc(), diag::err_format_attribute_not
)
1349 << (not_nsstring_type
? "a string type" : "an NSString")
1350 << IdxExpr
->getSourceRange();
1353 Ty
= getFunctionOrMethodResultType(d
);
1354 if (!isNSStringType(Ty
, S
.Context
) &&
1355 !isCFStringType(Ty
, S
.Context
) &&
1356 (!Ty
->isPointerType() ||
1357 !Ty
->getAs
<PointerType
>()->getPointeeType()->isCharType())) {
1358 // FIXME: Should highlight the actual expression that has the wrong type.
1359 S
.Diag(Attr
.getLoc(), diag::err_format_attribute_result_not
)
1360 << (not_nsstring_type
? "string type" : "NSString")
1361 << IdxExpr
->getSourceRange();
1365 d
->addAttr(::new (S
.Context
) FormatArgAttr(Attr
.getLoc(), S
.Context
, Idx
.getZExtValue()));
1368 enum FormatAttrKind
{
1377 /// getFormatAttrKind - Map from format attribute names to supported format
1379 static FormatAttrKind
getFormatAttrKind(llvm::StringRef Format
) {
1380 // Check for formats that get handled specially.
1381 if (Format
== "NSString")
1382 return NSStringFormat
;
1383 if (Format
== "CFString")
1384 return CFStringFormat
;
1385 if (Format
== "strftime")
1386 return StrftimeFormat
;
1388 // Otherwise, check for supported formats.
1389 if (Format
== "scanf" || Format
== "printf" || Format
== "printf0" ||
1390 Format
== "strfmon" || Format
== "cmn_err" || Format
== "strftime" ||
1391 Format
== "NSString" || Format
== "CFString" || Format
== "vcmn_err" ||
1392 Format
== "zcmn_err")
1393 return SupportedFormat
;
1395 if (Format
== "gcc_diag" || Format
== "gcc_cdiag" ||
1396 Format
== "gcc_cxxdiag" || Format
== "gcc_tdiag")
1397 return IgnoredFormat
;
1399 return InvalidFormat
;
1402 /// Handle __attribute__((init_priority(priority))) attributes based on
1403 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
1404 static void HandleInitPriorityAttr(Decl
*d
, const AttributeList
&Attr
,
1406 if (!S
.getLangOptions().CPlusPlus
) {
1407 S
.Diag(Attr
.getLoc(), diag::warn_attribute_ignored
) << Attr
.getName();
1411 if (!isa
<VarDecl
>(d
) || S
.getCurFunctionOrMethodDecl()) {
1412 S
.Diag(Attr
.getLoc(), diag::err_init_priority_object_attr
);
1416 QualType T
= dyn_cast
<VarDecl
>(d
)->getType();
1417 if (S
.Context
.getAsArrayType(T
))
1418 T
= S
.Context
.getBaseElementType(T
);
1419 if (!T
->getAs
<RecordType
>()) {
1420 S
.Diag(Attr
.getLoc(), diag::err_init_priority_object_attr
);
1425 if (Attr
.getNumArgs() != 1) {
1426 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1430 Expr
*priorityExpr
= static_cast<Expr
*>(Attr
.getArg(0));
1432 llvm::APSInt
priority(32);
1433 if (priorityExpr
->isTypeDependent() || priorityExpr
->isValueDependent() ||
1434 !priorityExpr
->isIntegerConstantExpr(priority
, S
.Context
)) {
1435 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_not_int
)
1436 << "init_priority" << priorityExpr
->getSourceRange();
1440 unsigned prioritynum
= priority
.getZExtValue();
1441 if (prioritynum
< 101 || prioritynum
> 65535) {
1442 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_outof_range
)
1443 << priorityExpr
->getSourceRange();
1447 d
->addAttr(::new (S
.Context
) InitPriorityAttr(Attr
.getLoc(), S
.Context
, prioritynum
));
1450 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1451 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1452 static void HandleFormatAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1454 if (!Attr
.getParameterName()) {
1455 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_string
)
1460 if (Attr
.getNumArgs() != 2) {
1461 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 3;
1465 if (!isFunctionOrMethodOrBlock(d
) || !hasFunctionProto(d
)) {
1466 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1467 << Attr
.getName() << 0 /*function*/;
1471 unsigned NumArgs
= getFunctionOrMethodNumArgs(d
);
1472 unsigned FirstIdx
= 1;
1474 llvm::StringRef Format
= Attr
.getParameterName()->getName();
1476 // Normalize the argument, __foo__ becomes foo.
1477 if (Format
.startswith("__") && Format
.endswith("__"))
1478 Format
= Format
.substr(2, Format
.size() - 4);
1480 // Check for supported formats.
1481 FormatAttrKind Kind
= getFormatAttrKind(Format
);
1483 if (Kind
== IgnoredFormat
)
1486 if (Kind
== InvalidFormat
) {
1487 S
.Diag(Attr
.getLoc(), diag::warn_attribute_type_not_supported
)
1488 << "format" << Attr
.getParameterName()->getName();
1492 // checks for the 2nd argument
1493 Expr
*IdxExpr
= static_cast<Expr
*>(Attr
.getArg(0));
1494 llvm::APSInt
Idx(32);
1495 if (IdxExpr
->isTypeDependent() || IdxExpr
->isValueDependent() ||
1496 !IdxExpr
->isIntegerConstantExpr(Idx
, S
.Context
)) {
1497 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
1498 << "format" << 2 << IdxExpr
->getSourceRange();
1502 // FIXME: We should handle the implicit 'this' parameter in a more generic
1503 // way that can be used for other arguments.
1504 bool HasImplicitThisParam
= false;
1505 if (CXXMethodDecl
*MD
= dyn_cast
<CXXMethodDecl
>(d
)) {
1506 if (MD
->isInstance()) {
1507 HasImplicitThisParam
= true;
1512 if (Idx
.getZExtValue() < FirstIdx
|| Idx
.getZExtValue() > NumArgs
) {
1513 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
1514 << "format" << 2 << IdxExpr
->getSourceRange();
1518 // FIXME: Do we need to bounds check?
1519 unsigned ArgIdx
= Idx
.getZExtValue() - 1;
1521 if (HasImplicitThisParam
) {
1523 S
.Diag(Attr
.getLoc(), diag::err_format_attribute_not
)
1524 << "a string type" << IdxExpr
->getSourceRange();
1530 // make sure the format string is really a string
1531 QualType Ty
= getFunctionOrMethodArgType(d
, ArgIdx
);
1533 if (Kind
== CFStringFormat
) {
1534 if (!isCFStringType(Ty
, S
.Context
)) {
1535 S
.Diag(Attr
.getLoc(), diag::err_format_attribute_not
)
1536 << "a CFString" << IdxExpr
->getSourceRange();
1539 } else if (Kind
== NSStringFormat
) {
1540 // FIXME: do we need to check if the type is NSString*? What are the
1542 if (!isNSStringType(Ty
, S
.Context
)) {
1543 // FIXME: Should highlight the actual expression that has the wrong type.
1544 S
.Diag(Attr
.getLoc(), diag::err_format_attribute_not
)
1545 << "an NSString" << IdxExpr
->getSourceRange();
1548 } else if (!Ty
->isPointerType() ||
1549 !Ty
->getAs
<PointerType
>()->getPointeeType()->isCharType()) {
1550 // FIXME: Should highlight the actual expression that has the wrong type.
1551 S
.Diag(Attr
.getLoc(), diag::err_format_attribute_not
)
1552 << "a string type" << IdxExpr
->getSourceRange();
1556 // check the 3rd argument
1557 Expr
*FirstArgExpr
= static_cast<Expr
*>(Attr
.getArg(1));
1558 llvm::APSInt
FirstArg(32);
1559 if (FirstArgExpr
->isTypeDependent() || FirstArgExpr
->isValueDependent() ||
1560 !FirstArgExpr
->isIntegerConstantExpr(FirstArg
, S
.Context
)) {
1561 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_n_not_int
)
1562 << "format" << 3 << FirstArgExpr
->getSourceRange();
1566 // check if the function is variadic if the 3rd argument non-zero
1567 if (FirstArg
!= 0) {
1568 if (isFunctionOrMethodVariadic(d
)) {
1569 ++NumArgs
; // +1 for ...
1571 S
.Diag(d
->getLocation(), diag::err_format_attribute_requires_variadic
);
1576 // strftime requires FirstArg to be 0 because it doesn't read from any
1577 // variable the input is just the current time + the format string.
1578 if (Kind
== StrftimeFormat
) {
1579 if (FirstArg
!= 0) {
1580 S
.Diag(Attr
.getLoc(), diag::err_format_strftime_third_parameter
)
1581 << FirstArgExpr
->getSourceRange();
1584 // if 0 it disables parameter checking (to use with e.g. va_list)
1585 } else if (FirstArg
!= 0 && FirstArg
!= NumArgs
) {
1586 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
1587 << "format" << 3 << FirstArgExpr
->getSourceRange();
1591 d
->addAttr(::new (S
.Context
) FormatAttr(Attr
.getLoc(), S
.Context
, Format
,
1593 FirstArg
.getZExtValue()));
1596 static void HandleTransparentUnionAttr(Decl
*d
, const AttributeList
&Attr
,
1598 // check the attribute arguments.
1599 if (Attr
.getNumArgs() != 0) {
1600 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1604 // Try to find the underlying union declaration.
1606 TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(d
);
1607 if (TD
&& TD
->getUnderlyingType()->isUnionType())
1608 RD
= TD
->getUnderlyingType()->getAsUnionType()->getDecl();
1610 RD
= dyn_cast
<RecordDecl
>(d
);
1612 if (!RD
|| !RD
->isUnion()) {
1613 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1614 << Attr
.getName() << 1 /*union*/;
1618 if (!RD
->isDefinition()) {
1619 S
.Diag(Attr
.getLoc(),
1620 diag::warn_transparent_union_attribute_not_definition
);
1624 RecordDecl::field_iterator Field
= RD
->field_begin(),
1625 FieldEnd
= RD
->field_end();
1626 if (Field
== FieldEnd
) {
1627 S
.Diag(Attr
.getLoc(), diag::warn_transparent_union_attribute_zero_fields
);
1631 FieldDecl
*FirstField
= *Field
;
1632 QualType FirstType
= FirstField
->getType();
1633 if (FirstType
->hasFloatingRepresentation() || FirstType
->isVectorType()) {
1634 S
.Diag(FirstField
->getLocation(),
1635 diag::warn_transparent_union_attribute_floating
)
1636 << FirstType
->isVectorType() << FirstType
;
1640 uint64_t FirstSize
= S
.Context
.getTypeSize(FirstType
);
1641 uint64_t FirstAlign
= S
.Context
.getTypeAlign(FirstType
);
1642 for (; Field
!= FieldEnd
; ++Field
) {
1643 QualType FieldType
= Field
->getType();
1644 if (S
.Context
.getTypeSize(FieldType
) != FirstSize
||
1645 S
.Context
.getTypeAlign(FieldType
) != FirstAlign
) {
1646 // Warn if we drop the attribute.
1647 bool isSize
= S
.Context
.getTypeSize(FieldType
) != FirstSize
;
1648 unsigned FieldBits
= isSize
? S
.Context
.getTypeSize(FieldType
)
1649 : S
.Context
.getTypeAlign(FieldType
);
1650 S
.Diag(Field
->getLocation(),
1651 diag::warn_transparent_union_attribute_field_size_align
)
1652 << isSize
<< Field
->getDeclName() << FieldBits
;
1653 unsigned FirstBits
= isSize
? FirstSize
: FirstAlign
;
1654 S
.Diag(FirstField
->getLocation(),
1655 diag::note_transparent_union_first_field_size_align
)
1656 << isSize
<< FirstBits
;
1661 RD
->addAttr(::new (S
.Context
) TransparentUnionAttr(Attr
.getLoc(), S
.Context
));
1664 static void HandleAnnotateAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1665 // check the attribute arguments.
1666 if (Attr
.getNumArgs() != 1) {
1667 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1670 Expr
*ArgExpr
= static_cast<Expr
*>(Attr
.getArg(0));
1671 StringLiteral
*SE
= dyn_cast
<StringLiteral
>(ArgExpr
);
1673 // Make sure that there is a string literal as the annotation's single
1676 S
.Diag(ArgExpr
->getLocStart(), diag::err_attribute_not_string
) <<"annotate";
1679 d
->addAttr(::new (S
.Context
) AnnotateAttr(Attr
.getLoc(), S
.Context
, SE
->getString()));
1682 static void HandleAlignedAttr(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
1683 // check the attribute arguments.
1684 if (Attr
.getNumArgs() > 1) {
1685 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
1689 //FIXME: The C++0x version of this attribute has more limited applicabilty
1690 // than GNU's, and should error out when it is used to specify a
1691 // weaker alignment, rather than being silently ignored.
1693 if (Attr
.getNumArgs() == 0) {
1694 D
->addAttr(::new (S
.Context
) AlignedAttr(Attr
.getLoc(), S
.Context
, true, 0));
1698 S
.AddAlignedAttr(Attr
.getLoc(), D
, static_cast<Expr
*>(Attr
.getArg(0)));
1701 void Sema::AddAlignedAttr(SourceLocation AttrLoc
, Decl
*D
, Expr
*E
) {
1702 if (E
->isTypeDependent() || E
->isValueDependent()) {
1703 // Save dependent expressions in the AST to be instantiated.
1704 D
->addAttr(::new (Context
) AlignedAttr(AttrLoc
, Context
, true, E
));
1708 // FIXME: Cache the number on the Attr object?
1709 llvm::APSInt
Alignment(32);
1710 if (!E
->isIntegerConstantExpr(Alignment
, Context
)) {
1711 Diag(AttrLoc
, diag::err_attribute_argument_not_int
)
1712 << "aligned" << E
->getSourceRange();
1715 if (!llvm::isPowerOf2_64(Alignment
.getZExtValue())) {
1716 Diag(AttrLoc
, diag::err_attribute_aligned_not_power_of_two
)
1717 << E
->getSourceRange();
1721 D
->addAttr(::new (Context
) AlignedAttr(AttrLoc
, Context
, true, E
));
1724 void Sema::AddAlignedAttr(SourceLocation AttrLoc
, Decl
*D
, TypeSourceInfo
*TS
) {
1725 // FIXME: Cache the number on the Attr object if non-dependent?
1726 // FIXME: Perform checking of type validity
1727 D
->addAttr(::new (Context
) AlignedAttr(AttrLoc
, Context
, false, TS
));
1731 /// HandleModeAttr - This attribute modifies the width of a decl with primitive
1734 /// Despite what would be logical, the mode attribute is a decl attribute, not a
1735 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
1736 /// HImode, not an intermediate pointer.
1737 static void HandleModeAttr(Decl
*D
, const AttributeList
&Attr
, Sema
&S
) {
1738 // This attribute isn't documented, but glibc uses it. It changes
1739 // the width of an int or unsigned int to the specified size.
1741 // Check that there aren't any arguments
1742 if (Attr
.getNumArgs() != 0) {
1743 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1747 IdentifierInfo
*Name
= Attr
.getParameterName();
1749 S
.Diag(Attr
.getLoc(), diag::err_attribute_missing_parameter_name
);
1753 llvm::StringRef Str
= Attr
.getParameterName()->getName();
1755 // Normalize the attribute name, __foo__ becomes foo.
1756 if (Str
.startswith("__") && Str
.endswith("__"))
1757 Str
= Str
.substr(2, Str
.size() - 4);
1759 unsigned DestWidth
= 0;
1760 bool IntegerMode
= true;
1761 bool ComplexMode
= false;
1762 switch (Str
.size()) {
1765 case 'Q': DestWidth
= 8; break;
1766 case 'H': DestWidth
= 16; break;
1767 case 'S': DestWidth
= 32; break;
1768 case 'D': DestWidth
= 64; break;
1769 case 'X': DestWidth
= 96; break;
1770 case 'T': DestWidth
= 128; break;
1772 if (Str
[1] == 'F') {
1773 IntegerMode
= false;
1774 } else if (Str
[1] == 'C') {
1775 IntegerMode
= false;
1777 } else if (Str
[1] != 'I') {
1782 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1783 // pointer on PIC16 and other embedded platforms.
1785 DestWidth
= S
.Context
.Target
.getPointerWidth(0);
1786 else if (Str
== "byte")
1787 DestWidth
= S
.Context
.Target
.getCharWidth();
1790 if (Str
== "pointer")
1791 DestWidth
= S
.Context
.Target
.getPointerWidth(0);
1796 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(D
))
1797 OldTy
= TD
->getUnderlyingType();
1798 else if (ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
1799 OldTy
= VD
->getType();
1801 S
.Diag(D
->getLocation(), diag::err_attr_wrong_decl
)
1802 << "mode" << SourceRange(Attr
.getLoc(), Attr
.getLoc());
1806 if (!OldTy
->getAs
<BuiltinType
>() && !OldTy
->isComplexType())
1807 S
.Diag(Attr
.getLoc(), diag::err_mode_not_primitive
);
1808 else if (IntegerMode
) {
1809 if (!OldTy
->isIntegralOrEnumerationType())
1810 S
.Diag(Attr
.getLoc(), diag::err_mode_wrong_type
);
1811 } else if (ComplexMode
) {
1812 if (!OldTy
->isComplexType())
1813 S
.Diag(Attr
.getLoc(), diag::err_mode_wrong_type
);
1815 if (!OldTy
->isFloatingType())
1816 S
.Diag(Attr
.getLoc(), diag::err_mode_wrong_type
);
1819 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1820 // and friends, at least with glibc.
1821 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1822 // width on unusual platforms.
1823 // FIXME: Make sure floating-point mappings are accurate
1824 // FIXME: Support XF and TF types
1826 switch (DestWidth
) {
1828 S
.Diag(Attr
.getLoc(), diag::err_unknown_machine_mode
) << Name
;
1831 S
.Diag(Attr
.getLoc(), diag::err_unsupported_machine_mode
) << Name
;
1835 S
.Diag(Attr
.getLoc(), diag::err_unsupported_machine_mode
) << Name
;
1838 if (OldTy
->isSignedIntegerType())
1839 NewTy
= S
.Context
.SignedCharTy
;
1841 NewTy
= S
.Context
.UnsignedCharTy
;
1845 S
.Diag(Attr
.getLoc(), diag::err_unsupported_machine_mode
) << Name
;
1848 if (OldTy
->isSignedIntegerType())
1849 NewTy
= S
.Context
.ShortTy
;
1851 NewTy
= S
.Context
.UnsignedShortTy
;
1855 NewTy
= S
.Context
.FloatTy
;
1856 else if (OldTy
->isSignedIntegerType())
1857 NewTy
= S
.Context
.IntTy
;
1859 NewTy
= S
.Context
.UnsignedIntTy
;
1863 NewTy
= S
.Context
.DoubleTy
;
1864 else if (OldTy
->isSignedIntegerType())
1865 if (S
.Context
.Target
.getLongWidth() == 64)
1866 NewTy
= S
.Context
.LongTy
;
1868 NewTy
= S
.Context
.LongLongTy
;
1870 if (S
.Context
.Target
.getLongWidth() == 64)
1871 NewTy
= S
.Context
.UnsignedLongTy
;
1873 NewTy
= S
.Context
.UnsignedLongLongTy
;
1876 NewTy
= S
.Context
.LongDoubleTy
;
1880 S
.Diag(Attr
.getLoc(), diag::err_unsupported_machine_mode
) << Name
;
1883 if (OldTy
->isSignedIntegerType())
1884 NewTy
= S
.Context
.Int128Ty
;
1886 NewTy
= S
.Context
.UnsignedInt128Ty
;
1891 NewTy
= S
.Context
.getComplexType(NewTy
);
1894 // Install the new type.
1895 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(D
)) {
1896 // FIXME: preserve existing source info.
1897 TD
->setTypeSourceInfo(S
.Context
.getTrivialTypeSourceInfo(NewTy
));
1899 cast
<ValueDecl
>(D
)->setType(NewTy
);
1902 static void HandleNoDebugAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1903 // check the attribute arguments.
1904 if (Attr
.getNumArgs() > 0) {
1905 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1909 if (!isFunctionOrMethod(d
)) {
1910 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1911 << Attr
.getName() << 0 /*function*/;
1915 d
->addAttr(::new (S
.Context
) NoDebugAttr(Attr
.getLoc(), S
.Context
));
1918 static void HandleNoInlineAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1919 // check the attribute arguments.
1920 if (Attr
.getNumArgs() != 0) {
1921 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1925 if (!isa
<FunctionDecl
>(d
)) {
1926 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1927 << Attr
.getName() << 0 /*function*/;
1931 d
->addAttr(::new (S
.Context
) NoInlineAttr(Attr
.getLoc(), S
.Context
));
1934 static void HandleNoInstrumentFunctionAttr(Decl
*d
, const AttributeList
&Attr
,
1936 // check the attribute arguments.
1937 if (Attr
.getNumArgs() != 0) {
1938 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1942 if (!isa
<FunctionDecl
>(d
)) {
1943 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1944 << Attr
.getName() << 0 /*function*/;
1948 d
->addAttr(::new (S
.Context
) NoInstrumentFunctionAttr(Attr
.getLoc(), S
.Context
));
1951 static void HandleGNUInlineAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1952 // check the attribute arguments.
1953 if (Attr
.getNumArgs() != 0) {
1954 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
1958 FunctionDecl
*Fn
= dyn_cast
<FunctionDecl
>(d
);
1960 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
1961 << Attr
.getName() << 0 /*function*/;
1965 if (!Fn
->isInlineSpecified()) {
1966 S
.Diag(Attr
.getLoc(), diag::warn_gnu_inline_attribute_requires_inline
);
1970 d
->addAttr(::new (S
.Context
) GNUInlineAttr(Attr
.getLoc(), S
.Context
));
1973 static void HandleCallConvAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1974 // Diagnostic is emitted elsewhere: here we store the (valid) Attr
1975 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
1976 assert(Attr
.isInvalid() == false);
1978 switch (Attr
.getKind()) {
1979 case AttributeList::AT_fastcall
:
1980 d
->addAttr(::new (S
.Context
) FastCallAttr(Attr
.getLoc(), S
.Context
));
1982 case AttributeList::AT_stdcall
:
1983 d
->addAttr(::new (S
.Context
) StdCallAttr(Attr
.getLoc(), S
.Context
));
1985 case AttributeList::AT_thiscall
:
1986 d
->addAttr(::new (S
.Context
) ThisCallAttr(Attr
.getLoc(), S
.Context
));
1987 case AttributeList::AT_cdecl
:
1988 d
->addAttr(::new (S
.Context
) CDeclAttr(Attr
.getLoc(), S
.Context
));
1991 llvm_unreachable("unexpected attribute kind");
1996 static void HandleRegparmAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
1997 // check the attribute arguments.
1998 if (Attr
.getNumArgs() != 1) {
1999 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 1;
2003 if (!isFunctionOrMethod(d
)) {
2004 S
.Diag(Attr
.getLoc(), diag::warn_attribute_wrong_decl_type
)
2005 << Attr
.getName() << 0 /*function*/;
2009 Expr
*NumParamsExpr
= static_cast<Expr
*>(Attr
.getArg(0));
2010 llvm::APSInt
NumParams(32);
2011 if (NumParamsExpr
->isTypeDependent() || NumParamsExpr
->isValueDependent() ||
2012 !NumParamsExpr
->isIntegerConstantExpr(NumParams
, S
.Context
)) {
2013 S
.Diag(Attr
.getLoc(), diag::err_attribute_argument_not_int
)
2014 << "regparm" << NumParamsExpr
->getSourceRange();
2018 if (S
.Context
.Target
.getRegParmMax() == 0) {
2019 S
.Diag(Attr
.getLoc(), diag::err_attribute_regparm_wrong_platform
)
2020 << NumParamsExpr
->getSourceRange();
2024 if (NumParams
.getLimitedValue(255) > S
.Context
.Target
.getRegParmMax()) {
2025 S
.Diag(Attr
.getLoc(), diag::err_attribute_regparm_invalid_number
)
2026 << S
.Context
.Target
.getRegParmMax() << NumParamsExpr
->getSourceRange();
2030 d
->addAttr(::new (S
.Context
) RegparmAttr(Attr
.getLoc(), S
.Context
,
2031 NumParams
.getZExtValue()));
2034 static void HandleFinalAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
2035 // check the attribute arguments.
2036 if (Attr
.getNumArgs() != 0) {
2037 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
2041 if (!isa
<CXXRecordDecl
>(d
)
2042 && (!isa
<CXXMethodDecl
>(d
) || !cast
<CXXMethodDecl
>(d
)->isVirtual())) {
2043 S
.Diag(Attr
.getLoc(),
2044 Attr
.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2045 : diag::warn_attribute_wrong_decl_type
)
2046 << Attr
.getName() << 7 /*virtual method or class*/;
2050 // FIXME: Conform to C++0x redeclaration rules.
2052 if (d
->getAttr
<FinalAttr
>()) {
2053 S
.Diag(Attr
.getLoc(), diag::err_repeat_attribute
) << "final";
2057 d
->addAttr(::new (S
.Context
) FinalAttr(Attr
.getLoc(), S
.Context
));
2060 //===----------------------------------------------------------------------===//
2061 // C++0x member checking attributes
2062 //===----------------------------------------------------------------------===//
2064 static void HandleBaseCheckAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
2065 if (Attr
.getNumArgs() != 0) {
2066 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
2070 if (!isa
<CXXRecordDecl
>(d
)) {
2071 S
.Diag(Attr
.getLoc(),
2072 Attr
.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2073 : diag::warn_attribute_wrong_decl_type
)
2074 << Attr
.getName() << 9 /*class*/;
2078 if (d
->getAttr
<BaseCheckAttr
>()) {
2079 S
.Diag(Attr
.getLoc(), diag::err_repeat_attribute
) << "base_check";
2083 d
->addAttr(::new (S
.Context
) BaseCheckAttr(Attr
.getLoc(), S
.Context
));
2086 static void HandleHidingAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
2087 if (Attr
.getNumArgs() != 0) {
2088 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
2092 if (!isa
<RecordDecl
>(d
->getDeclContext())) {
2093 // FIXME: It's not the type that's the problem
2094 S
.Diag(Attr
.getLoc(),
2095 Attr
.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2096 : diag::warn_attribute_wrong_decl_type
)
2097 << Attr
.getName() << 11 /*member*/;
2101 // FIXME: Conform to C++0x redeclaration rules.
2103 if (d
->getAttr
<HidingAttr
>()) {
2104 S
.Diag(Attr
.getLoc(), diag::err_repeat_attribute
) << "hiding";
2108 d
->addAttr(::new (S
.Context
) HidingAttr(Attr
.getLoc(), S
.Context
));
2111 static void HandleOverrideAttr(Decl
*d
, const AttributeList
&Attr
, Sema
&S
) {
2112 if (Attr
.getNumArgs() != 0) {
2113 S
.Diag(Attr
.getLoc(), diag::err_attribute_wrong_number_arguments
) << 0;
2117 if (!isa
<CXXMethodDecl
>(d
) || !cast
<CXXMethodDecl
>(d
)->isVirtual()) {
2118 // FIXME: It's not the type that's the problem
2119 S
.Diag(Attr
.getLoc(),
2120 Attr
.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
2121 : diag::warn_attribute_wrong_decl_type
)
2122 << Attr
.getName() << 10 /*virtual method*/;
2126 // FIXME: Conform to C++0x redeclaration rules.
2128 if (d
->getAttr
<OverrideAttr
>()) {
2129 S
.Diag(Attr
.getLoc(), diag::err_repeat_attribute
) << "override";
2133 d
->addAttr(::new (S
.Context
) OverrideAttr(Attr
.getLoc(), S
.Context
));
2136 //===----------------------------------------------------------------------===//
2137 // Checker-specific attribute handlers.
2138 //===----------------------------------------------------------------------===//
2140 static void HandleNSReturnsRetainedAttr(Decl
*d
, const AttributeList
&Attr
,
2145 if (ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(d
))
2146 RetTy
= MD
->getResultType();
2147 else if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(d
))
2148 RetTy
= FD
->getResultType();
2150 SourceLocation L
= Attr
.getLoc();
2151 S
.Diag(d
->getLocStart(), diag::warn_attribute_wrong_decl_type
)
2152 << SourceRange(L
, L
) << Attr
.getName() << 3 /* function or method */;
2156 if (!(S
.Context
.isObjCNSObjectType(RetTy
) || RetTy
->getAs
<PointerType
>()
2157 || RetTy
->getAs
<ObjCObjectPointerType
>())) {
2158 SourceLocation L
= Attr
.getLoc();
2159 S
.Diag(d
->getLocStart(), diag::warn_ns_attribute_wrong_return_type
)
2160 << SourceRange(L
, L
) << Attr
.getName();
2164 switch (Attr
.getKind()) {
2166 assert(0 && "invalid ownership attribute");
2168 case AttributeList::AT_cf_returns_not_retained
:
2169 d
->addAttr(::new (S
.Context
) CFReturnsNotRetainedAttr(Attr
.getLoc(), S
.Context
));
2171 case AttributeList::AT_ns_returns_not_retained
:
2172 d
->addAttr(::new (S
.Context
) NSReturnsNotRetainedAttr(Attr
.getLoc(), S
.Context
));
2174 case AttributeList::AT_cf_returns_retained
:
2175 d
->addAttr(::new (S
.Context
) CFReturnsRetainedAttr(Attr
.getLoc(), S
.Context
));
2177 case AttributeList::AT_ns_returns_retained
:
2178 d
->addAttr(::new (S
.Context
) NSReturnsRetainedAttr(Attr
.getLoc(), S
.Context
));
2183 static bool isKnownDeclSpecAttr(const AttributeList
&Attr
) {
2184 return Attr
.getKind() == AttributeList::AT_dllimport
||
2185 Attr
.getKind() == AttributeList::AT_dllexport
;
2188 //===----------------------------------------------------------------------===//
2189 // Top Level Sema Entry Points
2190 //===----------------------------------------------------------------------===//
2192 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
2193 /// the attribute applies to decls. If the attribute is a type attribute, just
2194 /// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to
2195 /// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4).
2196 static void ProcessDeclAttribute(Scope
*scope
, Decl
*D
,
2197 const AttributeList
&Attr
, Sema
&S
) {
2198 if (Attr
.isInvalid())
2201 if (Attr
.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr
))
2202 // FIXME: Try to deal with other __declspec attributes!
2204 switch (Attr
.getKind()) {
2205 case AttributeList::AT_IBAction
: HandleIBAction(D
, Attr
, S
); break;
2206 case AttributeList::AT_IBOutlet
: HandleIBOutlet(D
, Attr
, S
); break;
2207 case AttributeList::AT_IBOutletCollection
:
2208 HandleIBOutletCollection(D
, Attr
, S
); break;
2209 case AttributeList::AT_address_space
:
2210 case AttributeList::AT_objc_gc
:
2211 case AttributeList::AT_vector_size
:
2212 // Ignore these, these are type attributes, handled by
2213 // ProcessTypeAttributes.
2215 case AttributeList::AT_alias
: HandleAliasAttr (D
, Attr
, S
); break;
2216 case AttributeList::AT_aligned
: HandleAlignedAttr (D
, Attr
, S
); break;
2217 case AttributeList::AT_always_inline
:
2218 HandleAlwaysInlineAttr (D
, Attr
, S
); break;
2219 case AttributeList::AT_analyzer_noreturn
:
2220 HandleAnalyzerNoReturnAttr (D
, Attr
, S
); break;
2221 case AttributeList::AT_annotate
: HandleAnnotateAttr (D
, Attr
, S
); break;
2222 case AttributeList::AT_base_check
: HandleBaseCheckAttr (D
, Attr
, S
); break;
2223 case AttributeList::AT_carries_dependency
:
2224 HandleDependencyAttr (D
, Attr
, S
); break;
2225 case AttributeList::AT_constructor
: HandleConstructorAttr (D
, Attr
, S
); break;
2226 case AttributeList::AT_deprecated
: HandleDeprecatedAttr (D
, Attr
, S
); break;
2227 case AttributeList::AT_destructor
: HandleDestructorAttr (D
, Attr
, S
); break;
2228 case AttributeList::AT_ext_vector_type
:
2229 HandleExtVectorTypeAttr(scope
, D
, Attr
, S
);
2231 case AttributeList::AT_final
: HandleFinalAttr (D
, Attr
, S
); break;
2232 case AttributeList::AT_format
: HandleFormatAttr (D
, Attr
, S
); break;
2233 case AttributeList::AT_format_arg
: HandleFormatArgAttr (D
, Attr
, S
); break;
2234 case AttributeList::AT_gnu_inline
: HandleGNUInlineAttr (D
, Attr
, S
); break;
2235 case AttributeList::AT_hiding
: HandleHidingAttr (D
, Attr
, S
); break;
2236 case AttributeList::AT_mode
: HandleModeAttr (D
, Attr
, S
); break;
2237 case AttributeList::AT_malloc
: HandleMallocAttr (D
, Attr
, S
); break;
2238 case AttributeList::AT_nonnull
: HandleNonNullAttr (D
, Attr
, S
); break;
2239 case AttributeList::AT_ownership_returns
:
2240 case AttributeList::AT_ownership_takes
:
2241 case AttributeList::AT_ownership_holds
:
2242 HandleOwnershipAttr (D
, Attr
, S
); break;
2243 case AttributeList::AT_noreturn
: HandleNoReturnAttr (D
, Attr
, S
); break;
2244 case AttributeList::AT_nothrow
: HandleNothrowAttr (D
, Attr
, S
); break;
2245 case AttributeList::AT_override
: HandleOverrideAttr (D
, Attr
, S
); break;
2246 case AttributeList::AT_vecreturn
: HandleVecReturnAttr (D
, Attr
, S
); break;
2248 // Checker-specific.
2249 case AttributeList::AT_ns_returns_not_retained
:
2250 case AttributeList::AT_cf_returns_not_retained
:
2251 case AttributeList::AT_ns_returns_retained
:
2252 case AttributeList::AT_cf_returns_retained
:
2253 HandleNSReturnsRetainedAttr(D
, Attr
, S
); break;
2255 case AttributeList::AT_reqd_wg_size
:
2256 HandleReqdWorkGroupSize(D
, Attr
, S
); break;
2258 case AttributeList::AT_init_priority
:
2259 HandleInitPriorityAttr(D
, Attr
, S
); break;
2261 case AttributeList::AT_packed
: HandlePackedAttr (D
, Attr
, S
); break;
2262 case AttributeList::AT_section
: HandleSectionAttr (D
, Attr
, S
); break;
2263 case AttributeList::AT_unavailable
: HandleUnavailableAttr (D
, Attr
, S
); break;
2264 case AttributeList::AT_unused
: HandleUnusedAttr (D
, Attr
, S
); break;
2265 case AttributeList::AT_used
: HandleUsedAttr (D
, Attr
, S
); break;
2266 case AttributeList::AT_visibility
: HandleVisibilityAttr (D
, Attr
, S
); break;
2267 case AttributeList::AT_warn_unused_result
: HandleWarnUnusedResult(D
,Attr
,S
);
2269 case AttributeList::AT_weak
: HandleWeakAttr (D
, Attr
, S
); break;
2270 case AttributeList::AT_weakref
: HandleWeakRefAttr (D
, Attr
, S
); break;
2271 case AttributeList::AT_weak_import
: HandleWeakImportAttr (D
, Attr
, S
); break;
2272 case AttributeList::AT_transparent_union
:
2273 HandleTransparentUnionAttr(D
, Attr
, S
);
2275 case AttributeList::AT_objc_exception
:
2276 HandleObjCExceptionAttr(D
, Attr
, S
);
2278 case AttributeList::AT_overloadable
:HandleOverloadableAttr(D
, Attr
, S
); break;
2279 case AttributeList::AT_nsobject
: HandleObjCNSObject (D
, Attr
, S
); break;
2280 case AttributeList::AT_blocks
: HandleBlocksAttr (D
, Attr
, S
); break;
2281 case AttributeList::AT_sentinel
: HandleSentinelAttr (D
, Attr
, S
); break;
2282 case AttributeList::AT_const
: HandleConstAttr (D
, Attr
, S
); break;
2283 case AttributeList::AT_pure
: HandlePureAttr (D
, Attr
, S
); break;
2284 case AttributeList::AT_cleanup
: HandleCleanupAttr (D
, Attr
, S
); break;
2285 case AttributeList::AT_nodebug
: HandleNoDebugAttr (D
, Attr
, S
); break;
2286 case AttributeList::AT_noinline
: HandleNoInlineAttr (D
, Attr
, S
); break;
2287 case AttributeList::AT_regparm
: HandleRegparmAttr (D
, Attr
, S
); break;
2288 case AttributeList::IgnoredAttribute
:
2291 case AttributeList::AT_no_instrument_function
: // Interacts with -pg.
2292 HandleNoInstrumentFunctionAttr(D
, Attr
, S
);
2294 case AttributeList::AT_stdcall
:
2295 case AttributeList::AT_cdecl
:
2296 case AttributeList::AT_fastcall
:
2297 case AttributeList::AT_thiscall
:
2298 HandleCallConvAttr(D
, Attr
, S
);
2301 // Ask target about the attribute.
2302 const TargetAttributesSema
&TargetAttrs
= S
.getTargetAttributesSema();
2303 if (!TargetAttrs
.ProcessDeclAttribute(scope
, D
, Attr
, S
))
2304 S
.Diag(Attr
.getLoc(), diag::warn_unknown_attribute_ignored
)
2310 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
2311 /// attribute list to the specified decl, ignoring any type attributes.
2312 void Sema::ProcessDeclAttributeList(Scope
*S
, Decl
*D
, const AttributeList
*AttrList
) {
2313 for (const AttributeList
* l
= AttrList
; l
; l
= l
->getNext()) {
2314 ProcessDeclAttribute(S
, D
, *l
, *this);
2318 // static int a9 __attribute__((weakref));
2319 // but that looks really pointless. We reject it.
2320 if (D
->hasAttr
<WeakRefAttr
>() && !D
->hasAttr
<AliasAttr
>()) {
2321 Diag(AttrList
->getLoc(), diag::err_attribute_weakref_without_alias
) <<
2322 dyn_cast
<NamedDecl
>(D
)->getNameAsString();
2327 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
2328 /// #pragma weak needs a non-definition decl and source may not have one
2329 NamedDecl
* Sema::DeclClonePragmaWeak(NamedDecl
*ND
, IdentifierInfo
*II
) {
2330 assert(isa
<FunctionDecl
>(ND
) || isa
<VarDecl
>(ND
));
2331 NamedDecl
*NewD
= 0;
2332 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
)) {
2333 NewD
= FunctionDecl::Create(FD
->getASTContext(), FD
->getDeclContext(),
2334 FD
->getLocation(), DeclarationName(II
),
2335 FD
->getType(), FD
->getTypeSourceInfo());
2336 if (FD
->getQualifier()) {
2337 FunctionDecl
*NewFD
= cast
<FunctionDecl
>(NewD
);
2338 NewFD
->setQualifierInfo(FD
->getQualifier(), FD
->getQualifierRange());
2340 } else if (VarDecl
*VD
= dyn_cast
<VarDecl
>(ND
)) {
2341 NewD
= VarDecl::Create(VD
->getASTContext(), VD
->getDeclContext(),
2342 VD
->getLocation(), II
,
2343 VD
->getType(), VD
->getTypeSourceInfo(),
2344 VD
->getStorageClass(),
2345 VD
->getStorageClassAsWritten());
2346 if (VD
->getQualifier()) {
2347 VarDecl
*NewVD
= cast
<VarDecl
>(NewD
);
2348 NewVD
->setQualifierInfo(VD
->getQualifier(), VD
->getQualifierRange());
2354 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
2355 /// applied to it, possibly with an alias.
2356 void Sema::DeclApplyPragmaWeak(Scope
*S
, NamedDecl
*ND
, WeakInfo
&W
) {
2357 if (W
.getUsed()) return; // only do this once
2359 if (W
.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
2360 IdentifierInfo
*NDId
= ND
->getIdentifier();
2361 NamedDecl
*NewD
= DeclClonePragmaWeak(ND
, W
.getAlias());
2362 NewD
->addAttr(::new (Context
) AliasAttr(W
.getLocation(), Context
,
2364 NewD
->addAttr(::new (Context
) WeakAttr(W
.getLocation(), Context
));
2365 WeakTopLevelDecl
.push_back(NewD
);
2366 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
2367 // to insert Decl at TU scope, sorry.
2368 DeclContext
*SavedContext
= CurContext
;
2369 CurContext
= Context
.getTranslationUnitDecl();
2370 PushOnScopeChains(NewD
, S
);
2371 CurContext
= SavedContext
;
2372 } else { // just add weak to existing
2373 ND
->addAttr(::new (Context
) WeakAttr(W
.getLocation(), Context
));
2377 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
2378 /// it, apply them to D. This is a bit tricky because PD can have attributes
2379 /// specified in many different places, and we need to find and apply them all.
2380 void Sema::ProcessDeclAttributes(Scope
*S
, Decl
*D
, const Declarator
&PD
) {
2381 // Handle #pragma weak
2382 if (NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
)) {
2383 if (ND
->hasLinkage()) {
2384 WeakInfo W
= WeakUndeclaredIdentifiers
.lookup(ND
->getIdentifier());
2385 if (W
!= WeakInfo()) {
2386 // Identifier referenced by #pragma weak before it was declared
2387 DeclApplyPragmaWeak(S
, ND
, W
);
2388 WeakUndeclaredIdentifiers
[ND
->getIdentifier()] = W
;
2393 // Apply decl attributes from the DeclSpec if present.
2394 if (const AttributeList
*Attrs
= PD
.getDeclSpec().getAttributes())
2395 ProcessDeclAttributeList(S
, D
, Attrs
);
2397 // Walk the declarator structure, applying decl attributes that were in a type
2398 // position to the decl itself. This handles cases like:
2399 // int *__attr__(x)** D;
2400 // when X is a decl attribute.
2401 for (unsigned i
= 0, e
= PD
.getNumTypeObjects(); i
!= e
; ++i
)
2402 if (const AttributeList
*Attrs
= PD
.getTypeObject(i
).getAttrs())
2403 ProcessDeclAttributeList(S
, D
, Attrs
);
2405 // Finally, apply any attributes on the decl itself.
2406 if (const AttributeList
*Attrs
= PD
.getAttributes())
2407 ProcessDeclAttributeList(S
, D
, Attrs
);
2410 /// PushParsingDeclaration - Enter a new "scope" of deprecation
2413 /// The state token we use is the start index of this scope
2414 /// on the warning stack.
2415 Sema::ParsingDeclStackState
Sema::PushParsingDeclaration() {
2417 return (ParsingDeclStackState
) DelayedDiagnostics
.size();
2420 void Sema::PopParsingDeclaration(ParsingDeclStackState S
, Decl
*D
) {
2421 assert(ParsingDeclDepth
> 0 && "empty ParsingDeclaration stack");
2424 if (DelayedDiagnostics
.empty())
2427 unsigned SavedIndex
= (unsigned) S
;
2428 assert(SavedIndex
<= DelayedDiagnostics
.size() &&
2429 "saved index is out of bounds");
2431 unsigned E
= DelayedDiagnostics
.size();
2433 // We only want to actually emit delayed diagnostics when we
2434 // successfully parsed a decl.
2436 // We really do want to start with 0 here. We get one push for a
2437 // decl spec and another for each declarator; in a decl group like:
2438 // deprecated_typedef foo, *bar, baz();
2439 // only the declarator pops will be passed decls. This is correct;
2440 // we really do need to consider delayed diagnostics from the decl spec
2441 // for each of the different declarations.
2442 for (unsigned I
= 0; I
!= E
; ++I
) {
2443 if (DelayedDiagnostics
[I
].Triggered
)
2446 switch (DelayedDiagnostics
[I
].Kind
) {
2447 case DelayedDiagnostic::Deprecation
:
2448 HandleDelayedDeprecationCheck(DelayedDiagnostics
[I
], D
);
2451 case DelayedDiagnostic::Access
:
2452 HandleDelayedAccessCheck(DelayedDiagnostics
[I
], D
);
2458 // Destroy all the delayed diagnostics we're about to pop off.
2459 for (unsigned I
= SavedIndex
; I
!= E
; ++I
)
2460 DelayedDiagnostics
[I
].destroy();
2462 DelayedDiagnostics
.set_size(SavedIndex
);
2465 static bool isDeclDeprecated(Decl
*D
) {
2467 if (D
->hasAttr
<DeprecatedAttr
>())
2469 } while ((D
= cast_or_null
<Decl
>(D
->getDeclContext())));
2473 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic
&DD
,
2475 if (isDeclDeprecated(Ctx
))
2478 DD
.Triggered
= true;
2479 Diag(DD
.Loc
, diag::warn_deprecated
)
2480 << DD
.DeprecationData
.Decl
->getDeclName();
2483 void Sema::EmitDeprecationWarning(NamedDecl
*D
, SourceLocation Loc
) {
2484 // Delay if we're currently parsing a declaration.
2485 if (ParsingDeclDepth
) {
2486 DelayedDiagnostics
.push_back(DelayedDiagnostic::makeDeprecation(Loc
, D
));
2490 // Otherwise, don't warn if our current context is deprecated.
2491 if (isDeclDeprecated(cast
<Decl
>(CurContext
)))
2494 Diag(Loc
, diag::warn_deprecated
) << D
->getDeclName();