1 //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements decl-related attribute processing.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "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;
26 using namespace sema;
27
28 /// These constants match the enumerated choices of
29 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
30 enum {
31 ExpectedFunction,
32 ExpectedUnion,
33 ExpectedVariableOrFunction,
34 ExpectedFunctionOrMethod,
35 ExpectedParameter,
36 ExpectedParameterOrMethod,
37 ExpectedFunctionMethodOrBlock,
38 ExpectedClassOrVirtualMethod,
39 ExpectedFunctionMethodOrParameter,
40 ExpectedClass,
41 ExpectedVirtualMethod,
42 ExpectedClassMember,
43 ExpectedVariable,
44 ExpectedMethod,
45 ExpectedVariableFunctionOrLabel
46 };
47
48 //===----------------------------------------------------------------------===//
49 // Helper functions
50 //===----------------------------------------------------------------------===//
51
getFunctionType(const Decl * D,bool blocksToo=true)52 static const FunctionType *getFunctionType(const Decl *D,
53 bool blocksToo = true) {
54 QualType Ty;
55 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
56 Ty = decl->getType();
57 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
58 Ty = decl->getType();
59 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
60 Ty = decl->getUnderlyingType();
61 else
62 return 0;
63
64 if (Ty->isFunctionPointerType())
65 Ty = Ty->getAs<PointerType>()->getPointeeType();
66 else if (blocksToo && Ty->isBlockPointerType())
67 Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
68
69 return Ty->getAs<FunctionType>();
70 }
71
72 // FIXME: We should provide an abstraction around a method or function
73 // to provide the following bits of information.
74
75 /// isFunction - Return true if the given decl has function
76 /// type (function or function-typed variable).
isFunction(const Decl * D)77 static bool isFunction(const Decl *D) {
78 return getFunctionType(D, false) != NULL;
79 }
80
81 /// isFunctionOrMethod - Return true if the given decl has function
82 /// type (function or function-typed variable) or an Objective-C
83 /// method.
isFunctionOrMethod(const Decl * D)84 static bool isFunctionOrMethod(const Decl *D) {
85 return isFunction(D)|| isa<ObjCMethodDecl>(D);
86 }
87
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.
isFunctionOrMethodOrBlock(const Decl * D)91 static bool isFunctionOrMethodOrBlock(const Decl *D) {
92 if (isFunctionOrMethod(D))
93 return true;
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();
98 }
99 return isa<BlockDecl>(D);
100 }
101
102 /// Return true if the given decl has a declarator that should have
103 /// been processed by Sema::GetTypeForDeclarator.
hasDeclarator(const Decl * D)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);
108 }
109
110 /// hasFunctionProto - Return true if the given decl has a argument
111 /// information. This decl should have already passed
112 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
hasFunctionProto(const Decl * D)113 static bool hasFunctionProto(const Decl *D) {
114 if (const FunctionType *FnTy = getFunctionType(D))
115 return isa<FunctionProtoType>(FnTy);
116 else {
117 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
118 return true;
119 }
120 }
121
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).
getFunctionOrMethodNumArgs(const Decl * D)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();
131 }
132
getFunctionOrMethodArgType(const Decl * D,unsigned Idx)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();
138
139 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
140 }
141
getFunctionOrMethodResultType(const Decl * D)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();
146 }
147
isFunctionOrMethodVariadic(const Decl * D)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();
154 else {
155 return cast<ObjCMethodDecl>(D)->isVariadic();
156 }
157 }
158
isInstanceMethod(const Decl * D)159 static bool isInstanceMethod(const Decl *D) {
160 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
161 return MethodDecl->isInstance();
162 return false;
163 }
164
isNSStringType(QualType T,ASTContext & Ctx)165 static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
166 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
167 if (!PT)
168 return false;
169
170 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
171 if (!Cls)
172 return false;
173
174 IdentifierInfo* ClsName = Cls->getIdentifier();
175
176 // FIXME: Should we walk the chain of classes?
177 return ClsName == &Ctx.Idents.get("NSString") ||
178 ClsName == &Ctx.Idents.get("NSMutableString");
179 }
180
isCFStringType(QualType T,ASTContext & Ctx)181 static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
182 const PointerType *PT = T->getAs<PointerType>();
183 if (!PT)
184 return false;
185
186 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
187 if (!RT)
188 return false;
189
190 const RecordDecl *RD = RT->getDecl();
191 if (RD->getTagKind() != TTK_Struct)
192 return false;
193
194 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
195 }
196
checkAttributeNumArgs(Sema & S,const AttributeList & Attr,unsigned int Num)197 static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
198 unsigned int Num) {
199 if (Attr.getNumArgs() != Num) {
200 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num;
201 return false;
202 }
203
204 return true;
205 }
206
207 //===----------------------------------------------------------------------===//
208 // Attribute Implementations
209 //===----------------------------------------------------------------------===//
210
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).
214
handleExtVectorTypeAttr(Sema & S,Scope * scope,Decl * D,const AttributeList & Attr)215 static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
216 const AttributeList &Attr) {
217 TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D);
218 if (tDecl == 0) {
219 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
220 return;
221 }
222
223 QualType curType = tDecl->getUnderlyingType();
224
225 Expr *sizeExpr;
226
227 // Special case where the argument is a template id.
228 if (Attr.getParameterName()) {
229 CXXScopeSpec SS;
230 UnqualifiedId id;
231 id.setIdentifier(Attr.getParameterName(), Attr.getLoc());
232
233 ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false);
234 if (Size.isInvalid())
235 return;
236
237 sizeExpr = Size.get();
238 } else {
239 // check the attribute arguments.
240 if (!checkAttributeNumArgs(S, Attr, 1))
241 return;
242
243 sizeExpr = Attr.getArg(0);
244 }
245
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());
249 if (!T.isNull()) {
250 // FIXME: preserve the old source info.
251 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
252
253 // Remember this typedef decl, we will need it later for diagnostics.
254 S.ExtVectorDecls.push_back(tDecl);
255 }
256 }
257
handlePackedAttr(Sema & S,Decl * D,const AttributeList & Attr)258 static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
259 // check the attribute arguments.
260 if (!checkAttributeNumArgs(S, Attr, 0))
261 return;
262
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
267 // has no effect.
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();
272 else
273 FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
274 } else
275 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
276 }
277
handleMsStructAttr(Sema & S,Decl * D,const AttributeList & Attr)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));
281 else
282 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
283 }
284
handleIBAction(Sema & S,Decl * D,const AttributeList & Attr)285 static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
286 // check the attribute arguments.
287 if (!checkAttributeNumArgs(S, Attr, 0))
288 return;
289
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));
294 return;
295 }
296
297 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
298 }
299
handleIBOutlet(Sema & S,Decl * D,const AttributeList & Attr)300 static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
301 // check the attribute arguments.
302 if (!checkAttributeNumArgs(S, Attr, 0))
303 return;
304
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));
309 return;
310 }
311
312 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
313 }
314
handleIBOutletCollection(Sema & S,Decl * D,const AttributeList & Attr)315 static void handleIBOutletCollection(Sema &S, Decl *D,
316 const AttributeList &Attr) {
317
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;
321 return;
322 }
323
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();
328 return;
329 }
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;
334 return;
335 }
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;
340 return;
341 }
342
343 IdentifierInfo *II = Attr.getParameterName();
344 if (!II)
345 II = &S.Context.Idents.get("id");
346
347 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(),
348 S.getScopeForContext(D->getDeclContext()->getParent()));
349 if (!TypeRep) {
350 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
351 return;
352 }
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;
361 return;
362 }
363 D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
364 QT));
365 }
366
possibleTransparentUnionPointerType(QualType & T)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()) {
375 T = QT;
376 return;
377 }
378 }
379 }
380 }
381
handleNonNullAttr(Sema & S,Decl * D,const AttributeList & Attr)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
384 // ignore it as well
385 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
386 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
387 << Attr.getName() << ExpectedFunction;
388 return;
389 }
390
391 // In C++ the implicit 'this' function parameter also counts, and they are
392 // counted from one.
393 bool HasImplicitThisParam = isInstanceMethod(D);
394 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
395
396 // The nonnull attribute only applies to pointers.
397 llvm::SmallVector<unsigned, 10> NonNullArgs;
398
399 for (AttributeList::arg_iterator I=Attr.arg_begin(),
400 E=Attr.arg_end(); I!=E; ++I) {
401
402
403 // The argument must be an integer constant expression.
404 Expr *Ex = *I;
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();
410 return;
411 }
412
413 unsigned x = (unsigned) ArgNum.getZExtValue();
414
415 if (x < 1 || x > NumArgs) {
416 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
417 << "nonnull" << I.getArgNum() << Ex->getSourceRange();
418 return;
419 }
420
421 --x;
422 if (HasImplicitThisParam) {
423 if (x == 0) {
424 S.Diag(Attr.getLoc(),
425 diag::err_attribute_invalid_implicit_this_argument)
426 << "nonnull" << Ex->getSourceRange();
427 return;
428 }
429 --x;
430 }
431
432 // Is the function argument a pointer type?
433 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType();
434 possibleTransparentUnionPointerType(T);
435
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();
440 continue;
441 }
442
443 NonNullArgs.push_back(x);
444 }
445
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);
454 }
455
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);
462 return;
463 }
464 }
465
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,
470 size));
471 }
472
handleOwnershipAttr(Sema & S,Decl * D,const AttributeList & AL)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)).
482
483 if (!AL.getParameterName()) {
484 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
485 << AL.getName()->getName() << 1;
486 return;
487 }
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;
495 return;
496 }
497 break;
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;
502 return;
503 }
504 break;
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;
510 return;
511 }
512 break;
513 default:
514 // This should never happen given how we are called.
515 llvm_unreachable("Unknown ownership attribute");
516 }
517
518 if (!isFunction(D) || !hasFunctionProto(D)) {
519 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
520 << AL.getName() << ExpectedFunction;
521 return;
522 }
523
524 // In C++ the implicit 'this' function parameter also counts, and they are
525 // counted from one.
526 bool HasImplicitThisParam = isInstanceMethod(D);
527 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
528
529 llvm::StringRef Module = AL.getParameterName()->getName();
530
531 // Normalize the argument, __foo__ becomes foo.
532 if (Module.startswith("__") && Module.endswith("__"))
533 Module = Module.substr(2, Module.size() - 4);
534
535 llvm::SmallVector<unsigned, 10> OwnershipArgs;
536
537 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
538 ++I) {
539
540 Expr *IdxExpr = *I;
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();
546 continue;
547 }
548
549 unsigned x = (unsigned) ArgNum.getZExtValue();
550
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();
554 continue;
555 }
556 --x;
557 if (HasImplicitThisParam) {
558 if (x == 0) {
559 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
560 << "ownership" << IdxExpr->getSourceRange();
561 return;
562 }
563 --x;
564 }
565
566 switch (K) {
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")
575 << "pointer"
576 << IdxExpr->getSourceRange();
577 continue;
578 }
579 break;
580 }
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();
591 return;
592 }
593 }
594 break;
595 }
596 default:
597 llvm_unreachable("Unknown ownership attribute");
598 } // switch
599
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>();
604 i != e; ++i) {
605 if ((*i)->getOwnKind() != K) {
606 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
607 I!=E; ++I) {
608 if (x == *I) {
609 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
610 << AL.getName()->getName() << "ownership_*";
611 }
612 }
613 }
614 }
615 OwnershipArgs.push_back(x);
616 }
617
618 unsigned* start = OwnershipArgs.data();
619 unsigned size = OwnershipArgs.size();
620 llvm::array_pod_sort(start, start + size);
621
622 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
623 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
624 return;
625 }
626
627 D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
628 start, size));
629 }
630
631 /// Whether this declaration has internal linkage for the purposes of
632 /// things that want to complain about things not have internal linkage.
hasEffectivelyInternalLinkage(NamedDecl * D)633 static bool hasEffectivelyInternalLinkage(NamedDecl *D) {
634 switch (D->getLinkage()) {
635 case NoLinkage:
636 case InternalLinkage:
637 return true;
638
639 // Template instantiations that go from external to unique-external
640 // shouldn't get diagnosed.
641 case UniqueExternalLinkage:
642 return true;
643
644 case ExternalLinkage:
645 return false;
646 }
647 llvm_unreachable("unknown linkage kind!");
648 return false;
649 }
650
handleWeakRefAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
655 return;
656 }
657
658 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
659 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
660 << Attr.getName() << ExpectedVariableOrFunction;
661 return;
662 }
663
664 NamedDecl *nd = cast<NamedDecl>(D);
665
666 // gcc rejects
667 // class c {
668 // static int a __attribute__((weakref ("v2")));
669 // static int b() __attribute__((weakref ("f3")));
670 // };
671 // and ignores the attributes of
672 // void f(void) {
673 // static int a __attribute__((weakref ("v2")));
674 // }
675 // we reject them
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();
680 return;
681 }
682
683 // The GCC manual says
684 //
685 // At present, a declaration to which `weakref' is attached can only
686 // be `static'.
687 //
688 // It also says
689 //
690 // Without a TARGET,
691 // given as an argument to `weakref' or to `alias', `weakref' is
692 // equivalent to `weak'.
693 //
694 // gcc 4.4.1 will accept
695 // int a7 __attribute__((weakref));
696 // as
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.
700
701 if (!hasEffectivelyInternalLinkage(nd)) {
702 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static);
703 return;
704 }
705
706 // GCC rejects
707 // static ((alias ("y"), weakref)).
708 // Should we? How to check that weakref is before or after alias?
709
710 if (Attr.getNumArgs() == 1) {
711 Expr *Arg = Attr.getArg(0);
712 Arg = Arg->IgnoreParenCasts();
713 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
714
715 if (Str == 0 || Str->isWide()) {
716 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
717 << "weakref" << 1;
718 return;
719 }
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,
723 Str->getString()));
724 }
725
726 D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
727 }
728
handleAliasAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
733 return;
734 }
735
736 Expr *Arg = Attr.getArg(0);
737 Arg = Arg->IgnoreParenCasts();
738 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
739
740 if (Str == 0 || Str->isWide()) {
741 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
742 << "alias" << 1;
743 return;
744 }
745
746 if (S.Context.Target.getTriple().isOSDarwin()) {
747 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
748 return;
749 }
750
751 // FIXME: check if target symbol exists in current file
752
753 D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context,
754 Str->getString()));
755 }
756
handleNakedAttr(Sema & S,Decl * D,const AttributeList & Attr)757 static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
758 // Check the attribute arguments.
759 if (!checkAttributeNumArgs(S, Attr, 0))
760 return;
761
762 if (!isa<FunctionDecl>(D)) {
763 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
764 << Attr.getName() << ExpectedFunction;
765 return;
766 }
767
768 D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context));
769 }
770
handleAlwaysInlineAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
776 return;
777 }
778
779 if (!isa<FunctionDecl>(D)) {
780 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
781 << Attr.getName() << ExpectedFunction;
782 return;
783 }
784
785 D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
786 }
787
handleMallocAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
792 return;
793 }
794
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));
799 return;
800 }
801 }
802
803 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
804 }
805
handleMayAliasAttr(Sema & S,Decl * D,const AttributeList & Attr)806 static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
807 // check the attribute arguments.
808 if (!checkAttributeNumArgs(S, Attr, 0))
809 return;
810
811 D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context));
812 }
813
handleNoCommonAttr(Sema & S,Decl * D,const AttributeList & Attr)814 static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
815 assert(!Attr.isInvalid());
816 if (isa<VarDecl>(D))
817 D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context));
818 else
819 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
820 << Attr.getName() << ExpectedVariable;
821 }
822
handleCommonAttr(Sema & S,Decl * D,const AttributeList & Attr)823 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
824 assert(!Attr.isInvalid());
825 if (isa<VarDecl>(D))
826 D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context));
827 else
828 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
829 << Attr.getName() << ExpectedVariable;
830 }
831
handleNoReturnAttr(Sema & S,Decl * D,const AttributeList & attr)832 static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
833 if (hasDeclarator(D)) return;
834
835 if (S.CheckNoReturnAttr(attr)) return;
836
837 if (!isa<ObjCMethodDecl>(D)) {
838 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
839 << attr.getName() << ExpectedFunctionOrMethod;
840 return;
841 }
842
843 D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context));
844 }
845
CheckNoReturnAttr(const AttributeList & attr)846 bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
847 if (attr.hasParameterOrArguments()) {
848 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
849 attr.setInvalid();
850 return true;
851 }
852
853 return false;
854 }
855
handleAnalyzerNoReturnAttr(Sema & S,Decl * D,const AttributeList & Attr)856 static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
857 const AttributeList &Attr) {
858
859 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
860 // because 'analyzer_noreturn' does not impact the type.
861
862 if(!checkAttributeNumArgs(S, Attr, 0))
863 return;
864
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;
873 return;
874 }
875 }
876
877 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
878 }
879
880 // PS3 PPU-specific.
handleVecReturnAttr(Sema & S,Decl * D,const AttributeList & Attr)881 static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
882 /*
883 Returning a Vector Class in Registers
884
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.
890
891 Example:
892
893 struct Vector
894 {
895 __vector float xyzw;
896 } __attribute__((vecreturn));
897
898 Vector Add(Vector lhs, Vector rhs)
899 {
900 Vector result;
901 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
902 return result; // This will be returned in a register
903 }
904 */
905 if (!isa<RecordDecl>(D)) {
906 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
907 << Attr.getName() << ExpectedClass;
908 return;
909 }
910
911 if (D->getAttr<VecReturnAttr>()) {
912 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
913 return;
914 }
915
916 RecordDecl *record = cast<RecordDecl>(D);
917 int count = 0;
918
919 if (!isa<CXXRecordDecl>(record)) {
920 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
921 return;
922 }
923
924 if (!cast<CXXRecordDecl>(record)->isPOD()) {
925 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
926 return;
927 }
928
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);
933 return;
934 }
935 count++;
936 }
937
938 D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
939 }
940
handleDependencyAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
945 return;
946 }
947 // FIXME: Actually store the attribute on the declaration
948 }
949
handleUnusedAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
954 return;
955 }
956
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;
961 return;
962 }
963
964 D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
965 }
966
handleUsedAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
971 return;
972 }
973
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";
977 return;
978 }
979 } else if (!isFunctionOrMethod(D)) {
980 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
981 << Attr.getName() << ExpectedVariableOrFunction;
982 return;
983 }
984
985 D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
986 }
987
handleConstructorAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
992 return;
993 }
994
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();
1003 return;
1004 }
1005 priority = Idx.getZExtValue();
1006 }
1007
1008 if (!isa<FunctionDecl>(D)) {
1009 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1010 << Attr.getName() << ExpectedFunction;
1011 return;
1012 }
1013
1014 D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context,
1015 priority));
1016 }
1017
handleDestructorAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1022 return;
1023 }
1024
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();
1033 return;
1034 }
1035 priority = Idx.getZExtValue();
1036 }
1037
1038 if (!isa<FunctionDecl>(D)) {
1039 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1040 << Attr.getName() << ExpectedFunction;
1041 return;
1042 }
1043
1044 D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context,
1045 priority));
1046 }
1047
handleDeprecatedAttr(Sema & S,Decl * D,const AttributeList & Attr)1048 static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1049 unsigned NumArgs = Attr.getNumArgs();
1050 if (NumArgs > 1) {
1051 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1052 return;
1053 }
1054
1055 // Handle the case where deprecated attribute has a text message.
1056 llvm::StringRef Str;
1057 if (NumArgs == 1) {
1058 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1059 if (!SE) {
1060 S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string)
1061 << "deprecated";
1062 return;
1063 }
1064 Str = SE->getString();
1065 }
1066
1067 D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str));
1068 }
1069
handleUnavailableAttr(Sema & S,Decl * D,const AttributeList & Attr)1070 static void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1071 unsigned NumArgs = Attr.getNumArgs();
1072 if (NumArgs > 1) {
1073 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1074 return;
1075 }
1076
1077 // Handle the case where unavailable attribute has a text message.
1078 llvm::StringRef Str;
1079 if (NumArgs == 1) {
1080 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0));
1081 if (!SE) {
1082 S.Diag(Attr.getArg(0)->getLocStart(),
1083 diag::err_attribute_not_string) << "unavailable";
1084 return;
1085 }
1086 Str = SE->getString();
1087 }
1088 D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str));
1089 }
1090
handleArcWeakrefUnavailableAttr(Sema & S,Decl * D,const AttributeList & Attr)1091 static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
1092 const AttributeList &Attr) {
1093 unsigned NumArgs = Attr.getNumArgs();
1094 if (NumArgs > 0) {
1095 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0;
1096 return;
1097 }
1098
1099 D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
1100 Attr.getLoc(), S.Context));
1101 }
1102
handleAvailabilityAttr(Sema & S,Decl * D,const AttributeList & Attr)1103 static void handleAvailabilityAttr(Sema &S, Decl *D,
1104 const AttributeList &Attr) {
1105 IdentifierInfo *Platform = Attr.getParameterName();
1106 SourceLocation PlatformLoc = Attr.getParameterLoc();
1107
1108 llvm::StringRef PlatformName
1109 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
1110 if (PlatformName.empty()) {
1111 S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
1112 << Platform;
1113
1114 PlatformName = Platform->getName();
1115 }
1116
1117 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
1118 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
1119 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
1120 bool IsUnavailable = Attr.getUnavailableLoc().isValid();
1121
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();
1129 return;
1130 }
1131
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();
1137 return;
1138 }
1139
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();
1145 return;
1146 }
1147
1148 D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context,
1149 Platform,
1150 Introduced.Version,
1151 Deprecated.Version,
1152 Obsoleted.Version,
1153 IsUnavailable));
1154 }
1155
handleVisibilityAttr(Sema & S,Decl * D,const AttributeList & Attr)1156 static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1157 // check the attribute arguments.
1158 if(!checkAttributeNumArgs(S, Attr, 1))
1159 return;
1160
1161 Expr *Arg = Attr.getArg(0);
1162 Arg = Arg->IgnoreParenCasts();
1163 StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
1164
1165 if (Str == 0 || Str->isWide()) {
1166 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1167 << "visibility" << 1;
1168 return;
1169 }
1170
1171 llvm::StringRef TypeStr = Str->getString();
1172 VisibilityAttr::VisibilityType type;
1173
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;
1182 else {
1183 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
1184 return;
1185 }
1186
1187 D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
1188 }
1189
handleObjCMethodFamilyAttr(Sema & S,Decl * decl,const AttributeList & Attr)1190 static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
1191 const AttributeList &Attr) {
1192 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
1193 if (!method) {
1194 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1195 << ExpectedMethod;
1196 return;
1197 }
1198
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;
1203 } else {
1204 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1205 }
1206 Attr.setInvalid();
1207 return;
1208 }
1209
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;
1224 else {
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);
1228 return;
1229 }
1230
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.
1236 return;
1237 }
1238
1239 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(),
1240 S.Context, family));
1241 }
1242
handleObjCExceptionAttr(Sema & S,Decl * D,const AttributeList & Attr)1243 static void handleObjCExceptionAttr(Sema &S, Decl *D,
1244 const AttributeList &Attr) {
1245 if (!checkAttributeNumArgs(S, Attr, 0))
1246 return;
1247
1248 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
1249 if (OCI == 0) {
1250 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
1251 return;
1252 }
1253
1254 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
1255 }
1256
handleObjCNSObject(Sema & S,Decl * D,const AttributeList & Attr)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;
1260 return;
1261 }
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);
1267 return;
1268 }
1269 }
1270 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
1271 }
1272
1273 static void
handleOverloadableAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1277 return;
1278 }
1279
1280 if (!isa<FunctionDecl>(D)) {
1281 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
1282 return;
1283 }
1284
1285 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
1286 }
1287
handleBlocksAttr(Sema & S,Decl * D,const AttributeList & Attr)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)
1291 << "blocks" << 1;
1292 return;
1293 }
1294
1295 if (Attr.getNumArgs() != 0) {
1296 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1297 return;
1298 }
1299
1300 BlocksAttr::BlockType type;
1301 if (Attr.getParameterName()->isStr("byref"))
1302 type = BlocksAttr::ByRef;
1303 else {
1304 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1305 << "blocks" << Attr.getParameterName();
1306 return;
1307 }
1308
1309 D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
1310 }
1311
handleSentinelAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1316 return;
1317 }
1318
1319 int sentinel = 0;
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();
1327 return;
1328 }
1329 sentinel = Idx.getZExtValue();
1330
1331 if (sentinel < 0) {
1332 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
1333 << E->getSourceRange();
1334 return;
1335 }
1336 }
1337
1338 int nullPos = 0;
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();
1346 return;
1347 }
1348 nullPos = Idx.getZExtValue();
1349
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();
1355 return;
1356 }
1357 }
1358
1359 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1360 const FunctionType *FT = FD->getType()->getAs<FunctionType>();
1361 assert(FT && "FunctionDecl has non-function type?");
1362
1363 if (isa<FunctionNoProtoType>(FT)) {
1364 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
1365 return;
1366 }
1367
1368 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
1369 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
1370 return;
1371 }
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;
1375 return;
1376 }
1377 } else if (isa<BlockDecl>(D)) {
1378 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the
1379 // caller.
1380 ;
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;
1389 return;
1390 }
1391 } else {
1392 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1393 << Attr.getName() << ExpectedFunctionMethodOrBlock;
1394 return;
1395 }
1396 } else {
1397 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1398 << Attr.getName() << ExpectedFunctionMethodOrBlock;
1399 return;
1400 }
1401 D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel,
1402 nullPos));
1403 }
1404
handleWarnUnusedResult(Sema & S,Decl * D,const AttributeList & Attr)1405 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
1406 // check the attribute arguments.
1407 if (!checkAttributeNumArgs(S, Attr, 0))
1408 return;
1409
1410 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) {
1411 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1412 << Attr.getName() << ExpectedFunctionOrMethod;
1413 return;
1414 }
1415
1416 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
1417 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
1418 << Attr.getName() << 0;
1419 return;
1420 }
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;
1425 return;
1426 }
1427
1428 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
1429 }
1430
handleWeakAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1435 return;
1436 }
1437
1438 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1439 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1440 << Attr.getName() << ExpectedVariableOrFunction;
1441 return;
1442 }
1443
1444 NamedDecl *nd = cast<NamedDecl>(D);
1445
1446 // 'weak' only applies to declarations with external linkage.
1447 if (hasEffectivelyInternalLinkage(nd)) {
1448 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static);
1449 return;
1450 }
1451
1452 nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
1453 }
1454
handleWeakImportAttr(Sema & S,Decl * D,const AttributeList & Attr)1455 static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1456 // check the attribute arguments.
1457 if (!checkAttributeNumArgs(S, Attr, 0))
1458 return;
1459
1460
1461 // weak_import only applies to variable & function declarations.
1462 bool isDef = false;
1463 if (!D->canBeWeakImported(isDef)) {
1464 if (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.
1472 } else
1473 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1474 << Attr.getName() << ExpectedVariableOrFunction;
1475
1476 return;
1477 }
1478
1479 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
1480 }
1481
handleReqdWorkGroupSize(Sema & S,Decl * D,const AttributeList & Attr)1482 static void handleReqdWorkGroupSize(Sema &S, Decl *D,
1483 const AttributeList &Attr) {
1484 // Attribute has 3 arguments.
1485 if (!checkAttributeNumArgs(S, Attr, 3))
1486 return;
1487
1488 unsigned WGSize[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();
1496 return;
1497 }
1498 WGSize[i] = (unsigned) ArgNum.getZExtValue();
1499 }
1500 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
1501 WGSize[0], WGSize[1],
1502 WGSize[2]));
1503 }
1504
handleSectionAttr(Sema & S,Decl * D,const AttributeList & Attr)1505 static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1506 // Attribute has no arguments.
1507 if (!checkAttributeNumArgs(S, Attr, 1))
1508 return;
1509
1510 // Make sure that there is a string literal as the sections's single
1511 // argument.
1512 Expr *ArgExpr = Attr.getArg(0);
1513 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
1514 if (!SE) {
1515 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section";
1516 return;
1517 }
1518
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)
1523 << Error;
1524 return;
1525 }
1526
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);
1530 return;
1531 }
1532
1533 D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context,
1534 SE->getString()));
1535 }
1536
1537
handleNothrowAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1542 return;
1543 }
1544
1545 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
1546 if (Existing->getLocation().isInvalid())
1547 Existing->setLocation(Attr.getLoc());
1548 } else {
1549 D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
1550 }
1551 }
1552
handleConstAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1557 return;
1558 }
1559
1560 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
1561 if (Existing->getLocation().isInvalid())
1562 Existing->setLocation(Attr.getLoc());
1563 } else {
1564 D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
1565 }
1566 }
1567
handlePureAttr(Sema & S,Decl * D,const AttributeList & Attr)1568 static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1569 // check the attribute arguments.
1570 if (!checkAttributeNumArgs(S, Attr, 0))
1571 return;
1572
1573 D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
1574 }
1575
handleCleanupAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
1579 return;
1580 }
1581
1582 if (Attr.getNumArgs() != 0) {
1583 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1584 return;
1585 }
1586
1587 VarDecl *VD = dyn_cast<VarDecl>(D);
1588
1589 if (!VD || !VD->hasLocalStorage()) {
1590 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1591 return;
1592 }
1593
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);
1599 if (!CleanupDecl) {
1600 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1601 Attr.getParameterName();
1602 return;
1603 }
1604
1605 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1606 if (!FD) {
1607 S.Diag(Attr.getParameterLoc(),
1608 diag::err_attribute_cleanup_arg_not_function)
1609 << Attr.getParameterName();
1610 return;
1611 }
1612
1613 if (FD->getNumParams() != 1) {
1614 S.Diag(Attr.getParameterLoc(),
1615 diag::err_attribute_cleanup_func_must_take_one_arg)
1616 << Attr.getParameterName();
1617 return;
1618 }
1619
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;
1629 return;
1630 }
1631
1632 D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
1633 S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD);
1634 }
1635
1636 /// Handle __attribute__((format_arg((idx)))) attribute based on
1637 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
handleFormatArgAttr(Sema & S,Decl * D,const AttributeList & Attr)1638 static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1639 if (!checkAttributeNumArgs(S, Attr, 1))
1640 return;
1641
1642 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
1643 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1644 << Attr.getName() << ExpectedFunction;
1645 return;
1646 }
1647
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;
1653
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();
1661 return;
1662 }
1663
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();
1667 return;
1668 }
1669
1670 unsigned ArgIdx = Idx.getZExtValue() - 1;
1671
1672 if (HasImplicitThisParam) {
1673 if (ArgIdx == 0) {
1674 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument)
1675 << "format_arg" << IdxExpr->getSourceRange();
1676 return;
1677 }
1678 ArgIdx--;
1679 }
1680
1681 // make sure the format string is really a string
1682 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1683
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();
1693 return;
1694 }
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();
1704 return;
1705 }
1706
1707 D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context,
1708 Idx.getZExtValue()));
1709 }
1710
1711 enum FormatAttrKind {
1712 CFStringFormat,
1713 NSStringFormat,
1714 StrftimeFormat,
1715 SupportedFormat,
1716 IgnoredFormat,
1717 InvalidFormat
1718 };
1719
1720 /// getFormatAttrKind - Map from format attribute names to supported format
1721 /// types.
getFormatAttrKind(llvm::StringRef 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;
1730
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;
1738
1739 if (Format == "gcc_diag" || Format == "gcc_cdiag" ||
1740 Format == "gcc_cxxdiag" || Format == "gcc_tdiag")
1741 return IgnoredFormat;
1742
1743 return InvalidFormat;
1744 }
1745
1746 /// Handle __attribute__((init_priority(priority))) attributes based on
1747 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
handleInitPriorityAttr(Sema & S,Decl * D,const AttributeList & Attr)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();
1752 return;
1753 }
1754
1755 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
1756 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
1757 Attr.setInvalid();
1758 return;
1759 }
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);
1765 Attr.setInvalid();
1766 return;
1767 }
1768
1769 if (Attr.getNumArgs() != 1) {
1770 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1771 Attr.setInvalid();
1772 return;
1773 }
1774 Expr *priorityExpr = Attr.getArg(0);
1775
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();
1781 Attr.setInvalid();
1782 return;
1783 }
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();
1788 Attr.setInvalid();
1789 return;
1790 }
1791 D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context,
1792 prioritynum));
1793 }
1794
1795 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
1796 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
handleFormatAttr(Sema & S,Decl * D,const AttributeList & Attr)1797 static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1798
1799 if (!Attr.getParameterName()) {
1800 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
1801 << "format" << 1;
1802 return;
1803 }
1804
1805 if (Attr.getNumArgs() != 2) {
1806 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
1807 return;
1808 }
1809
1810 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
1811 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1812 << Attr.getName() << ExpectedFunction;
1813 return;
1814 }
1815
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;
1821
1822 llvm::StringRef Format = Attr.getParameterName()->getName();
1823
1824 // Normalize the argument, __foo__ becomes foo.
1825 if (Format.startswith("__") && Format.endswith("__"))
1826 Format = Format.substr(2, Format.size() - 4);
1827
1828 // Check for supported formats.
1829 FormatAttrKind Kind = getFormatAttrKind(Format);
1830
1831 if (Kind == IgnoredFormat)
1832 return;
1833
1834 if (Kind == InvalidFormat) {
1835 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1836 << "format" << Attr.getParameterName()->getName();
1837 return;
1838 }
1839
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();
1847 return;
1848 }
1849
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();
1853 return;
1854 }
1855
1856 // FIXME: Do we need to bounds check?
1857 unsigned ArgIdx = Idx.getZExtValue() - 1;
1858
1859 if (HasImplicitThisParam) {
1860 if (ArgIdx == 0) {
1861 S.Diag(Attr.getLoc(),
1862 diag::err_format_attribute_implicit_this_format_string)
1863 << IdxExpr->getSourceRange();
1864 return;
1865 }
1866 ArgIdx--;
1867 }
1868
1869 // make sure the format string is really a string
1870 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
1871
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();
1876 return;
1877 }
1878 } else if (Kind == NSStringFormat) {
1879 // FIXME: do we need to check if the type is NSString*? What are the
1880 // semantics?
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();
1885 return;
1886 }
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();
1892 return;
1893 }
1894
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();
1902 return;
1903 }
1904
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 ...
1909 } else {
1910 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
1911 return;
1912 }
1913 }
1914
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();
1921 return;
1922 }
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();
1927 return;
1928 }
1929
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>();
1934 i != e ; ++i) {
1935 FormatAttr *f = *i;
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
1940 // location.
1941 if (f->getLocation().isInvalid())
1942 f->setLocation(Attr.getLoc());
1943 return;
1944 }
1945 }
1946
1947 D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
1948 Idx.getZExtValue(),
1949 FirstArg.getZExtValue()));
1950 }
1951
handleTransparentUnionAttr(Sema & S,Decl * D,const AttributeList & Attr)1952 static void handleTransparentUnionAttr(Sema &S, Decl *D,
1953 const AttributeList &Attr) {
1954 // check the attribute arguments.
1955 if (!checkAttributeNumArgs(S, Attr, 0))
1956 return;
1957
1958
1959 // Try to find the underlying union declaration.
1960 RecordDecl *RD = 0;
1961 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
1962 if (TD && TD->getUnderlyingType()->isUnionType())
1963 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1964 else
1965 RD = dyn_cast<RecordDecl>(D);
1966
1967 if (!RD || !RD->isUnion()) {
1968 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1969 << Attr.getName() << ExpectedUnion;
1970 return;
1971 }
1972
1973 if (!RD->isDefinition()) {
1974 S.Diag(Attr.getLoc(),
1975 diag::warn_transparent_union_attribute_not_definition);
1976 return;
1977 }
1978
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);
1983 return;
1984 }
1985
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;
1992 return;
1993 }
1994
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;
2012 return;
2013 }
2014 }
2015
2016 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
2017 }
2018
handleAnnotateAttr(Sema & S,Decl * D,const AttributeList & Attr)2019 static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2020 // check the attribute arguments.
2021 if (!checkAttributeNumArgs(S, Attr, 1))
2022 return;
2023
2024 Expr *ArgExpr = Attr.getArg(0);
2025 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr);
2026
2027 // Make sure that there is a string literal as the annotation's single
2028 // argument.
2029 if (!SE) {
2030 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
2031 return;
2032 }
2033 D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context,
2034 SE->getString()));
2035 }
2036
handleAlignedAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
2041 return;
2042 }
2043
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.
2047
2048 if (Attr.getNumArgs() == 0) {
2049 D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
2050 return;
2051 }
2052
2053 S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0));
2054 }
2055
AddAlignedAttr(SourceLocation AttrLoc,Decl * D,Expr * E)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));
2060 return;
2061 }
2062
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();
2068 return;
2069 }
2070 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
2071 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
2072 << E->getSourceRange();
2073 return;
2074 }
2075
2076 D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
2077 }
2078
AddAlignedAttr(SourceLocation AttrLoc,Decl * D,TypeSourceInfo * TS)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));
2083 return;
2084 }
2085
2086 /// handleModeAttr - This attribute modifies the width of a decl with primitive
2087 /// type.
2088 ///
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.
handleModeAttr(Sema & S,Decl * D,const AttributeList & Attr)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.
2095
2096 // Check that there aren't any arguments
2097 if (!checkAttributeNumArgs(S, Attr, 0))
2098 return;
2099
2100
2101 IdentifierInfo *Name = Attr.getParameterName();
2102 if (!Name) {
2103 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
2104 return;
2105 }
2106
2107 llvm::StringRef Str = Attr.getParameterName()->getName();
2108
2109 // Normalize the attribute name, __foo__ becomes foo.
2110 if (Str.startswith("__") && Str.endswith("__"))
2111 Str = Str.substr(2, Str.size() - 4);
2112
2113 unsigned DestWidth = 0;
2114 bool IntegerMode = true;
2115 bool ComplexMode = false;
2116 switch (Str.size()) {
2117 case 2:
2118 switch (Str[0]) {
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;
2125 }
2126 if (Str[1] == 'F') {
2127 IntegerMode = false;
2128 } else if (Str[1] == 'C') {
2129 IntegerMode = false;
2130 ComplexMode = true;
2131 } else if (Str[1] != 'I') {
2132 DestWidth = 0;
2133 }
2134 break;
2135 case 4:
2136 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
2137 // pointer on PIC16 and other embedded platforms.
2138 if (Str == "word")
2139 DestWidth = S.Context.Target.getPointerWidth(0);
2140 else if (Str == "byte")
2141 DestWidth = S.Context.Target.getCharWidth();
2142 break;
2143 case 7:
2144 if (Str == "pointer")
2145 DestWidth = S.Context.Target.getPointerWidth(0);
2146 break;
2147 }
2148
2149 QualType OldTy;
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();
2154 else {
2155 S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
2156 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
2157 return;
2158 }
2159
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);
2168 } else {
2169 if (!OldTy->isFloatingType())
2170 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
2171 }
2172
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
2179 QualType NewTy;
2180 switch (DestWidth) {
2181 case 0:
2182 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
2183 return;
2184 default:
2185 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2186 return;
2187 case 8:
2188 if (!IntegerMode) {
2189 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2190 return;
2191 }
2192 if (OldTy->isSignedIntegerType())
2193 NewTy = S.Context.SignedCharTy;
2194 else
2195 NewTy = S.Context.UnsignedCharTy;
2196 break;
2197 case 16:
2198 if (!IntegerMode) {
2199 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2200 return;
2201 }
2202 if (OldTy->isSignedIntegerType())
2203 NewTy = S.Context.ShortTy;
2204 else
2205 NewTy = S.Context.UnsignedShortTy;
2206 break;
2207 case 32:
2208 if (!IntegerMode)
2209 NewTy = S.Context.FloatTy;
2210 else if (OldTy->isSignedIntegerType())
2211 NewTy = S.Context.IntTy;
2212 else
2213 NewTy = S.Context.UnsignedIntTy;
2214 break;
2215 case 64:
2216 if (!IntegerMode)
2217 NewTy = S.Context.DoubleTy;
2218 else if (OldTy->isSignedIntegerType())
2219 if (S.Context.Target.getLongWidth() == 64)
2220 NewTy = S.Context.LongTy;
2221 else
2222 NewTy = S.Context.LongLongTy;
2223 else
2224 if (S.Context.Target.getLongWidth() == 64)
2225 NewTy = S.Context.UnsignedLongTy;
2226 else
2227 NewTy = S.Context.UnsignedLongLongTy;
2228 break;
2229 case 96:
2230 NewTy = S.Context.LongDoubleTy;
2231 break;
2232 case 128:
2233 if (!IntegerMode) {
2234 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
2235 return;
2236 }
2237 if (OldTy->isSignedIntegerType())
2238 NewTy = S.Context.Int128Ty;
2239 else
2240 NewTy = S.Context.UnsignedInt128Ty;
2241 break;
2242 }
2243
2244 if (ComplexMode) {
2245 NewTy = S.Context.getComplexType(NewTy);
2246 }
2247
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));
2252 } else
2253 cast<ValueDecl>(D)->setType(NewTy);
2254 }
2255
handleNoDebugAttr(Sema & S,Decl * D,const AttributeList & Attr)2256 static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2257 // check the attribute arguments.
2258 if (!checkAttributeNumArgs(S, Attr, 0))
2259 return;
2260
2261 if (!isFunctionOrMethod(D)) {
2262 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2263 << Attr.getName() << ExpectedFunction;
2264 return;
2265 }
2266
2267 D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
2268 }
2269
handleNoInlineAttr(Sema & S,Decl * D,const AttributeList & Attr)2270 static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2271 // check the attribute arguments.
2272 if (!checkAttributeNumArgs(S, Attr, 0))
2273 return;
2274
2275
2276 if (!isa<FunctionDecl>(D)) {
2277 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2278 << Attr.getName() << ExpectedFunction;
2279 return;
2280 }
2281
2282 D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
2283 }
2284
handleNoInstrumentFunctionAttr(Sema & S,Decl * D,const AttributeList & Attr)2285 static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
2286 const AttributeList &Attr) {
2287 // check the attribute arguments.
2288 if (!checkAttributeNumArgs(S, Attr, 0))
2289 return;
2290
2291
2292 if (!isa<FunctionDecl>(D)) {
2293 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2294 << Attr.getName() << ExpectedFunction;
2295 return;
2296 }
2297
2298 D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(),
2299 S.Context));
2300 }
2301
handleConstantAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
2307 return;
2308 }
2309
2310 if (!isa<VarDecl>(D)) {
2311 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2312 << Attr.getName() << ExpectedVariable;
2313 return;
2314 }
2315
2316 D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context));
2317 } else {
2318 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
2319 }
2320 }
2321
handleDeviceAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
2327 return;
2328 }
2329
2330 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
2331 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2332 << Attr.getName() << ExpectedVariableOrFunction;
2333 return;
2334 }
2335
2336 D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context));
2337 } else {
2338 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
2339 }
2340 }
2341
handleGlobalAttr(Sema & S,Decl * D,const AttributeList & Attr)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))
2346 return;
2347
2348 if (!isa<FunctionDecl>(D)) {
2349 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2350 << Attr.getName() << ExpectedFunction;
2351 return;
2352 }
2353
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)
2359 << FD->getType()
2360 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(),
2361 "void");
2362 } else {
2363 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
2364 << FD->getType();
2365 }
2366 return;
2367 }
2368
2369 D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context));
2370 } else {
2371 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
2372 }
2373 }
2374
handleHostAttr(Sema & S,Decl * D,const AttributeList & Attr)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))
2379 return;
2380
2381
2382 if (!isa<FunctionDecl>(D)) {
2383 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2384 << Attr.getName() << ExpectedFunction;
2385 return;
2386 }
2387
2388 D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context));
2389 } else {
2390 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
2391 }
2392 }
2393
handleSharedAttr(Sema & S,Decl * D,const AttributeList & Attr)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))
2398 return;
2399
2400
2401 if (!isa<VarDecl>(D)) {
2402 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2403 << Attr.getName() << ExpectedVariable;
2404 return;
2405 }
2406
2407 D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context));
2408 } else {
2409 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
2410 }
2411 }
2412
handleGNUInlineAttr(Sema & S,Decl * D,const AttributeList & Attr)2413 static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2414 // check the attribute arguments.
2415 if (!checkAttributeNumArgs(S, Attr, 0))
2416 return;
2417
2418 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
2419 if (Fn == 0) {
2420 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2421 << Attr.getName() << ExpectedFunction;
2422 return;
2423 }
2424
2425 if (!Fn->isInlineSpecified()) {
2426 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
2427 return;
2428 }
2429
2430 D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
2431 }
2432
handleCallConvAttr(Sema & S,Decl * D,const AttributeList & Attr)2433 static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2434 if (hasDeclarator(D)) return;
2435
2436 // Diagnostic is emitted elsewhere: here we store the (valid) Attr
2437 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
2438 CallingConv CC;
2439 if (S.CheckCallingConvAttr(Attr, CC))
2440 return;
2441
2442 if (!isa<ObjCMethodDecl>(D)) {
2443 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2444 << Attr.getName() << ExpectedFunctionOrMethod;
2445 return;
2446 }
2447
2448 switch (Attr.getKind()) {
2449 case AttributeList::AT_fastcall:
2450 D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
2451 return;
2452 case AttributeList::AT_stdcall:
2453 D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
2454 return;
2455 case AttributeList::AT_thiscall:
2456 D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
2457 return;
2458 case AttributeList::AT_cdecl:
2459 D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
2460 return;
2461 case AttributeList::AT_pascal:
2462 D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
2463 return;
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)
2469 << "pcs" << 1;
2470 Attr.setInvalid();
2471 return;
2472 }
2473
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;
2480 else {
2481 S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
2482 Attr.setInvalid();
2483 return;
2484 }
2485
2486 D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS));
2487 }
2488 default:
2489 llvm_unreachable("unexpected attribute kind");
2490 return;
2491 }
2492 }
2493
handleOpenCLKernelAttr(Sema & S,Decl * D,const AttributeList & Attr)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));
2497 }
2498
CheckCallingConvAttr(const AttributeList & attr,CallingConv & CC)2499 bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) {
2500 if (attr.isInvalid())
2501 return true;
2502
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;
2507 attr.setInvalid();
2508 return true;
2509 }
2510
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)
2524 << "pcs" << 1;
2525 attr.setInvalid();
2526 return true;
2527 }
2528
2529 llvm::StringRef StrRef = Str->getString();
2530 if (StrRef == "aapcs") {
2531 CC = CC_AAPCS;
2532 break;
2533 } else if (StrRef == "aapcs-vfp") {
2534 CC = CC_AAPCS_VFP;
2535 break;
2536 }
2537 // FALLS THROUGH
2538 }
2539 default: llvm_unreachable("unexpected attribute kind"); return true;
2540 }
2541
2542 return false;
2543 }
2544
handleRegparmAttr(Sema & S,Decl * D,const AttributeList & Attr)2545 static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2546 if (hasDeclarator(D)) return;
2547
2548 unsigned numParams;
2549 if (S.CheckRegparmAttr(Attr, numParams))
2550 return;
2551
2552 if (!isa<ObjCMethodDecl>(D)) {
2553 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2554 << Attr.getName() << ExpectedFunctionOrMethod;
2555 return;
2556 }
2557
2558 D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams));
2559 }
2560
2561 /// Checks a regparm attribute, returning true if it is ill-formed and
2562 /// otherwise setting numParams to the appropriate value.
CheckRegparmAttr(const AttributeList & Attr,unsigned & numParams)2563 bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
2564 if (Attr.isInvalid())
2565 return true;
2566
2567 if (Attr.getNumArgs() != 1) {
2568 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
2569 Attr.setInvalid();
2570 return true;
2571 }
2572
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();
2579 Attr.setInvalid();
2580 return true;
2581 }
2582
2583 if (Context.Target.getRegParmMax() == 0) {
2584 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
2585 << NumParamsExpr->getSourceRange();
2586 Attr.setInvalid();
2587 return true;
2588 }
2589
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();
2594 Attr.setInvalid();
2595 return true;
2596 }
2597
2598 return false;
2599 }
2600
handleLaunchBoundsAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
2607 return;
2608 }
2609
2610 if (!isFunctionOrMethod(D)) {
2611 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2612 << Attr.getName() << ExpectedFunctionOrMethod;
2613 return;
2614 }
2615
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();
2623 return;
2624 }
2625
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();
2634 return;
2635 }
2636 }
2637
2638 D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context,
2639 MaxThreads.getZExtValue(),
2640 MinBlocks.getZExtValue()));
2641 } else {
2642 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
2643 }
2644 }
2645
2646 //===----------------------------------------------------------------------===//
2647 // Checker-specific attribute handlers.
2648 //===----------------------------------------------------------------------===//
2649
isValidSubjectOfNSAttribute(Sema & S,QualType type)2650 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
2651 return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type);
2652 }
isValidSubjectOfCFAttribute(Sema & S,QualType type)2653 static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
2654 return type->isPointerType() || isValidSubjectOfNSAttribute(S, type);
2655 }
2656
handleNSConsumedAttr(Sema & S,Decl * D,const AttributeList & Attr)2657 static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2658 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
2659 if (!param) {
2660 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
2661 << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter;
2662 return;
2663 }
2664
2665 bool typeOK, cf;
2666 if (Attr.getKind() == AttributeList::AT_ns_consumed) {
2667 typeOK = isValidSubjectOfNSAttribute(S, param->getType());
2668 cf = false;
2669 } else {
2670 typeOK = isValidSubjectOfCFAttribute(S, param->getType());
2671 cf = true;
2672 }
2673
2674 if (!typeOK) {
2675 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
2676 << SourceRange(Attr.getLoc()) << Attr.getName() << cf;
2677 return;
2678 }
2679
2680 if (cf)
2681 param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context));
2682 else
2683 param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context));
2684 }
2685
handleNSConsumesSelfAttr(Sema & S,Decl * D,const AttributeList & Attr)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;
2691 return;
2692 }
2693
2694 D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context));
2695 }
2696
handleNSReturnsRetainedAttr(Sema & S,Decl * D,const AttributeList & Attr)2697 static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
2698 const AttributeList &Attr) {
2699
2700 QualType returnType;
2701
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();
2711 else {
2712 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
2713 << SourceRange(Attr.getLoc()) << Attr.getName()
2714 << ExpectedFunctionOrMethod;
2715 return;
2716 }
2717
2718 bool typeOK;
2719 bool cf;
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);
2726 cf = false;
2727 break;
2728
2729 case AttributeList::AT_cf_returns_retained:
2730 case AttributeList::AT_cf_returns_not_retained:
2731 typeOK = isValidSubjectOfCFAttribute(S, returnType);
2732 cf = true;
2733 break;
2734 }
2735
2736 if (!typeOK) {
2737 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
2738 << SourceRange(Attr.getLoc())
2739 << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
2740 return;
2741 }
2742
2743 switch (Attr.getKind()) {
2744 default:
2745 assert(0 && "invalid ownership attribute");
2746 return;
2747 case AttributeList::AT_ns_returns_autoreleased:
2748 D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(),
2749 S.Context));
2750 return;
2751 case AttributeList::AT_cf_returns_not_retained:
2752 D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(),
2753 S.Context));
2754 return;
2755 case AttributeList::AT_ns_returns_not_retained:
2756 D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(),
2757 S.Context));
2758 return;
2759 case AttributeList::AT_cf_returns_retained:
2760 D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(),
2761 S.Context));
2762 return;
2763 case AttributeList::AT_ns_returns_retained:
2764 D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(),
2765 S.Context));
2766 return;
2767 };
2768 }
2769
handleObjCOwnershipAttr(Sema & S,Decl * D,const AttributeList & Attr)2770 static void handleObjCOwnershipAttr(Sema &S, Decl *D,
2771 const AttributeList &Attr) {
2772 if (hasDeclarator(D)) return;
2773
2774 SourceLocation L = Attr.getLoc();
2775 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
2776 << SourceRange(L, L) << Attr.getName() << 12 /* variable */;
2777 }
2778
handleObjCPreciseLifetimeAttr(Sema & S,Decl * D,const AttributeList & Attr)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 */;
2785 return;
2786 }
2787
2788 ValueDecl *vd = cast<ValueDecl>(D);
2789 QualType type = vd->getType();
2790
2791 if (!type->isDependentType() &&
2792 !type->isObjCLifetimeType()) {
2793 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
2794 << type;
2795 return;
2796 }
2797
2798 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
2799
2800 // If we have no lifetime yet, check the lifetime we're presumably
2801 // going to infer.
2802 if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
2803 lifetime = type->getObjCARCImplicitLifetime();
2804
2805 switch (lifetime) {
2806 case Qualifiers::OCL_None:
2807 assert(type->isDependentType() &&
2808 "didn't infer lifetime for non-dependent type?");
2809 break;
2810
2811 case Qualifiers::OCL_Weak: // meaningful
2812 case Qualifiers::OCL_Strong: // meaningful
2813 break;
2814
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);
2819 break;
2820 }
2821
2822 D->addAttr(::new (S.Context)
2823 ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context));
2824 }
2825
isKnownDeclSpecAttr(const AttributeList & Attr)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;
2830 }
2831
2832 //===----------------------------------------------------------------------===//
2833 // Microsoft specific attribute handlers.
2834 //===----------------------------------------------------------------------===//
2835
handleUuidAttr(Sema & S,Decl * D,const AttributeList & Attr)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))
2840 return;
2841
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)
2846 << "uuid" << 1;
2847 return;
2848 }
2849
2850 llvm::StringRef StrRef = Str->getString();
2851
2852 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
2853 StrRef.back() == '}';
2854
2855 // Validate GUID length.
2856 if (IsCurly && StrRef.size() != 38) {
2857 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2858 return;
2859 }
2860 if (!IsCurly && StrRef.size() != 36) {
2861 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2862 return;
2863 }
2864
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 '{'
2869 ++I;
2870
2871 for (int i = 0; i < 36; ++i) {
2872 if (i == 8 || i == 13 || i == 18 || i == 23) {
2873 if (*I != '-') {
2874 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2875 return;
2876 }
2877 } else if (!isxdigit(*I)) {
2878 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
2879 return;
2880 }
2881 I++;
2882 }
2883
2884 D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context,
2885 Str->getString()));
2886 } else
2887 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
2888 }
2889
2890 //===----------------------------------------------------------------------===//
2891 // Top Level Sema Entry Points
2892 //===----------------------------------------------------------------------===//
2893
ProcessNonInheritableDeclAttr(Sema & S,Scope * scope,Decl * D,const AttributeList & Attr)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;
2900 default:
2901 break;
2902 }
2903 }
2904
ProcessInheritableDeclAttr(Sema & S,Scope * scope,Decl * D,const AttributeList & Attr)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.
2920 break;
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.
2926 break;
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);
2944 break;
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);
2951 break;
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;
2966
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;
2971
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;
2977
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;
2984
2985 case AttributeList::AT_reqd_wg_size:
2986 handleReqdWorkGroupSize(S, D, Attr); break;
2987
2988 case AttributeList::AT_init_priority:
2989 handleInitPriorityAttr(S, D, Attr); break;
2990
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);
2997 break;
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);
3002 break;
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);
3008 break;
3009 case AttributeList::AT_objc_exception:
3010 handleObjCExceptionAttr(S, D, Attr);
3011 break;
3012 case AttributeList::AT_objc_method_family:
3013 handleObjCMethodFamilyAttr(S, D, Attr);
3014 break;
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:
3025 // Just ignore
3026 break;
3027 case AttributeList::AT_no_instrument_function: // Interacts with -pg.
3028 handleNoInstrumentFunctionAttr(S, D, Attr);
3029 break;
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);
3037 break;
3038 case AttributeList::AT_opencl_kernel_function:
3039 handleOpenCLKernelAttr(S, D, Attr);
3040 break;
3041 case AttributeList::AT_uuid:
3042 handleUuidAttr(S, D, Attr);
3043 break;
3044 default:
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)
3049 << Attr.getName();
3050 break;
3051 }
3052 }
3053
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).
ProcessDeclAttribute(Sema & S,Scope * scope,Decl * D,const AttributeList & Attr,bool NonInheritable,bool Inheritable)3058 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
3059 const AttributeList &Attr,
3060 bool NonInheritable, bool Inheritable) {
3061 if (Attr.isInvalid())
3062 return;
3063
3064 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr))
3065 // FIXME: Try to deal with other __declspec attributes!
3066 return;
3067
3068 if (NonInheritable)
3069 ProcessNonInheritableDeclAttr(S, scope, D, Attr);
3070
3071 if (Inheritable)
3072 ProcessInheritableDeclAttr(S, scope, D, Attr);
3073 }
3074
3075 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified
3076 /// attribute list to the specified decl, ignoring any type attributes.
ProcessDeclAttributeList(Scope * S,Decl * D,const AttributeList * AttrList,bool NonInheritable,bool Inheritable)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);
3082 }
3083
3084 // GCC accepts
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();
3090 return;
3091 }
3092 }
3093
3094 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
3095 /// #pragma weak needs a non-definition decl and source may not have one
DeclClonePragmaWeak(NamedDecl * ND,IdentifierInfo * II)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());
3107 }
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());
3117 }
3118 }
3119 return NewD;
3120 }
3121
3122 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
3123 /// applied to it, possibly with an alias.
DeclApplyPragmaWeak(Scope * S,NamedDecl * ND,WeakInfo & W)3124 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
3125 if (W.getUsed()) return; // only do this once
3126 W.setUsed(true);
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,
3131 NDId->getName()));
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));
3142 }
3143 }
3144
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.
ProcessDeclAttributes(Scope * S,Decl * D,const Declarator & PD,bool NonInheritable,bool Inheritable)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
3151 // have to do this.
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;
3161 }
3162 }
3163 }
3164 }
3165
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);
3169
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);
3177
3178 // Finally, apply any attributes on the decl itself.
3179 if (const AttributeList *Attrs = PD.getAttributes())
3180 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable);
3181 }
3182
3183 /// Is the given declaration allowed to use a forbidden type?
isForbiddenTypeAllowed(Sema & S,Decl * decl)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))
3189 return false;
3190
3191 // Require it to be declared in a system header.
3192 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
3193 }
3194
3195 /// Handle a delayed forbidden-type diagnostic.
handleDelayedForbiddenType(Sema & S,DelayedDiagnostic & diag,Decl * decl)3196 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
3197 Decl *decl) {
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"));
3201 return;
3202 }
3203
3204 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
3205 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
3206 diag.Triggered = true;
3207 }
3208
3209 // This duplicates a vector push_back but hides the need to know the
3210 // size of the type.
add(const DelayedDiagnostic & diag)3211 void Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) {
3212 assert(StackSize <= StackCapacity);
3213
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;
3219
3220 if (StackCapacity)
3221 memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic));
3222
3223 delete[] oldBuffer;
3224 Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer);
3225 StackCapacity = newCapacity;
3226 }
3227
3228 assert(StackSize < StackCapacity);
3229 new (&Stack[StackSize++]) DelayedDiagnostic(diag);
3230 }
3231
popParsingDecl(Sema & S,ParsingDeclState state,Decl * decl)3232 void Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state,
3233 Decl *decl) {
3234 DelayedDiagnostics &DD = S.DelayedDiagnostics;
3235
3236 // Check the invariants.
3237 assert(DD.StackSize >= state.SavedStackSize);
3238 assert(state.SavedStackSize >= DD.ActiveStackBase);
3239 assert(DD.ParsingDepth > 0);
3240
3241 // Drop the parsing depth.
3242 DD.ParsingDepth--;
3243
3244 // If there are no active diagnostics, we're done.
3245 if (DD.StackSize == DD.ActiveStackBase)
3246 return;
3247
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];
3260 if (diag.Triggered)
3261 continue;
3262
3263 switch (diag.Kind) {
3264 case DelayedDiagnostic::Deprecation:
3265 S.HandleDelayedDeprecationCheck(diag, decl);
3266 break;
3267
3268 case DelayedDiagnostic::Access:
3269 S.HandleDelayedAccessCheck(diag, decl);
3270 break;
3271
3272 case DelayedDiagnostic::ForbiddenType:
3273 handleDelayedForbiddenType(S, diag, decl);
3274 break;
3275 }
3276 }
3277 }
3278
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();
3282
3283 DD.StackSize = state.SavedStackSize;
3284 }
3285
isDeclDeprecated(Decl * D)3286 static bool isDeclDeprecated(Decl *D) {
3287 do {
3288 if (D->isDeprecated())
3289 return true;
3290 } while ((D = cast_or_null<Decl>(D->getDeclContext())));
3291 return false;
3292 }
3293
HandleDelayedDeprecationCheck(DelayedDiagnostic & DD,Decl * Ctx)3294 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
3295 Decl *Ctx) {
3296 if (isDeclDeprecated(Ctx))
3297 return;
3298
3299 DD.Triggered = true;
3300 if (!DD.getDeprecationMessage().empty())
3301 Diag(DD.Loc, diag::warn_deprecated_message)
3302 << DD.getDeprecationDecl()->getDeclName()
3303 << DD.getDeprecationMessage();
3304 else
3305 Diag(DD.Loc, diag::warn_deprecated)
3306 << DD.getDeprecationDecl()->getDeclName();
3307 }
3308
EmitDeprecationWarning(NamedDecl * D,llvm::StringRef Message,SourceLocation Loc,const ObjCInterfaceDecl * UnknownObjCClass)3309 void Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message,
3310 SourceLocation Loc,
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));
3315 return;
3316 }
3317
3318 // Otherwise, don't warn if our current context is deprecated.
3319 if (isDeclDeprecated(cast<Decl>(CurContext)))
3320 return;
3321 if (!Message.empty())
3322 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
3323 << Message;
3324 else {
3325 if (!UnknownObjCClass)
3326 Diag(Loc, diag::warn_deprecated) << D->getDeclName();
3327 else {
3328 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
3329 Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
3330 }
3331 }
3332 }
3333