1193326Sed//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements decl-related attribute processing.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14212904Sdim#include "clang/Sema/SemaInternal.h"
15202379Srdivacky#include "TargetAttributesSema.h"
16193326Sed#include "clang/AST/ASTContext.h"
17245431Sdim#include "clang/AST/CXXInheritance.h"
18212904Sdim#include "clang/AST/DeclCXX.h"
19252723Sdim#include "clang/AST/DeclObjC.h"
20226890Sdim#include "clang/AST/DeclTemplate.h"
21193326Sed#include "clang/AST/Expr.h"
22252723Sdim#include "clang/AST/Mangle.h"
23252723Sdim#include "clang/Basic/CharInfo.h"
24224145Sdim#include "clang/Basic/SourceManager.h"
25193326Sed#include "clang/Basic/TargetInfo.h"
26263509Sdim#include "clang/Lex/Preprocessor.h"
27212904Sdim#include "clang/Sema/DeclSpec.h"
28212904Sdim#include "clang/Sema/DelayedDiagnostic.h"
29226890Sdim#include "clang/Sema/Lookup.h"
30252723Sdim#include "clang/Sema/Scope.h"
31198092Srdivacky#include "llvm/ADT/StringExtras.h"
32193326Sedusing namespace clang;
33212904Sdimusing namespace sema;
34193326Sed
35221345Sdim/// These constants match the enumerated choices of
36221345Sdim/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
37226890Sdimenum AttributeDeclKind {
38221345Sdim  ExpectedFunction,
39221345Sdim  ExpectedUnion,
40221345Sdim  ExpectedVariableOrFunction,
41221345Sdim  ExpectedFunctionOrMethod,
42221345Sdim  ExpectedParameter,
43221345Sdim  ExpectedFunctionMethodOrBlock,
44252723Sdim  ExpectedFunctionMethodOrClass,
45221345Sdim  ExpectedFunctionMethodOrParameter,
46221345Sdim  ExpectedClass,
47221345Sdim  ExpectedVariable,
48221345Sdim  ExpectedMethod,
49226890Sdim  ExpectedVariableFunctionOrLabel,
50235633Sdim  ExpectedFieldOrGlobalVar,
51245431Sdim  ExpectedStruct,
52252723Sdim  ExpectedVariableFunctionOrTag,
53252723Sdim  ExpectedTLSVar,
54252723Sdim  ExpectedVariableOrField,
55252723Sdim  ExpectedVariableFieldOrTag,
56263509Sdim  ExpectedTypeOrNamespace,
57263509Sdim  ExpectedObjectiveCInterface,
58263509Sdim  ExpectedMethodOrProperty,
59263509Sdim  ExpectedStructOrUnion,
60263509Sdim  ExpectedStructOrUnionOrClass
61221345Sdim};
62221345Sdim
63193326Sed//===----------------------------------------------------------------------===//
64193326Sed//  Helper functions
65193326Sed//===----------------------------------------------------------------------===//
66193326Sed
67224145Sdimstatic const FunctionType *getFunctionType(const Decl *D,
68198092Srdivacky                                           bool blocksToo = true) {
69193326Sed  QualType Ty;
70224145Sdim  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
71193326Sed    Ty = decl->getType();
72224145Sdim  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
73193326Sed    Ty = decl->getType();
74224145Sdim  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
75193326Sed    Ty = decl->getUnderlyingType();
76193326Sed  else
77193326Sed    return 0;
78198092Srdivacky
79193326Sed  if (Ty->isFunctionPointerType())
80198092Srdivacky    Ty = Ty->getAs<PointerType>()->getPointeeType();
81193326Sed  else if (blocksToo && Ty->isBlockPointerType())
82198092Srdivacky    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
83193326Sed
84198092Srdivacky  return Ty->getAs<FunctionType>();
85193326Sed}
86193326Sed
87193326Sed// FIXME: We should provide an abstraction around a method or function
88193326Sed// to provide the following bits of information.
89193326Sed
90201361Srdivacky/// isFunction - Return true if the given decl has function
91198092Srdivacky/// type (function or function-typed variable).
92224145Sdimstatic bool isFunction(const Decl *D) {
93224145Sdim  return getFunctionType(D, false) != NULL;
94198092Srdivacky}
95198092Srdivacky
96198092Srdivacky/// isFunctionOrMethod - Return true if the given decl has function
97193326Sed/// type (function or function-typed variable) or an Objective-C
98193326Sed/// method.
99224145Sdimstatic bool isFunctionOrMethod(const Decl *D) {
100245431Sdim  return isFunction(D) || isa<ObjCMethodDecl>(D);
101193326Sed}
102193326Sed
103193326Sed/// isFunctionOrMethodOrBlock - Return true if the given decl has function
104193326Sed/// type (function or function-typed variable) or an Objective-C
105193326Sed/// method or a block.
106224145Sdimstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
107224145Sdim  if (isFunctionOrMethod(D))
108193326Sed    return true;
109193326Sed  // check for block is more involved.
110224145Sdim  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
111193326Sed    QualType Ty = V->getType();
112193326Sed    return Ty->isBlockPointerType();
113193326Sed  }
114224145Sdim  return isa<BlockDecl>(D);
115193326Sed}
116193326Sed
117218893Sdim/// Return true if the given decl has a declarator that should have
118218893Sdim/// been processed by Sema::GetTypeForDeclarator.
119224145Sdimstatic bool hasDeclarator(const Decl *D) {
120224145Sdim  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
121224145Sdim  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
122224145Sdim         isa<ObjCPropertyDecl>(D);
123218893Sdim}
124218893Sdim
125193326Sed/// hasFunctionProto - Return true if the given decl has a argument
126193326Sed/// information. This decl should have already passed
127193326Sed/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
128224145Sdimstatic bool hasFunctionProto(const Decl *D) {
129224145Sdim  if (const FunctionType *FnTy = getFunctionType(D))
130193326Sed    return isa<FunctionProtoType>(FnTy);
131193326Sed  else {
132224145Sdim    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
133193326Sed    return true;
134193326Sed  }
135193326Sed}
136193326Sed
137193326Sed/// getFunctionOrMethodNumArgs - Return number of function or method
138193326Sed/// arguments. It is an error to call this on a K&R function (use
139193326Sed/// hasFunctionProto first).
140224145Sdimstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) {
141224145Sdim  if (const FunctionType *FnTy = getFunctionType(D))
142193326Sed    return cast<FunctionProtoType>(FnTy)->getNumArgs();
143224145Sdim  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
144193326Sed    return BD->getNumParams();
145224145Sdim  return cast<ObjCMethodDecl>(D)->param_size();
146193326Sed}
147193326Sed
148224145Sdimstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
149224145Sdim  if (const FunctionType *FnTy = getFunctionType(D))
150193326Sed    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
151224145Sdim  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
152193326Sed    return BD->getParamDecl(Idx)->getType();
153198092Srdivacky
154224145Sdim  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
155193326Sed}
156193326Sed
157224145Sdimstatic QualType getFunctionOrMethodResultType(const Decl *D) {
158224145Sdim  if (const FunctionType *FnTy = getFunctionType(D))
159193326Sed    return cast<FunctionProtoType>(FnTy)->getResultType();
160224145Sdim  return cast<ObjCMethodDecl>(D)->getResultType();
161193326Sed}
162193326Sed
163224145Sdimstatic bool isFunctionOrMethodVariadic(const Decl *D) {
164224145Sdim  if (const FunctionType *FnTy = getFunctionType(D)) {
165193326Sed    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
166193326Sed    return proto->isVariadic();
167224145Sdim  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
168207619Srdivacky    return BD->isVariadic();
169193326Sed  else {
170224145Sdim    return cast<ObjCMethodDecl>(D)->isVariadic();
171193326Sed  }
172193326Sed}
173193326Sed
174224145Sdimstatic bool isInstanceMethod(const Decl *D) {
175224145Sdim  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
176218893Sdim    return MethodDecl->isInstance();
177218893Sdim  return false;
178218893Sdim}
179218893Sdim
180193326Sedstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
181198092Srdivacky  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
182193326Sed  if (!PT)
183193326Sed    return false;
184198092Srdivacky
185208600Srdivacky  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
186208600Srdivacky  if (!Cls)
187193326Sed    return false;
188198092Srdivacky
189208600Srdivacky  IdentifierInfo* ClsName = Cls->getIdentifier();
190198092Srdivacky
191193326Sed  // FIXME: Should we walk the chain of classes?
192193326Sed  return ClsName == &Ctx.Idents.get("NSString") ||
193193326Sed         ClsName == &Ctx.Idents.get("NSMutableString");
194193326Sed}
195193326Sed
196193326Sedstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
197198092Srdivacky  const PointerType *PT = T->getAs<PointerType>();
198193326Sed  if (!PT)
199193326Sed    return false;
200193326Sed
201198092Srdivacky  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
202193326Sed  if (!RT)
203193326Sed    return false;
204198092Srdivacky
205193326Sed  const RecordDecl *RD = RT->getDecl();
206208600Srdivacky  if (RD->getTagKind() != TTK_Struct)
207193326Sed    return false;
208193326Sed
209193326Sed  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
210193326Sed}
211193326Sed
212263509Sdimstatic unsigned getNumAttributeArgs(const AttributeList &Attr) {
213263509Sdim  // FIXME: Include the type in the argument list.
214263509Sdim  return Attr.getNumArgs() + Attr.hasParsedType();
215263509Sdim}
216263509Sdim
217226890Sdim/// \brief Check if the attribute has exactly as many args as Num. May
218226890Sdim/// output an error.
219224145Sdimstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
220263509Sdim                                  unsigned Num) {
221263509Sdim  if (getNumAttributeArgs(Attr) != Num) {
222263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
223263509Sdim      << Attr.getName() << Num;
224224145Sdim    return false;
225224145Sdim  }
226224145Sdim
227224145Sdim  return true;
228224145Sdim}
229224145Sdim
230226890Sdim
231226890Sdim/// \brief Check if the attribute has at least as many args as Num. May
232226890Sdim/// output an error.
233226890Sdimstatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
234263509Sdim                                         unsigned Num) {
235263509Sdim  if (getNumAttributeArgs(Attr) < Num) {
236226890Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
237226890Sdim    return false;
238226890Sdim  }
239226890Sdim
240226890Sdim  return true;
241226890Sdim}
242226890Sdim
243245431Sdim/// \brief Check if IdxExpr is a valid argument index for a function or
244245431Sdim/// instance method D.  May output an error.
245226890Sdim///
246245431Sdim/// \returns true if IdxExpr is a valid index.
247245431Sdimstatic bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
248245431Sdim                                               StringRef AttrName,
249245431Sdim                                               SourceLocation AttrLoc,
250245431Sdim                                               unsigned AttrArgNum,
251245431Sdim                                               const Expr *IdxExpr,
252245431Sdim                                               uint64_t &Idx)
253245431Sdim{
254263509Sdim  assert(isFunctionOrMethod(D));
255245431Sdim
256245431Sdim  // In C++ the implicit 'this' function parameter also counts.
257245431Sdim  // Parameters are counted from one.
258263509Sdim  bool HP = hasFunctionProto(D);
259263509Sdim  bool HasImplicitThisParam = isInstanceMethod(D);
260263509Sdim  bool IV = HP && isFunctionOrMethodVariadic(D);
261263509Sdim  unsigned NumArgs = (HP ? getFunctionOrMethodNumArgs(D) : 0) +
262263509Sdim                     HasImplicitThisParam;
263245431Sdim
264245431Sdim  llvm::APSInt IdxInt;
265245431Sdim  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
266245431Sdim      !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
267263509Sdim    std::string Name = std::string("'") + AttrName.str() + std::string("'");
268263509Sdim    S.Diag(AttrLoc, diag::err_attribute_argument_n_type) << Name.c_str()
269263509Sdim      << AttrArgNum << AANT_ArgumentIntegerConstant << IdxExpr->getSourceRange();
270245431Sdim    return false;
271245431Sdim  }
272245431Sdim
273245431Sdim  Idx = IdxInt.getLimitedValue();
274263509Sdim  if (Idx < 1 || (!IV && Idx > NumArgs)) {
275245431Sdim    S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds)
276245431Sdim      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
277245431Sdim    return false;
278245431Sdim  }
279245431Sdim  Idx--; // Convert to zero-based.
280245431Sdim  if (HasImplicitThisParam) {
281245431Sdim    if (Idx == 0) {
282245431Sdim      S.Diag(AttrLoc,
283245431Sdim             diag::err_attribute_invalid_implicit_this_argument)
284245431Sdim        << AttrName << IdxExpr->getSourceRange();
285245431Sdim      return false;
286245431Sdim    }
287245431Sdim    --Idx;
288245431Sdim  }
289245431Sdim
290245431Sdim  return true;
291245431Sdim}
292245431Sdim
293263509Sdim/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
294263509Sdim/// If not emit an error and return false. If the argument is an identifier it
295263509Sdim/// will emit an error with a fixit hint and treat it as if it was a string
296263509Sdim/// literal.
297263509Sdimbool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr,
298263509Sdim                                          unsigned ArgNum, StringRef &Str,
299263509Sdim                                          SourceLocation *ArgLocation) {
300263509Sdim  // Look for identifiers. If we have one emit a hint to fix it to a literal.
301263509Sdim  if (Attr.isArgIdent(ArgNum)) {
302263509Sdim    IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
303263509Sdim    Diag(Loc->Loc, diag::err_attribute_argument_type)
304263509Sdim        << Attr.getName() << AANT_ArgumentString
305263509Sdim        << FixItHint::CreateInsertion(Loc->Loc, "\"")
306263509Sdim        << FixItHint::CreateInsertion(PP.getLocForEndOfToken(Loc->Loc), "\"");
307263509Sdim    Str = Loc->Ident->getName();
308263509Sdim    if (ArgLocation)
309263509Sdim      *ArgLocation = Loc->Loc;
310263509Sdim    return true;
311263509Sdim  }
312263509Sdim
313263509Sdim  // Now check for an actual string literal.
314263509Sdim  Expr *ArgExpr = Attr.getArgAsExpr(ArgNum);
315263509Sdim  StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
316263509Sdim  if (ArgLocation)
317263509Sdim    *ArgLocation = ArgExpr->getLocStart();
318263509Sdim
319263509Sdim  if (!Literal || !Literal->isAscii()) {
320263509Sdim    Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
321263509Sdim        << Attr.getName() << AANT_ArgumentString;
322263509Sdim    return false;
323263509Sdim  }
324263509Sdim
325263509Sdim  Str = Literal->getString();
326263509Sdim  return true;
327263509Sdim}
328263509Sdim
329245431Sdim///
330226890Sdim/// \brief Check if passed in Decl is a field or potentially shared global var
331226890Sdim/// \return true if the Decl is a field or potentially shared global variable
332226890Sdim///
333226890Sdimstatic bool mayBeSharedVariable(const Decl *D) {
334226890Sdim  if (isa<FieldDecl>(D))
335226890Sdim    return true;
336226890Sdim  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
337252723Sdim    return vd->hasGlobalStorage() && !vd->getTLSKind();
338226890Sdim
339226890Sdim  return false;
340226890Sdim}
341226890Sdim
342226890Sdim/// \brief Check if the passed-in expression is of type int or bool.
343226890Sdimstatic bool isIntOrBool(Expr *Exp) {
344226890Sdim  QualType QT = Exp->getType();
345226890Sdim  return QT->isBooleanType() || QT->isIntegerType();
346226890Sdim}
347226890Sdim
348245431Sdim
349245431Sdim// Check to see if the type is a smart pointer of some kind.  We assume
350245431Sdim// it's a smart pointer if it defines both operator-> and operator*.
351245431Sdimstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
352245431Sdim  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
353245431Sdim    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
354252723Sdim  if (Res1.empty())
355245431Sdim    return false;
356245431Sdim
357245431Sdim  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
358245431Sdim    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
359252723Sdim  if (Res2.empty())
360245431Sdim    return false;
361245431Sdim
362245431Sdim  return true;
363245431Sdim}
364245431Sdim
365226890Sdim/// \brief Check if passed in Decl is a pointer type.
366226890Sdim/// Note that this function may produce an error message.
367226890Sdim/// \return true if the Decl is a pointer type; false otherwise
368245431Sdimstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
369245431Sdim                                       const AttributeList &Attr) {
370226890Sdim  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
371226890Sdim    QualType QT = vd->getType();
372226890Sdim    if (QT->isAnyPointerType())
373226890Sdim      return true;
374245431Sdim
375245431Sdim    if (const RecordType *RT = QT->getAs<RecordType>()) {
376245431Sdim      // If it's an incomplete type, it could be a smart pointer; skip it.
377245431Sdim      // (We don't want to force template instantiation if we can avoid it,
378245431Sdim      // since that would alter the order in which templates are instantiated.)
379245431Sdim      if (RT->isIncompleteType())
380245431Sdim        return true;
381245431Sdim
382245431Sdim      if (threadSafetyCheckIsSmartPointer(S, RT))
383245431Sdim        return true;
384245431Sdim    }
385245431Sdim
386245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
387226890Sdim      << Attr.getName()->getName() << QT;
388226890Sdim  } else {
389226890Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
390226890Sdim      << Attr.getName();
391226890Sdim  }
392226890Sdim  return false;
393226890Sdim}
394226890Sdim
395226890Sdim/// \brief Checks that the passed in QualType either is of RecordType or points
396226890Sdim/// to RecordType. Returns the relevant RecordType, null if it does not exit.
397226890Sdimstatic const RecordType *getRecordType(QualType QT) {
398226890Sdim  if (const RecordType *RT = QT->getAs<RecordType>())
399226890Sdim    return RT;
400226890Sdim
401226890Sdim  // Now check if we point to record type.
402226890Sdim  if (const PointerType *PT = QT->getAs<PointerType>())
403226890Sdim    return PT->getPointeeType()->getAs<RecordType>();
404226890Sdim
405226890Sdim  return 0;
406226890Sdim}
407226890Sdim
408245431Sdim
409245431Sdimstatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
410245431Sdim                                             CXXBasePath &Path, void *Unused) {
411245431Sdim  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
412245431Sdim  if (RT->getDecl()->getAttr<LockableAttr>())
413245431Sdim    return true;
414245431Sdim  return false;
415245431Sdim}
416245431Sdim
417245431Sdim
418226890Sdim/// \brief Thread Safety Analysis: Checks that the passed in RecordType
419245431Sdim/// resolves to a lockable object.
420235633Sdimstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
421235633Sdim                                   QualType Ty) {
422235633Sdim  const RecordType *RT = getRecordType(Ty);
423245431Sdim
424235633Sdim  // Warn if could not get record type for this argument.
425226890Sdim  if (!RT) {
426245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
427235633Sdim      << Attr.getName() << Ty.getAsString();
428235633Sdim    return;
429226890Sdim  }
430245431Sdim
431245431Sdim  // Don't check for lockable if the class hasn't been defined yet.
432235633Sdim  if (RT->isIncompleteType())
433235633Sdim    return;
434245431Sdim
435245431Sdim  // Allow smart pointers to be used as lockable objects.
436245431Sdim  // FIXME -- Check the type that the smart pointer points to.
437245431Sdim  if (threadSafetyCheckIsSmartPointer(S, RT))
438235633Sdim    return;
439245431Sdim
440245431Sdim  // Check if the type is lockable.
441245431Sdim  RecordDecl *RD = RT->getDecl();
442245431Sdim  if (RD->getAttr<LockableAttr>())
443245431Sdim    return;
444245431Sdim
445245431Sdim  // Else check if any base classes are lockable.
446245431Sdim  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
447245431Sdim    CXXBasePaths BPaths(false, false);
448245431Sdim    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
449245431Sdim      return;
450226890Sdim  }
451245431Sdim
452245431Sdim  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
453245431Sdim    << Attr.getName() << Ty.getAsString();
454226890Sdim}
455226890Sdim
456226890Sdim/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
457245431Sdim/// from Sidx, resolve to a lockable object.
458226890Sdim/// \param Sidx The attribute argument index to start checking with.
459226890Sdim/// \param ParamIdxOk Whether an argument can be indexing into a function
460226890Sdim/// parameter list.
461245431Sdimstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
462226890Sdim                                         const AttributeList &Attr,
463226890Sdim                                         SmallVectorImpl<Expr*> &Args,
464226890Sdim                                         int Sidx = 0,
465226890Sdim                                         bool ParamIdxOk = false) {
466226890Sdim  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
467263509Sdim    Expr *ArgExp = Attr.getArgAsExpr(Idx);
468226890Sdim
469226890Sdim    if (ArgExp->isTypeDependent()) {
470245431Sdim      // FIXME -- need to check this again on template instantiation
471226890Sdim      Args.push_back(ArgExp);
472226890Sdim      continue;
473226890Sdim    }
474226890Sdim
475245431Sdim    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
476245431Sdim      if (StrLit->getLength() == 0 ||
477263509Sdim          (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) {
478245431Sdim        // Pass empty strings to the analyzer without warnings.
479245431Sdim        // Treat "*" as the universal lock.
480245431Sdim        Args.push_back(ArgExp);
481245431Sdim        continue;
482245431Sdim      }
483245431Sdim
484245431Sdim      // We allow constant strings to be used as a placeholder for expressions
485245431Sdim      // that are not valid C++ syntax, but warn that they are ignored.
486245431Sdim      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
487245431Sdim        Attr.getName();
488245431Sdim      Args.push_back(ArgExp);
489245431Sdim      continue;
490245431Sdim    }
491245431Sdim
492226890Sdim    QualType ArgTy = ArgExp->getType();
493226890Sdim
494245431Sdim    // A pointer to member expression of the form  &MyClass::mu is treated
495245431Sdim    // specially -- we need to look at the type of the member.
496245431Sdim    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
497245431Sdim      if (UOp->getOpcode() == UO_AddrOf)
498245431Sdim        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
499245431Sdim          if (DRE->getDecl()->isCXXInstanceMember())
500245431Sdim            ArgTy = DRE->getDecl()->getType();
501245431Sdim
502226890Sdim    // First see if we can just cast to record type, or point to record type.
503226890Sdim    const RecordType *RT = getRecordType(ArgTy);
504226890Sdim
505226890Sdim    // Now check if we index into a record type function param.
506226890Sdim    if(!RT && ParamIdxOk) {
507226890Sdim      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
508226890Sdim      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
509226890Sdim      if(FD && IL) {
510226890Sdim        unsigned int NumParams = FD->getNumParams();
511226890Sdim        llvm::APInt ArgValue = IL->getValue();
512226890Sdim        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
513226890Sdim        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
514226890Sdim        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
515226890Sdim          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
516226890Sdim            << Attr.getName() << Idx + 1 << NumParams;
517245431Sdim          continue;
518226890Sdim        }
519226890Sdim        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
520226890Sdim      }
521226890Sdim    }
522226890Sdim
523235633Sdim    checkForLockableRecord(S, D, Attr, ArgTy);
524226890Sdim
525226890Sdim    Args.push_back(ArgExp);
526226890Sdim  }
527226890Sdim}
528226890Sdim
529193326Sed//===----------------------------------------------------------------------===//
530193326Sed// Attribute Implementations
531193326Sed//===----------------------------------------------------------------------===//
532193326Sed
533193326Sed// FIXME: All this manual attribute parsing code is gross. At the
534193326Sed// least add some helper functions to check most argument patterns (#
535193326Sed// and types of args).
536193326Sed
537245431Sdimenum ThreadAttributeDeclKind {
538245431Sdim  ThreadExpectedFieldOrGlobalVar,
539245431Sdim  ThreadExpectedFunctionOrMethod,
540245431Sdim  ThreadExpectedClassOrStruct
541245431Sdim};
542245431Sdim
543245431Sdimstatic bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
544245431Sdim                                      const AttributeList &Attr) {
545226890Sdim  // D must be either a member field or global (potentially shared) variable.
546226890Sdim  if (!mayBeSharedVariable(D)) {
547245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
548245431Sdim      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
549245431Sdim    return false;
550226890Sdim  }
551226890Sdim
552245431Sdim  return true;
553245431Sdim}
554245431Sdim
555245431Sdimstatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
556245431Sdim  if (!checkGuardedVarAttrCommon(S, D, Attr))
557226890Sdim    return;
558226890Sdim
559252723Sdim  D->addAttr(::new (S.Context)
560252723Sdim             GuardedVarAttr(Attr.getRange(), S.Context,
561252723Sdim                            Attr.getAttributeSpellingListIndex()));
562226890Sdim}
563226890Sdim
564245431Sdimstatic void handlePtGuardedVarAttr(Sema &S, Decl *D,
565252723Sdim                                   const AttributeList &Attr) {
566245431Sdim  if (!checkGuardedVarAttrCommon(S, D, Attr))
567245431Sdim    return;
568245431Sdim
569245431Sdim  if (!threadSafetyCheckIsPointer(S, D, Attr))
570245431Sdim    return;
571245431Sdim
572252723Sdim  D->addAttr(::new (S.Context)
573252723Sdim             PtGuardedVarAttr(Attr.getRange(), S.Context,
574252723Sdim                              Attr.getAttributeSpellingListIndex()));
575245431Sdim}
576245431Sdim
577245431Sdimstatic bool checkGuardedByAttrCommon(Sema &S, Decl *D,
578245431Sdim                                     const AttributeList &Attr,
579245431Sdim                                     Expr* &Arg) {
580226890Sdim  // D must be either a member field or global (potentially shared) variable.
581226890Sdim  if (!mayBeSharedVariable(D)) {
582245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
583245431Sdim      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
584245431Sdim    return false;
585226890Sdim  }
586226890Sdim
587245431Sdim  SmallVector<Expr*, 1> Args;
588245431Sdim  // check that all arguments are lockable objects
589245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
590245431Sdim  unsigned Size = Args.size();
591245431Sdim  if (Size != 1)
592245431Sdim    return false;
593245431Sdim
594245431Sdim  Arg = Args[0];
595245431Sdim
596245431Sdim  return true;
597245431Sdim}
598245431Sdim
599245431Sdimstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
600245431Sdim  Expr *Arg = 0;
601245431Sdim  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
602226890Sdim    return;
603226890Sdim
604245431Sdim  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
605245431Sdim}
606226890Sdim
607245431Sdimstatic void handlePtGuardedByAttr(Sema &S, Decl *D,
608245431Sdim                                  const AttributeList &Attr) {
609245431Sdim  Expr *Arg = 0;
610245431Sdim  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
611245431Sdim    return;
612245431Sdim
613245431Sdim  if (!threadSafetyCheckIsPointer(S, D, Attr))
614245431Sdim    return;
615245431Sdim
616245431Sdim  D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
617245431Sdim                                               S.Context, Arg));
618226890Sdim}
619226890Sdim
620245431Sdimstatic bool checkLockableAttrCommon(Sema &S, Decl *D,
621245431Sdim                                    const AttributeList &Attr) {
622226890Sdim  // FIXME: Lockable structs for C code.
623263509Sdim  if (!isa<RecordDecl>(D)) {
624245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
625245431Sdim      << Attr.getName() << ThreadExpectedClassOrStruct;
626245431Sdim    return false;
627226890Sdim  }
628226890Sdim
629245431Sdim  return true;
630226890Sdim}
631226890Sdim
632245431Sdimstatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
633245431Sdim  if (!checkLockableAttrCommon(S, D, Attr))
634245431Sdim    return;
635245431Sdim
636245431Sdim  D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
637245431Sdim}
638245431Sdim
639245431Sdimstatic void handleScopedLockableAttr(Sema &S, Decl *D,
640245431Sdim                             const AttributeList &Attr) {
641245431Sdim  if (!checkLockableAttrCommon(S, D, Attr))
642245431Sdim    return;
643245431Sdim
644252723Sdim  D->addAttr(::new (S.Context)
645252723Sdim             ScopedLockableAttr(Attr.getRange(), S.Context,
646252723Sdim                                Attr.getAttributeSpellingListIndex()));
647245431Sdim}
648245431Sdim
649252723Sdimstatic void handleNoThreadSafetyAnalysis(Sema &S, Decl *D,
650252723Sdim                                         const AttributeList &Attr) {
651226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
652245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
653245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
654226890Sdim    return;
655226890Sdim  }
656226890Sdim
657226890Sdim  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
658226890Sdim                                                          S.Context));
659226890Sdim}
660226890Sdim
661252723Sdimstatic void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
662245431Sdim                                      const AttributeList &Attr) {
663235633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
664252723Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
665235633Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
666235633Sdim    return;
667235633Sdim  }
668235633Sdim
669252723Sdim  D->addAttr(::new (S.Context)
670252723Sdim             NoSanitizeAddressAttr(Attr.getRange(), S.Context,
671252723Sdim                                   Attr.getAttributeSpellingListIndex()));
672235633Sdim}
673235633Sdim
674252723Sdimstatic void handleNoSanitizeMemory(Sema &S, Decl *D,
675252723Sdim                                   const AttributeList &Attr) {
676252723Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
677252723Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
678252723Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
679252723Sdim    return;
680252723Sdim  }
681252723Sdim
682252723Sdim  D->addAttr(::new (S.Context) NoSanitizeMemoryAttr(Attr.getRange(),
683252723Sdim                                                         S.Context));
684252723Sdim}
685252723Sdim
686252723Sdimstatic void handleNoSanitizeThread(Sema &S, Decl *D,
687252723Sdim                                   const AttributeList &Attr) {
688252723Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
689252723Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
690252723Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
691252723Sdim    return;
692252723Sdim  }
693252723Sdim
694252723Sdim  D->addAttr(::new (S.Context) NoSanitizeThreadAttr(Attr.getRange(),
695252723Sdim                                                    S.Context));
696252723Sdim}
697252723Sdim
698245431Sdimstatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
699245431Sdim                                        const AttributeList &Attr,
700263509Sdim                                        SmallVectorImpl<Expr *> &Args) {
701226890Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
702245431Sdim    return false;
703226890Sdim
704226890Sdim  // D must be either a member field or global (potentially shared) variable.
705226890Sdim  ValueDecl *VD = dyn_cast<ValueDecl>(D);
706226890Sdim  if (!VD || !mayBeSharedVariable(D)) {
707245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
708245431Sdim      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
709245431Sdim    return false;
710226890Sdim  }
711226890Sdim
712245431Sdim  // Check that this attribute only applies to lockable types.
713226890Sdim  QualType QT = VD->getType();
714226890Sdim  if (!QT->isDependentType()) {
715226890Sdim    const RecordType *RT = getRecordType(QT);
716226890Sdim    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
717245431Sdim      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
718245431Sdim        << Attr.getName();
719245431Sdim      return false;
720226890Sdim    }
721226890Sdim  }
722226890Sdim
723245431Sdim  // Check that all arguments are lockable objects.
724245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
725252723Sdim  if (Args.empty())
726245431Sdim    return false;
727245431Sdim
728245431Sdim  return true;
729245431Sdim}
730245431Sdim
731245431Sdimstatic void handleAcquiredAfterAttr(Sema &S, Decl *D,
732245431Sdim                                    const AttributeList &Attr) {
733226890Sdim  SmallVector<Expr*, 1> Args;
734245431Sdim  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
735226890Sdim    return;
736226890Sdim
737245431Sdim  Expr **StartArg = &Args[0];
738252723Sdim  D->addAttr(::new (S.Context)
739252723Sdim             AcquiredAfterAttr(Attr.getRange(), S.Context,
740252723Sdim                               StartArg, Args.size(),
741252723Sdim                               Attr.getAttributeSpellingListIndex()));
742245431Sdim}
743226890Sdim
744245431Sdimstatic void handleAcquiredBeforeAttr(Sema &S, Decl *D,
745245431Sdim                                     const AttributeList &Attr) {
746245431Sdim  SmallVector<Expr*, 1> Args;
747245431Sdim  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
748245431Sdim    return;
749245431Sdim
750245431Sdim  Expr **StartArg = &Args[0];
751252723Sdim  D->addAttr(::new (S.Context)
752252723Sdim             AcquiredBeforeAttr(Attr.getRange(), S.Context,
753252723Sdim                                StartArg, Args.size(),
754252723Sdim                                Attr.getAttributeSpellingListIndex()));
755226890Sdim}
756226890Sdim
757245431Sdimstatic bool checkLockFunAttrCommon(Sema &S, Decl *D,
758245431Sdim                                   const AttributeList &Attr,
759263509Sdim                                   SmallVectorImpl<Expr *> &Args) {
760226890Sdim  // zero or more arguments ok
761226890Sdim
762226890Sdim  // check that the attribute is applied to a function
763226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
764245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
765245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
766245431Sdim    return false;
767226890Sdim  }
768226890Sdim
769226890Sdim  // check that all arguments are lockable objects
770245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
771245431Sdim
772245431Sdim  return true;
773245431Sdim}
774245431Sdim
775245431Sdimstatic void handleSharedLockFunctionAttr(Sema &S, Decl *D,
776245431Sdim                                         const AttributeList &Attr) {
777226890Sdim  SmallVector<Expr*, 1> Args;
778245431Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
779226890Sdim    return;
780226890Sdim
781226890Sdim  unsigned Size = Args.size();
782226890Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
783252723Sdim  D->addAttr(::new (S.Context)
784252723Sdim             SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
785252723Sdim                                    Attr.getAttributeSpellingListIndex()));
786245431Sdim}
787226890Sdim
788245431Sdimstatic void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
789245431Sdim                                            const AttributeList &Attr) {
790245431Sdim  SmallVector<Expr*, 1> Args;
791245431Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
792245431Sdim    return;
793245431Sdim
794245431Sdim  unsigned Size = Args.size();
795245431Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
796252723Sdim  D->addAttr(::new (S.Context)
797252723Sdim             ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
798252723Sdim                                       StartArg, Size,
799252723Sdim                                       Attr.getAttributeSpellingListIndex()));
800226890Sdim}
801226890Sdim
802263509Sdimstatic void handleAssertSharedLockAttr(Sema &S, Decl *D,
803263509Sdim                                       const AttributeList &Attr) {
804263509Sdim  SmallVector<Expr*, 1> Args;
805263509Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
806263509Sdim    return;
807263509Sdim
808263509Sdim  unsigned Size = Args.size();
809263509Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
810263509Sdim  D->addAttr(::new (S.Context)
811263509Sdim             AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size,
812263509Sdim                                  Attr.getAttributeSpellingListIndex()));
813263509Sdim}
814263509Sdim
815263509Sdimstatic void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
816263509Sdim                                          const AttributeList &Attr) {
817263509Sdim  SmallVector<Expr*, 1> Args;
818263509Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
819263509Sdim    return;
820263509Sdim
821263509Sdim  unsigned Size = Args.size();
822263509Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
823263509Sdim  D->addAttr(::new (S.Context)
824263509Sdim             AssertExclusiveLockAttr(Attr.getRange(), S.Context,
825263509Sdim                                     StartArg, Size,
826263509Sdim                                     Attr.getAttributeSpellingListIndex()));
827263509Sdim}
828263509Sdim
829263509Sdim
830245431Sdimstatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
831245431Sdim                                      const AttributeList &Attr,
832263509Sdim                                      SmallVectorImpl<Expr *> &Args) {
833226890Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
834245431Sdim    return false;
835226890Sdim
836226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
837245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
838245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
839245431Sdim    return false;
840226890Sdim  }
841226890Sdim
842263509Sdim  if (!isIntOrBool(Attr.getArgAsExpr(0))) {
843263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
844263509Sdim      << Attr.getName() << 1 << AANT_ArgumentIntOrBool;
845245431Sdim    return false;
846226890Sdim  }
847226890Sdim
848245431Sdim  // check that all arguments are lockable objects
849245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
850245431Sdim
851245431Sdim  return true;
852245431Sdim}
853245431Sdim
854245431Sdimstatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
855245431Sdim                                            const AttributeList &Attr) {
856226890Sdim  SmallVector<Expr*, 2> Args;
857245431Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
858226890Sdim    return;
859226890Sdim
860252723Sdim  D->addAttr(::new (S.Context)
861252723Sdim             SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
862263509Sdim                                       Attr.getArgAsExpr(0),
863263509Sdim                                       Args.data(), Args.size(),
864252723Sdim                                       Attr.getAttributeSpellingListIndex()));
865245431Sdim}
866226890Sdim
867245431Sdimstatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
868245431Sdim                                               const AttributeList &Attr) {
869245431Sdim  SmallVector<Expr*, 2> Args;
870245431Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
871245431Sdim    return;
872245431Sdim
873252723Sdim  D->addAttr(::new (S.Context)
874252723Sdim             ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
875263509Sdim                                          Attr.getArgAsExpr(0),
876263509Sdim                                          Args.data(), Args.size(),
877252723Sdim                                          Attr.getAttributeSpellingListIndex()));
878226890Sdim}
879226890Sdim
880245431Sdimstatic bool checkLocksRequiredCommon(Sema &S, Decl *D,
881245431Sdim                                     const AttributeList &Attr,
882263509Sdim                                     SmallVectorImpl<Expr *> &Args) {
883226890Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
884245431Sdim    return false;
885226890Sdim
886226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
887245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
888245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
889245431Sdim    return false;
890226890Sdim  }
891226890Sdim
892226890Sdim  // check that all arguments are lockable objects
893245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
894252723Sdim  if (Args.empty())
895245431Sdim    return false;
896245431Sdim
897245431Sdim  return true;
898245431Sdim}
899245431Sdim
900245431Sdimstatic void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
901245431Sdim                                             const AttributeList &Attr) {
902226890Sdim  SmallVector<Expr*, 1> Args;
903245431Sdim  if (!checkLocksRequiredCommon(S, D, Attr, Args))
904226890Sdim    return;
905226890Sdim
906245431Sdim  Expr **StartArg = &Args[0];
907252723Sdim  D->addAttr(::new (S.Context)
908252723Sdim             ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context,
909252723Sdim                                        StartArg, Args.size(),
910252723Sdim                                        Attr.getAttributeSpellingListIndex()));
911245431Sdim}
912226890Sdim
913245431Sdimstatic void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
914245431Sdim                                          const AttributeList &Attr) {
915245431Sdim  SmallVector<Expr*, 1> Args;
916245431Sdim  if (!checkLocksRequiredCommon(S, D, Attr, Args))
917245431Sdim    return;
918245431Sdim
919245431Sdim  Expr **StartArg = &Args[0];
920252723Sdim  D->addAttr(::new (S.Context)
921252723Sdim             SharedLocksRequiredAttr(Attr.getRange(), S.Context,
922252723Sdim                                     StartArg, Args.size(),
923252723Sdim                                     Attr.getAttributeSpellingListIndex()));
924226890Sdim}
925226890Sdim
926226890Sdimstatic void handleUnlockFunAttr(Sema &S, Decl *D,
927226890Sdim                                const AttributeList &Attr) {
928226890Sdim  // zero or more arguments ok
929226890Sdim
930226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
931245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
932245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
933226890Sdim    return;
934226890Sdim  }
935226890Sdim
936226890Sdim  // check that all arguments are lockable objects
937226890Sdim  SmallVector<Expr*, 1> Args;
938245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
939226890Sdim  unsigned Size = Args.size();
940226890Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
941226890Sdim
942252723Sdim  D->addAttr(::new (S.Context)
943252723Sdim             UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
944252723Sdim                                Attr.getAttributeSpellingListIndex()));
945226890Sdim}
946226890Sdim
947226890Sdimstatic void handleLockReturnedAttr(Sema &S, Decl *D,
948226890Sdim                                   const AttributeList &Attr) {
949226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
950245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
951245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
952226890Sdim    return;
953226890Sdim  }
954226890Sdim
955245431Sdim  // check that the argument is lockable object
956245431Sdim  SmallVector<Expr*, 1> Args;
957245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
958245431Sdim  unsigned Size = Args.size();
959245431Sdim  if (Size == 0)
960226890Sdim    return;
961226890Sdim
962252723Sdim  D->addAttr(::new (S.Context)
963252723Sdim             LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
964252723Sdim                              Attr.getAttributeSpellingListIndex()));
965226890Sdim}
966226890Sdim
967226890Sdimstatic void handleLocksExcludedAttr(Sema &S, Decl *D,
968226890Sdim                                    const AttributeList &Attr) {
969226890Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
970226890Sdim    return;
971226890Sdim
972226890Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
973245431Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
974245431Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
975226890Sdim    return;
976226890Sdim  }
977226890Sdim
978226890Sdim  // check that all arguments are lockable objects
979226890Sdim  SmallVector<Expr*, 1> Args;
980245431Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
981245431Sdim  unsigned Size = Args.size();
982245431Sdim  if (Size == 0)
983226890Sdim    return;
984245431Sdim  Expr **StartArg = &Args[0];
985226890Sdim
986252723Sdim  D->addAttr(::new (S.Context)
987252723Sdim             LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
988252723Sdim                               Attr.getAttributeSpellingListIndex()));
989226890Sdim}
990226890Sdim
991263509Sdimstatic void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
992263509Sdim  ConsumableAttr::ConsumedState DefaultState;
993226890Sdim
994263509Sdim  if (Attr.isArgIdent(0)) {
995263509Sdim    IdentifierLoc *IL = Attr.getArgAsIdent(0);
996263509Sdim    if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
997263509Sdim                                                   DefaultState)) {
998263509Sdim      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
999263509Sdim        << Attr.getName() << IL->Ident;
1000263509Sdim      return;
1001263509Sdim    }
1002263509Sdim  } else {
1003263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
1004263509Sdim        << Attr.getName() << AANT_ArgumentIdentifier;
1005263509Sdim    return;
1006263509Sdim  }
1007263509Sdim
1008263509Sdim  if (!isa<CXXRecordDecl>(D)) {
1009263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1010263509Sdim      Attr.getName() << ExpectedClass;
1011263509Sdim    return;
1012263509Sdim  }
1013263509Sdim
1014263509Sdim  D->addAttr(::new (S.Context)
1015263509Sdim             ConsumableAttr(Attr.getRange(), S.Context, DefaultState,
1016263509Sdim                            Attr.getAttributeSpellingListIndex()));
1017263509Sdim}
1018263509Sdim
1019263509Sdimstatic bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1020263509Sdim                                        const AttributeList &Attr) {
1021263509Sdim  ASTContext &CurrContext = S.getASTContext();
1022263509Sdim  QualType ThisType = MD->getThisType(CurrContext)->getPointeeType();
1023263509Sdim
1024263509Sdim  if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1025263509Sdim    if (!RD->hasAttr<ConsumableAttr>()) {
1026263509Sdim      S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) <<
1027263509Sdim        RD->getNameAsString();
1028263509Sdim
1029263509Sdim      return false;
1030263509Sdim    }
1031263509Sdim  }
1032263509Sdim
1033263509Sdim  return true;
1034263509Sdim}
1035263509Sdim
1036263509Sdim
1037263509Sdimstatic void handleCallableWhenAttr(Sema &S, Decl *D,
1038263509Sdim                                   const AttributeList &Attr) {
1039263509Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1040263509Sdim    return;
1041263509Sdim
1042263509Sdim  if (!isa<CXXMethodDecl>(D)) {
1043263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1044263509Sdim      Attr.getName() << ExpectedMethod;
1045263509Sdim    return;
1046263509Sdim  }
1047263509Sdim
1048263509Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1049263509Sdim    return;
1050263509Sdim
1051263509Sdim  SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1052263509Sdim  for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) {
1053263509Sdim    CallableWhenAttr::ConsumedState CallableState;
1054263509Sdim
1055263509Sdim    StringRef StateString;
1056263509Sdim    SourceLocation Loc;
1057263509Sdim    if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc))
1058263509Sdim      return;
1059263509Sdim
1060263509Sdim    if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1061263509Sdim                                                     CallableState)) {
1062263509Sdim      S.Diag(Loc, diag::warn_attribute_type_not_supported)
1063263509Sdim        << Attr.getName() << StateString;
1064263509Sdim      return;
1065263509Sdim    }
1066263509Sdim
1067263509Sdim    States.push_back(CallableState);
1068263509Sdim  }
1069263509Sdim
1070263509Sdim  D->addAttr(::new (S.Context)
1071263509Sdim             CallableWhenAttr(Attr.getRange(), S.Context, States.data(),
1072263509Sdim               States.size(), Attr.getAttributeSpellingListIndex()));
1073263509Sdim}
1074263509Sdim
1075263509Sdim
1076263509Sdimstatic void handleParamTypestateAttr(Sema &S, Decl *D,
1077263509Sdim                                    const AttributeList &Attr) {
1078263509Sdim  if (!checkAttributeNumArgs(S, Attr, 1)) return;
1079263509Sdim
1080263509Sdim  if (!isa<ParmVarDecl>(D)) {
1081263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1082263509Sdim      Attr.getName() << ExpectedParameter;
1083263509Sdim    return;
1084263509Sdim  }
1085263509Sdim
1086263509Sdim  ParamTypestateAttr::ConsumedState ParamState;
1087263509Sdim
1088263509Sdim  if (Attr.isArgIdent(0)) {
1089263509Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1090263509Sdim    StringRef StateString = Ident->Ident->getName();
1091263509Sdim
1092263509Sdim    if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1093263509Sdim                                                       ParamState)) {
1094263509Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1095263509Sdim        << Attr.getName() << StateString;
1096263509Sdim      return;
1097263509Sdim    }
1098263509Sdim  } else {
1099263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1100263509Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1101263509Sdim    return;
1102263509Sdim  }
1103263509Sdim
1104263509Sdim  // FIXME: This check is currently being done in the analysis.  It can be
1105263509Sdim  //        enabled here only after the parser propagates attributes at
1106263509Sdim  //        template specialization definition, not declaration.
1107263509Sdim  //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1108263509Sdim  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1109263509Sdim  //
1110263509Sdim  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1111263509Sdim  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1112263509Sdim  //      ReturnType.getAsString();
1113263509Sdim  //    return;
1114263509Sdim  //}
1115263509Sdim
1116263509Sdim  D->addAttr(::new (S.Context)
1117263509Sdim             ParamTypestateAttr(Attr.getRange(), S.Context, ParamState,
1118263509Sdim                                Attr.getAttributeSpellingListIndex()));
1119263509Sdim}
1120263509Sdim
1121263509Sdim
1122263509Sdimstatic void handleReturnTypestateAttr(Sema &S, Decl *D,
1123263509Sdim                                      const AttributeList &Attr) {
1124263509Sdim  if (!checkAttributeNumArgs(S, Attr, 1)) return;
1125263509Sdim
1126263509Sdim  if (!(isa<FunctionDecl>(D) || isa<ParmVarDecl>(D))) {
1127263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1128263509Sdim      Attr.getName() << ExpectedFunctionMethodOrParameter;
1129263509Sdim    return;
1130263509Sdim  }
1131263509Sdim
1132263509Sdim  ReturnTypestateAttr::ConsumedState ReturnState;
1133263509Sdim
1134263509Sdim  if (Attr.isArgIdent(0)) {
1135263509Sdim    IdentifierLoc *IL = Attr.getArgAsIdent(0);
1136263509Sdim    if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1137263509Sdim                                                        ReturnState)) {
1138263509Sdim      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
1139263509Sdim        << Attr.getName() << IL->Ident;
1140263509Sdim      return;
1141263509Sdim    }
1142263509Sdim  } else {
1143263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1144263509Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1145263509Sdim    return;
1146263509Sdim  }
1147263509Sdim
1148263509Sdim  // FIXME: This check is currently being done in the analysis.  It can be
1149263509Sdim  //        enabled here only after the parser propagates attributes at
1150263509Sdim  //        template specialization definition, not declaration.
1151263509Sdim  //QualType ReturnType;
1152263509Sdim  //
1153263509Sdim  //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1154263509Sdim  //  ReturnType = Param->getType();
1155263509Sdim  //
1156263509Sdim  //} else if (const CXXConstructorDecl *Constructor =
1157263509Sdim  //             dyn_cast<CXXConstructorDecl>(D)) {
1158263509Sdim  //  ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType();
1159263509Sdim  //
1160263509Sdim  //} else {
1161263509Sdim  //
1162263509Sdim  //  ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1163263509Sdim  //}
1164263509Sdim  //
1165263509Sdim  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1166263509Sdim  //
1167263509Sdim  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1168263509Sdim  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1169263509Sdim  //      ReturnType.getAsString();
1170263509Sdim  //    return;
1171263509Sdim  //}
1172263509Sdim
1173263509Sdim  D->addAttr(::new (S.Context)
1174263509Sdim             ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState,
1175263509Sdim                                 Attr.getAttributeSpellingListIndex()));
1176263509Sdim}
1177263509Sdim
1178263509Sdim
1179263509Sdimstatic void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1180263509Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
1181263509Sdim    return;
1182263509Sdim
1183263509Sdim  if (!isa<CXXMethodDecl>(D)) {
1184263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1185263509Sdim      Attr.getName() << ExpectedMethod;
1186263509Sdim    return;
1187263509Sdim  }
1188263509Sdim
1189263509Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1190263509Sdim    return;
1191263509Sdim
1192263509Sdim  SetTypestateAttr::ConsumedState NewState;
1193263509Sdim  if (Attr.isArgIdent(0)) {
1194263509Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1195263509Sdim    StringRef Param = Ident->Ident->getName();
1196263509Sdim    if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1197263509Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1198263509Sdim        << Attr.getName() << Param;
1199263509Sdim      return;
1200263509Sdim    }
1201263509Sdim  } else {
1202263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1203263509Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1204263509Sdim    return;
1205263509Sdim  }
1206263509Sdim
1207263509Sdim  D->addAttr(::new (S.Context)
1208263509Sdim             SetTypestateAttr(Attr.getRange(), S.Context, NewState,
1209263509Sdim                              Attr.getAttributeSpellingListIndex()));
1210263509Sdim}
1211263509Sdim
1212263509Sdimstatic void handleTestTypestateAttr(Sema &S, Decl *D,
1213263509Sdim                                    const AttributeList &Attr) {
1214263509Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
1215263509Sdim    return;
1216263509Sdim
1217263509Sdim  if (!isa<CXXMethodDecl>(D)) {
1218263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1219263509Sdim      Attr.getName() << ExpectedMethod;
1220263509Sdim    return;
1221263509Sdim  }
1222263509Sdim
1223263509Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1224263509Sdim    return;
1225263509Sdim
1226263509Sdim  TestTypestateAttr::ConsumedState TestState;
1227263509Sdim  if (Attr.isArgIdent(0)) {
1228263509Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1229263509Sdim    StringRef Param = Ident->Ident->getName();
1230263509Sdim    if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1231263509Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1232263509Sdim        << Attr.getName() << Param;
1233263509Sdim      return;
1234263509Sdim    }
1235263509Sdim  } else {
1236263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1237263509Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1238263509Sdim    return;
1239263509Sdim  }
1240263509Sdim
1241263509Sdim  D->addAttr(::new (S.Context)
1242263509Sdim             TestTypestateAttr(Attr.getRange(), S.Context, TestState,
1243263509Sdim                                Attr.getAttributeSpellingListIndex()));
1244263509Sdim}
1245263509Sdim
1246224145Sdimstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
1247224145Sdim                                    const AttributeList &Attr) {
1248252723Sdim  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
1249252723Sdim  if (TD == 0) {
1250252723Sdim    // __attribute__((ext_vector_type(N))) can only be applied to typedefs
1251252723Sdim    // and type-ids.
1252193326Sed    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
1253193326Sed    return;
1254193326Sed  }
1255198092Srdivacky
1256252723Sdim  // Remember this typedef decl, we will need it later for diagnostics.
1257252723Sdim  S.ExtVectorDecls.push_back(TD);
1258193326Sed}
1259193326Sed
1260224145Sdimstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1261224145Sdim  if (TagDecl *TD = dyn_cast<TagDecl>(D))
1262226890Sdim    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
1263224145Sdim  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
1264193326Sed    // If the alignment is less than or equal to 8 bits, the packed attribute
1265193326Sed    // has no effect.
1266245431Sdim    if (!FD->getType()->isDependentType() &&
1267245431Sdim        !FD->getType()->isIncompleteType() &&
1268193326Sed        S.Context.getTypeAlign(FD->getType()) <= 8)
1269193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1270193326Sed        << Attr.getName() << FD->getType();
1271193326Sed    else
1272252723Sdim      FD->addAttr(::new (S.Context)
1273252723Sdim                  PackedAttr(Attr.getRange(), S.Context,
1274252723Sdim                             Attr.getAttributeSpellingListIndex()));
1275193326Sed  } else
1276193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1277193326Sed}
1278193326Sed
1279224145Sdimstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1280245431Sdim  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
1281252723Sdim    RD->addAttr(::new (S.Context)
1282252723Sdim                MsStructAttr(Attr.getRange(), S.Context,
1283252723Sdim                             Attr.getAttributeSpellingListIndex()));
1284221345Sdim  else
1285221345Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1286221345Sdim}
1287221345Sdim
1288224145Sdimstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
1289204643Srdivacky  // The IBAction attributes only apply to instance methods.
1290224145Sdim  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
1291204643Srdivacky    if (MD->isInstanceMethod()) {
1292252723Sdim      D->addAttr(::new (S.Context)
1293252723Sdim                 IBActionAttr(Attr.getRange(), S.Context,
1294252723Sdim                              Attr.getAttributeSpellingListIndex()));
1295204643Srdivacky      return;
1296204643Srdivacky    }
1297204643Srdivacky
1298218893Sdim  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
1299204643Srdivacky}
1300204643Srdivacky
1301226890Sdimstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
1302226890Sdim  // The IBOutlet/IBOutletCollection attributes only apply to instance
1303226890Sdim  // variables or properties of Objective-C classes.  The outlet must also
1304226890Sdim  // have an object reference type.
1305226890Sdim  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
1306226890Sdim    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1307235633Sdim      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
1308226890Sdim        << Attr.getName() << VD->getType() << 0;
1309226890Sdim      return false;
1310226890Sdim    }
1311226890Sdim  }
1312226890Sdim  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1313226890Sdim    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1314235633Sdim      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
1315226890Sdim        << Attr.getName() << PD->getType() << 1;
1316226890Sdim      return false;
1317226890Sdim    }
1318226890Sdim  }
1319226890Sdim  else {
1320226890Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
1321226890Sdim    return false;
1322226890Sdim  }
1323235633Sdim
1324226890Sdim  return true;
1325226890Sdim}
1326226890Sdim
1327224145Sdimstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
1328226890Sdim  if (!checkIBOutletCommon(S, D, Attr))
1329204643Srdivacky    return;
1330204643Srdivacky
1331252723Sdim  D->addAttr(::new (S.Context)
1332252723Sdim             IBOutletAttr(Attr.getRange(), S.Context,
1333252723Sdim                          Attr.getAttributeSpellingListIndex()));
1334193326Sed}
1335193326Sed
1336224145Sdimstatic void handleIBOutletCollection(Sema &S, Decl *D,
1337224145Sdim                                     const AttributeList &Attr) {
1338208600Srdivacky
1339208600Srdivacky  // The iboutletcollection attribute can have zero or one arguments.
1340263509Sdim  if (Attr.getNumArgs() > 1) {
1341263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1342263509Sdim      << Attr.getName() << 1;
1343208600Srdivacky    return;
1344208600Srdivacky  }
1345208600Srdivacky
1346226890Sdim  if (!checkIBOutletCommon(S, D, Attr))
1347208600Srdivacky    return;
1348226890Sdim
1349263509Sdim  ParsedType PT;
1350263509Sdim
1351263509Sdim  if (Attr.hasParsedType())
1352263509Sdim    PT = Attr.getTypeArg();
1353263509Sdim  else {
1354263509Sdim    PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(),
1355263509Sdim                       S.getScopeForContext(D->getDeclContext()->getParent()));
1356263509Sdim    if (!PT) {
1357263509Sdim      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1358263509Sdim      return;
1359263509Sdim    }
1360212904Sdim  }
1361263509Sdim
1362263509Sdim  TypeSourceInfo *QTLoc = 0;
1363263509Sdim  QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1364263509Sdim  if (!QTLoc)
1365263509Sdim    QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
1366263509Sdim
1367212904Sdim  // Diagnose use of non-object type in iboutletcollection attribute.
1368212904Sdim  // FIXME. Gnu attribute extension ignores use of builtin types in
1369212904Sdim  // attributes. So, __attribute__((iboutletcollection(char))) will be
1370212904Sdim  // treated as __attribute__((iboutletcollection())).
1371235633Sdim  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1372263509Sdim    S.Diag(Attr.getLoc(),
1373263509Sdim           QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1374263509Sdim                               : diag::err_iboutletcollection_type) << QT;
1375212904Sdim    return;
1376212904Sdim  }
1377263509Sdim
1378252723Sdim  D->addAttr(::new (S.Context)
1379263509Sdim             IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc,
1380252723Sdim                                    Attr.getAttributeSpellingListIndex()));
1381208600Srdivacky}
1382208600Srdivacky
1383224145Sdimstatic void possibleTransparentUnionPointerType(QualType &T) {
1384224145Sdim  if (const RecordType *UT = T->getAsUnionType())
1385224145Sdim    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1386224145Sdim      RecordDecl *UD = UT->getDecl();
1387224145Sdim      for (RecordDecl::field_iterator it = UD->field_begin(),
1388224145Sdim           itend = UD->field_end(); it != itend; ++it) {
1389224145Sdim        QualType QT = it->getType();
1390224145Sdim        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
1391224145Sdim          T = QT;
1392224145Sdim          return;
1393224145Sdim        }
1394224145Sdim      }
1395224145Sdim    }
1396224145Sdim}
1397224145Sdim
1398245431Sdimstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1399245431Sdim  if (!isFunctionOrMethod(D)) {
1400245431Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1401263509Sdim    << Attr.getName() << ExpectedFunctionOrMethod;
1402245431Sdim    return;
1403245431Sdim  }
1404245431Sdim
1405245431Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1406245431Sdim    return;
1407245431Sdim
1408245431Sdim  SmallVector<unsigned, 8> SizeArgs;
1409263509Sdim  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
1410263509Sdim    Expr *Ex = Attr.getArgAsExpr(i);
1411263509Sdim    uint64_t Idx;
1412263509Sdim    if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
1413263509Sdim                                            Attr.getLoc(), i + 1, Ex, Idx))
1414245431Sdim      return;
1415245431Sdim
1416245431Sdim    // check if the function argument is of an integer type
1417263509Sdim    QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType();
1418245431Sdim    if (!T->isIntegerType()) {
1419263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
1420263509Sdim        << Attr.getName() << AANT_ArgumentIntegerConstant
1421263509Sdim        << Ex->getSourceRange();
1422245431Sdim      return;
1423245431Sdim    }
1424263509Sdim    SizeArgs.push_back(Idx);
1425245431Sdim  }
1426245431Sdim
1427245431Sdim  // check if the function returns a pointer
1428245431Sdim  if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
1429245431Sdim    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1430263509Sdim    << Attr.getName() << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
1431245431Sdim  }
1432245431Sdim
1433252723Sdim  D->addAttr(::new (S.Context)
1434252723Sdim             AllocSizeAttr(Attr.getRange(), S.Context,
1435252723Sdim                           SizeArgs.data(), SizeArgs.size(),
1436252723Sdim                           Attr.getAttributeSpellingListIndex()));
1437245431Sdim}
1438245431Sdim
1439224145Sdimstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1440198092Srdivacky  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
1441198092Srdivacky  // ignore it as well
1442224145Sdim  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
1443193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1444221345Sdim      << Attr.getName() << ExpectedFunction;
1445193326Sed    return;
1446193326Sed  }
1447198092Srdivacky
1448263509Sdim  SmallVector<unsigned, 8> NonNullArgs;
1449263509Sdim  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
1450263509Sdim    Expr *Ex = Attr.getArgAsExpr(i);
1451263509Sdim    uint64_t Idx;
1452263509Sdim    if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
1453263509Sdim                                            Attr.getLoc(), i + 1, Ex, Idx))
1454193326Sed      return;
1455198092Srdivacky
1456193326Sed    // Is the function argument a pointer type?
1457263509Sdim    QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType();
1458224145Sdim    possibleTransparentUnionPointerType(T);
1459224145Sdim
1460198092Srdivacky    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
1461193326Sed      // FIXME: Should also highlight argument in decl.
1462212904Sdim      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
1463193326Sed        << "nonnull" << Ex->getSourceRange();
1464193326Sed      continue;
1465193326Sed    }
1466198092Srdivacky
1467263509Sdim    NonNullArgs.push_back(Idx);
1468193326Sed  }
1469198092Srdivacky
1470198092Srdivacky  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1471198092Srdivacky  // arguments have a nonnull attribute.
1472193326Sed  if (NonNullArgs.empty()) {
1473252723Sdim    for (unsigned i = 0, e = getFunctionOrMethodNumArgs(D); i != e; ++i) {
1474252723Sdim      QualType T = getFunctionOrMethodArgType(D, i).getNonReferenceType();
1475224145Sdim      possibleTransparentUnionPointerType(T);
1476198092Srdivacky      if (T->isAnyPointerType() || T->isBlockPointerType())
1477252723Sdim        NonNullArgs.push_back(i);
1478193326Sed    }
1479198092Srdivacky
1480218893Sdim    // No pointer arguments?
1481193326Sed    if (NonNullArgs.empty()) {
1482218893Sdim      // Warn the trivial case only if attribute is not coming from a
1483218893Sdim      // macro instantiation.
1484218893Sdim      if (Attr.getLoc().isFileID())
1485218893Sdim        S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1486193326Sed      return;
1487193326Sed    }
1488193326Sed  }
1489193326Sed
1490252723Sdim  unsigned *start = &NonNullArgs[0];
1491193326Sed  unsigned size = NonNullArgs.size();
1492212904Sdim  llvm::array_pod_sort(start, start + size);
1493252723Sdim  D->addAttr(::new (S.Context)
1494252723Sdim             NonNullAttr(Attr.getRange(), S.Context, start, size,
1495252723Sdim                         Attr.getAttributeSpellingListIndex()));
1496193326Sed}
1497193326Sed
1498263509Sdimstatic const char *ownershipKindToDiagName(OwnershipAttr::OwnershipKind K) {
1499263509Sdim  switch (K) {
1500263509Sdim    case OwnershipAttr::Holds:    return "'ownership_holds'";
1501263509Sdim    case OwnershipAttr::Takes:    return "'ownership_takes'";
1502263509Sdim    case OwnershipAttr::Returns:  return "'ownership_returns'";
1503263509Sdim  }
1504263509Sdim  llvm_unreachable("unknown ownership");
1505263509Sdim}
1506263509Sdim
1507224145Sdimstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1508263509Sdim  // This attribute must be applied to a function declaration. The first
1509263509Sdim  // argument to the attribute must be an identifier, the name of the resource,
1510263509Sdim  // for example: malloc. The following arguments must be argument indexes, the
1511263509Sdim  // arguments must be of integer type for Returns, otherwise of pointer type.
1512212904Sdim  // The difference between Holds and Takes is that a pointer may still be used
1513263509Sdim  // after being held. free() should be __attribute((ownership_takes)), whereas
1514212904Sdim  // a list append function may well be __attribute((ownership_holds)).
1515212904Sdim
1516263509Sdim  if (!AL.isArgIdent(0)) {
1517263509Sdim    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1518263509Sdim      << AL.getName() << 1 << AANT_ArgumentIdentifier;
1519212904Sdim    return;
1520212904Sdim  }
1521263509Sdim
1522212904Sdim  // Figure out our Kind, and check arguments while we're at it.
1523212904Sdim  OwnershipAttr::OwnershipKind K;
1524212904Sdim  switch (AL.getKind()) {
1525212904Sdim  case AttributeList::AT_ownership_takes:
1526212904Sdim    K = OwnershipAttr::Takes;
1527263509Sdim    if (AL.getNumArgs() < 2) {
1528263509Sdim      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << 2;
1529212904Sdim      return;
1530212904Sdim    }
1531212904Sdim    break;
1532212904Sdim  case AttributeList::AT_ownership_holds:
1533212904Sdim    K = OwnershipAttr::Holds;
1534263509Sdim    if (AL.getNumArgs() < 2) {
1535263509Sdim      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << 2;
1536212904Sdim      return;
1537212904Sdim    }
1538212904Sdim    break;
1539212904Sdim  case AttributeList::AT_ownership_returns:
1540212904Sdim    K = OwnershipAttr::Returns;
1541263509Sdim
1542263509Sdim    if (AL.getNumArgs() > 2) {
1543263509Sdim      S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << 1;
1544212904Sdim      return;
1545212904Sdim    }
1546212904Sdim    break;
1547212904Sdim  default:
1548212904Sdim    // This should never happen given how we are called.
1549212904Sdim    llvm_unreachable("Unknown ownership attribute");
1550212904Sdim  }
1551212904Sdim
1552224145Sdim  if (!isFunction(D) || !hasFunctionProto(D)) {
1553221345Sdim    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1554221345Sdim      << AL.getName() << ExpectedFunction;
1555212904Sdim    return;
1556212904Sdim  }
1557212904Sdim
1558263509Sdim  StringRef Module = AL.getArgAsIdent(0)->Ident->getName();
1559212904Sdim
1560212904Sdim  // Normalize the argument, __foo__ becomes foo.
1561212904Sdim  if (Module.startswith("__") && Module.endswith("__"))
1562212904Sdim    Module = Module.substr(2, Module.size() - 4);
1563212904Sdim
1564263509Sdim  SmallVector<unsigned, 8> OwnershipArgs;
1565263509Sdim  for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1566263509Sdim    Expr *Ex = AL.getArgAsExpr(i);
1567263509Sdim    uint64_t Idx;
1568263509Sdim    if (!checkFunctionOrMethodArgumentIndex(S, D, AL.getName()->getName(),
1569263509Sdim                                            AL.getLoc(), i, Ex, Idx))
1570263509Sdim      return;
1571212904Sdim
1572263509Sdim    // Is the function argument a pointer type?
1573263509Sdim    QualType T = getFunctionOrMethodArgType(D, Idx);
1574263509Sdim    int Err = -1;  // No error
1575212904Sdim    switch (K) {
1576263509Sdim      case OwnershipAttr::Takes:
1577263509Sdim      case OwnershipAttr::Holds:
1578263509Sdim        if (!T->isAnyPointerType() && !T->isBlockPointerType())
1579263509Sdim          Err = 0;
1580263509Sdim        break;
1581263509Sdim      case OwnershipAttr::Returns:
1582263509Sdim        if (!T->isIntegerType())
1583263509Sdim          Err = 1;
1584263509Sdim        break;
1585212904Sdim    }
1586263509Sdim    if (-1 != Err) {
1587263509Sdim      S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err
1588263509Sdim        << Ex->getSourceRange();
1589263509Sdim      return;
1590212904Sdim    }
1591212904Sdim
1592212904Sdim    // Check we don't have a conflict with another ownership attribute.
1593212904Sdim    for (specific_attr_iterator<OwnershipAttr>
1594263509Sdim         i = D->specific_attr_begin<OwnershipAttr>(),
1595263509Sdim         e = D->specific_attr_end<OwnershipAttr>(); i != e; ++i) {
1596263509Sdim      if ((*i)->getOwnKind() != K && (*i)->args_end() !=
1597263509Sdim          std::find((*i)->args_begin(), (*i)->args_end(), Idx)) {
1598263509Sdim        S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1599263509Sdim          << AL.getName() << ownershipKindToDiagName((*i)->getOwnKind());
1600263509Sdim        return;
1601212904Sdim      }
1602212904Sdim    }
1603263509Sdim    OwnershipArgs.push_back(Idx);
1604212904Sdim  }
1605212904Sdim
1606212904Sdim  unsigned* start = OwnershipArgs.data();
1607212904Sdim  unsigned size = OwnershipArgs.size();
1608212904Sdim  llvm::array_pod_sort(start, start + size);
1609212904Sdim
1610252723Sdim  D->addAttr(::new (S.Context)
1611252723Sdim             OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size,
1612252723Sdim                           AL.getAttributeSpellingListIndex()));
1613212904Sdim}
1614212904Sdim
1615224145Sdimstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1616204643Srdivacky  // Check the attribute arguments.
1617204643Srdivacky  if (Attr.getNumArgs() > 1) {
1618263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1619263509Sdim      << Attr.getName() << 1;
1620204643Srdivacky    return;
1621204643Srdivacky  }
1622204643Srdivacky
1623224145Sdim  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
1624218893Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1625221345Sdim      << Attr.getName() << ExpectedVariableOrFunction;
1626218893Sdim    return;
1627218893Sdim  }
1628218893Sdim
1629224145Sdim  NamedDecl *nd = cast<NamedDecl>(D);
1630218893Sdim
1631204643Srdivacky  // gcc rejects
1632204643Srdivacky  // class c {
1633204643Srdivacky  //   static int a __attribute__((weakref ("v2")));
1634204643Srdivacky  //   static int b() __attribute__((weakref ("f3")));
1635204643Srdivacky  // };
1636204643Srdivacky  // and ignores the attributes of
1637204643Srdivacky  // void f(void) {
1638204643Srdivacky  //   static int a __attribute__((weakref ("v2")));
1639204643Srdivacky  // }
1640204643Srdivacky  // we reject them
1641224145Sdim  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1642212904Sdim  if (!Ctx->isFileContext()) {
1643212904Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
1644218893Sdim        nd->getNameAsString();
1645212904Sdim    return;
1646204643Srdivacky  }
1647204643Srdivacky
1648204643Srdivacky  // The GCC manual says
1649204643Srdivacky  //
1650204643Srdivacky  // At present, a declaration to which `weakref' is attached can only
1651204643Srdivacky  // be `static'.
1652204643Srdivacky  //
1653204643Srdivacky  // It also says
1654204643Srdivacky  //
1655204643Srdivacky  // Without a TARGET,
1656204643Srdivacky  // given as an argument to `weakref' or to `alias', `weakref' is
1657204643Srdivacky  // equivalent to `weak'.
1658204643Srdivacky  //
1659204643Srdivacky  // gcc 4.4.1 will accept
1660204643Srdivacky  // int a7 __attribute__((weakref));
1661204643Srdivacky  // as
1662204643Srdivacky  // int a7 __attribute__((weak));
1663204643Srdivacky  // This looks like a bug in gcc. We reject that for now. We should revisit
1664204643Srdivacky  // it if this behaviour is actually used.
1665204643Srdivacky
1666204643Srdivacky  // GCC rejects
1667204643Srdivacky  // static ((alias ("y"), weakref)).
1668204643Srdivacky  // Should we? How to check that weakref is before or after alias?
1669204643Srdivacky
1670263509Sdim  // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1671263509Sdim  // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
1672263509Sdim  // StringRef parameter it was given anyway.
1673263509Sdim  StringRef Str;
1674263509Sdim  if (Attr.getNumArgs() && S.checkStringLiteralArgumentAttr(Attr, 0, Str))
1675204643Srdivacky    // GCC will accept anything as the argument of weakref. Should we
1676204643Srdivacky    // check for an existing decl?
1677263509Sdim    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1678263509Sdim                                        Attr.getAttributeSpellingListIndex()));
1679204643Srdivacky
1680252723Sdim  D->addAttr(::new (S.Context)
1681252723Sdim             WeakRefAttr(Attr.getRange(), S.Context,
1682252723Sdim                         Attr.getAttributeSpellingListIndex()));
1683204643Srdivacky}
1684204643Srdivacky
1685224145Sdimstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1686263509Sdim  StringRef Str;
1687263509Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
1688193326Sed    return;
1689198092Srdivacky
1690226890Sdim  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1691218893Sdim    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1692218893Sdim    return;
1693218893Sdim  }
1694218893Sdim
1695193326Sed  // FIXME: check if target symbol exists in current file
1696198092Srdivacky
1697263509Sdim  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1698252723Sdim                                         Attr.getAttributeSpellingListIndex()));
1699193326Sed}
1700193326Sed
1701245431Sdimstatic void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1702245431Sdim  if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
1703245431Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1704245431Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
1705245431Sdim    return;
1706245431Sdim  }
1707245431Sdim
1708252723Sdim  D->addAttr(::new (S.Context)
1709252723Sdim             MinSizeAttr(Attr.getRange(), S.Context,
1710252723Sdim                         Attr.getAttributeSpellingListIndex()));
1711245431Sdim}
1712245431Sdim
1713245431Sdimstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1714245431Sdim  if (!isa<FunctionDecl>(D)) {
1715245431Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1716245431Sdim      << Attr.getName() << ExpectedFunction;
1717245431Sdim    return;
1718245431Sdim  }
1719245431Sdim
1720245431Sdim  if (D->hasAttr<HotAttr>()) {
1721245431Sdim    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1722245431Sdim      << Attr.getName() << "hot";
1723245431Sdim    return;
1724245431Sdim  }
1725245431Sdim
1726252723Sdim  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
1727252723Sdim                                        Attr.getAttributeSpellingListIndex()));
1728245431Sdim}
1729245431Sdim
1730245431Sdimstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1731245431Sdim  if (!isa<FunctionDecl>(D)) {
1732245431Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1733245431Sdim      << Attr.getName() << ExpectedFunction;
1734245431Sdim    return;
1735245431Sdim  }
1736245431Sdim
1737245431Sdim  if (D->hasAttr<ColdAttr>()) {
1738245431Sdim    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1739245431Sdim      << Attr.getName() << "cold";
1740245431Sdim    return;
1741245431Sdim  }
1742245431Sdim
1743252723Sdim  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
1744252723Sdim                                       Attr.getAttributeSpellingListIndex()));
1745245431Sdim}
1746245431Sdim
1747224145Sdimstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1748224145Sdim  if (!isa<FunctionDecl>(D)) {
1749218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1750221345Sdim      << Attr.getName() << ExpectedFunction;
1751218893Sdim    return;
1752218893Sdim  }
1753218893Sdim
1754252723Sdim  D->addAttr(::new (S.Context)
1755252723Sdim             NakedAttr(Attr.getRange(), S.Context,
1756252723Sdim                       Attr.getAttributeSpellingListIndex()));
1757218893Sdim}
1758218893Sdim
1759224145Sdimstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
1760224145Sdim                                   const AttributeList &Attr) {
1761224145Sdim  if (!isa<FunctionDecl>(D)) {
1762193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1763221345Sdim      << Attr.getName() << ExpectedFunction;
1764193326Sed    return;
1765193326Sed  }
1766198092Srdivacky
1767252723Sdim  D->addAttr(::new (S.Context)
1768252723Sdim             AlwaysInlineAttr(Attr.getRange(), S.Context,
1769252723Sdim                              Attr.getAttributeSpellingListIndex()));
1770193326Sed}
1771193326Sed
1772245431Sdimstatic void handleTLSModelAttr(Sema &S, Decl *D,
1773245431Sdim                               const AttributeList &Attr) {
1774263509Sdim  StringRef Model;
1775263509Sdim  SourceLocation LiteralLoc;
1776245431Sdim  // Check that it is a string.
1777263509Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc))
1778245431Sdim    return;
1779245431Sdim
1780252723Sdim  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) {
1781245431Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1782245431Sdim      << Attr.getName() << ExpectedTLSVar;
1783245431Sdim    return;
1784245431Sdim  }
1785245431Sdim
1786245431Sdim  // Check that the value.
1787245431Sdim  if (Model != "global-dynamic" && Model != "local-dynamic"
1788245431Sdim      && Model != "initial-exec" && Model != "local-exec") {
1789263509Sdim    S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
1790245431Sdim    return;
1791245431Sdim  }
1792245431Sdim
1793252723Sdim  D->addAttr(::new (S.Context)
1794252723Sdim             TLSModelAttr(Attr.getRange(), S.Context, Model,
1795252723Sdim                          Attr.getAttributeSpellingListIndex()));
1796245431Sdim}
1797245431Sdim
1798224145Sdimstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1799224145Sdim  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1800198092Srdivacky    QualType RetTy = FD->getResultType();
1801198092Srdivacky    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
1802252723Sdim      D->addAttr(::new (S.Context)
1803252723Sdim                 MallocAttr(Attr.getRange(), S.Context,
1804252723Sdim                            Attr.getAttributeSpellingListIndex()));
1805198092Srdivacky      return;
1806198092Srdivacky    }
1807198092Srdivacky  }
1808198092Srdivacky
1809198092Srdivacky  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
1810198092Srdivacky}
1811198092Srdivacky
1812224145Sdimstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1813252723Sdim  D->addAttr(::new (S.Context)
1814252723Sdim             MayAliasAttr(Attr.getRange(), S.Context,
1815252723Sdim                          Attr.getAttributeSpellingListIndex()));
1816218893Sdim}
1817218893Sdim
1818224145Sdimstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1819224145Sdim  if (isa<VarDecl>(D))
1820252723Sdim    D->addAttr(::new (S.Context)
1821252723Sdim               NoCommonAttr(Attr.getRange(), S.Context,
1822252723Sdim                            Attr.getAttributeSpellingListIndex()));
1823218893Sdim  else
1824218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1825221345Sdim      << Attr.getName() << ExpectedVariable;
1826212904Sdim}
1827212904Sdim
1828224145Sdimstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1829263509Sdim  if (S.LangOpts.CPlusPlus) {
1830263509Sdim    S.Diag(Attr.getLoc(), diag::err_common_not_supported_cplusplus);
1831263509Sdim    return;
1832263509Sdim  }
1833263509Sdim
1834224145Sdim  if (isa<VarDecl>(D))
1835252723Sdim    D->addAttr(::new (S.Context)
1836252723Sdim               CommonAttr(Attr.getRange(), S.Context,
1837252723Sdim                          Attr.getAttributeSpellingListIndex()));
1838218893Sdim  else
1839218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1840221345Sdim      << Attr.getName() << ExpectedVariable;
1841218893Sdim}
1842218893Sdim
1843224145Sdimstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
1844224145Sdim  if (hasDeclarator(D)) return;
1845218893Sdim
1846218893Sdim  if (S.CheckNoReturnAttr(attr)) return;
1847218893Sdim
1848224145Sdim  if (!isa<ObjCMethodDecl>(D)) {
1849218893Sdim    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1850221345Sdim      << attr.getName() << ExpectedFunctionOrMethod;
1851218893Sdim    return;
1852218893Sdim  }
1853218893Sdim
1854252723Sdim  D->addAttr(::new (S.Context)
1855252723Sdim             NoReturnAttr(attr.getRange(), S.Context,
1856252723Sdim                          attr.getAttributeSpellingListIndex()));
1857218893Sdim}
1858218893Sdim
1859218893Sdimbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1860263509Sdim  if (!checkAttributeNumArgs(*this, attr, 0)) {
1861218893Sdim    attr.setInvalid();
1862218893Sdim    return true;
1863218893Sdim  }
1864218893Sdim
1865218893Sdim  return false;
1866218893Sdim}
1867218893Sdim
1868224145Sdimstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
1869224145Sdim                                       const AttributeList &Attr) {
1870212904Sdim
1871212904Sdim  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1872212904Sdim  // because 'analyzer_noreturn' does not impact the type.
1873224145Sdim  if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
1874224145Sdim    ValueDecl *VD = dyn_cast<ValueDecl>(D);
1875200583Srdivacky    if (VD == 0 || (!VD->getType()->isBlockPointerType()
1876200583Srdivacky                    && !VD->getType()->isFunctionPointerType())) {
1877199990Srdivacky      S.Diag(Attr.getLoc(),
1878252723Sdim             Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
1879212904Sdim             : diag::warn_attribute_wrong_decl_type)
1880221345Sdim        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1881212904Sdim      return;
1882193326Sed    }
1883193326Sed  }
1884212904Sdim
1885252723Sdim  D->addAttr(::new (S.Context)
1886252723Sdim             AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
1887252723Sdim                                  Attr.getAttributeSpellingListIndex()));
1888193326Sed}
1889193326Sed
1890252723Sdimstatic void handleCXX11NoReturnAttr(Sema &S, Decl *D,
1891252723Sdim                                    const AttributeList &Attr) {
1892252723Sdim  // C++11 [dcl.attr.noreturn]p1:
1893252723Sdim  //   The attribute may be applied to the declarator-id in a function
1894252723Sdim  //   declaration.
1895252723Sdim  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
1896252723Sdim  if (!FD) {
1897252723Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1898252723Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
1899252723Sdim    return;
1900252723Sdim  }
1901252723Sdim
1902252723Sdim  D->addAttr(::new (S.Context)
1903252723Sdim             CXX11NoReturnAttr(Attr.getRange(), S.Context,
1904252723Sdim                               Attr.getAttributeSpellingListIndex()));
1905252723Sdim}
1906252723Sdim
1907212904Sdim// PS3 PPU-specific.
1908224145Sdimstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1909212904Sdim/*
1910212904Sdim  Returning a Vector Class in Registers
1911212904Sdim
1912218893Sdim  According to the PPU ABI specifications, a class with a single member of
1913218893Sdim  vector type is returned in memory when used as the return value of a function.
1914218893Sdim  This results in inefficient code when implementing vector classes. To return
1915218893Sdim  the value in a single vector register, add the vecreturn attribute to the
1916218893Sdim  class definition. This attribute is also applicable to struct types.
1917212904Sdim
1918212904Sdim  Example:
1919212904Sdim
1920212904Sdim  struct Vector
1921212904Sdim  {
1922212904Sdim    __vector float xyzw;
1923212904Sdim  } __attribute__((vecreturn));
1924212904Sdim
1925212904Sdim  Vector Add(Vector lhs, Vector rhs)
1926212904Sdim  {
1927212904Sdim    Vector result;
1928212904Sdim    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
1929212904Sdim    return result; // This will be returned in a register
1930212904Sdim  }
1931212904Sdim*/
1932224145Sdim  if (!isa<RecordDecl>(D)) {
1933212904Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1934221345Sdim      << Attr.getName() << ExpectedClass;
1935212904Sdim    return;
1936212904Sdim  }
1937193326Sed
1938224145Sdim  if (D->getAttr<VecReturnAttr>()) {
1939212904Sdim    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
1940212904Sdim    return;
1941212904Sdim  }
1942212904Sdim
1943224145Sdim  RecordDecl *record = cast<RecordDecl>(D);
1944218893Sdim  int count = 0;
1945218893Sdim
1946218893Sdim  if (!isa<CXXRecordDecl>(record)) {
1947218893Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1948218893Sdim    return;
1949218893Sdim  }
1950218893Sdim
1951218893Sdim  if (!cast<CXXRecordDecl>(record)->isPOD()) {
1952218893Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
1953218893Sdim    return;
1954218893Sdim  }
1955218893Sdim
1956218893Sdim  for (RecordDecl::field_iterator iter = record->field_begin();
1957218893Sdim       iter != record->field_end(); iter++) {
1958218893Sdim    if ((count == 1) || !iter->getType()->isVectorType()) {
1959218893Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1960218893Sdim      return;
1961218893Sdim    }
1962218893Sdim    count++;
1963218893Sdim  }
1964218893Sdim
1965252723Sdim  D->addAttr(::new (S.Context)
1966252723Sdim             VecReturnAttr(Attr.getRange(), S.Context,
1967252723Sdim                           Attr.getAttributeSpellingListIndex()));
1968193326Sed}
1969193326Sed
1970252723Sdimstatic void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
1971252723Sdim                                 const AttributeList &Attr) {
1972252723Sdim  if (isa<ParmVarDecl>(D)) {
1973252723Sdim    // [[carries_dependency]] can only be applied to a parameter if it is a
1974252723Sdim    // parameter of a function declaration or lambda.
1975252723Sdim    if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
1976252723Sdim      S.Diag(Attr.getLoc(),
1977252723Sdim             diag::err_carries_dependency_param_not_function_decl);
1978252723Sdim      return;
1979252723Sdim    }
1980252723Sdim  } else if (!isa<FunctionDecl>(D)) {
1981199990Srdivacky    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1982221345Sdim      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1983199990Srdivacky    return;
1984199990Srdivacky  }
1985252723Sdim
1986252723Sdim  D->addAttr(::new (S.Context) CarriesDependencyAttr(
1987252723Sdim                                   Attr.getRange(), S.Context,
1988252723Sdim                                   Attr.getAttributeSpellingListIndex()));
1989199990Srdivacky}
1990199990Srdivacky
1991224145Sdimstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1992224145Sdim  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
1993245431Sdim      !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
1994193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1995221345Sdim      << Attr.getName() << ExpectedVariableFunctionOrLabel;
1996193326Sed    return;
1997193326Sed  }
1998198092Srdivacky
1999252723Sdim  D->addAttr(::new (S.Context)
2000252723Sdim             UnusedAttr(Attr.getRange(), S.Context,
2001252723Sdim                        Attr.getAttributeSpellingListIndex()));
2002193326Sed}
2003193326Sed
2004226890Sdimstatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
2005226890Sdim                                   const AttributeList &Attr) {
2006226890Sdim  if (!isa<FunctionDecl>(D)) {
2007226890Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2008226890Sdim      << Attr.getName() << ExpectedFunction;
2009226890Sdim    return;
2010226890Sdim  }
2011226890Sdim
2012252723Sdim  D->addAttr(::new (S.Context)
2013252723Sdim             ReturnsTwiceAttr(Attr.getRange(), S.Context,
2014252723Sdim                              Attr.getAttributeSpellingListIndex()));
2015226890Sdim}
2016226890Sdim
2017224145Sdimstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2018224145Sdim  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
2019263509Sdim    if (VD->hasLocalStorage()) {
2020193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
2021193326Sed      return;
2022193326Sed    }
2023224145Sdim  } else if (!isFunctionOrMethod(D)) {
2024193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2025221345Sdim      << Attr.getName() << ExpectedVariableOrFunction;
2026193326Sed    return;
2027193326Sed  }
2028198092Srdivacky
2029252723Sdim  D->addAttr(::new (S.Context)
2030252723Sdim             UsedAttr(Attr.getRange(), S.Context,
2031252723Sdim                      Attr.getAttributeSpellingListIndex()));
2032193326Sed}
2033193326Sed
2034224145Sdimstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2035193326Sed  // check the attribute arguments.
2036221345Sdim  if (Attr.getNumArgs() > 1) {
2037221345Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
2038193326Sed    return;
2039198092Srdivacky  }
2040193326Sed
2041193326Sed  int priority = 65535; // FIXME: Do not hardcode such constants.
2042193326Sed  if (Attr.getNumArgs() > 0) {
2043263509Sdim    Expr *E = Attr.getArgAsExpr(0);
2044193326Sed    llvm::APSInt Idx(32);
2045208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2046208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2047263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2048263509Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2049263509Sdim        << E->getSourceRange();
2050193326Sed      return;
2051193326Sed    }
2052193326Sed    priority = Idx.getZExtValue();
2053193326Sed  }
2054198092Srdivacky
2055224145Sdim  if (!isa<FunctionDecl>(D)) {
2056193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2057221345Sdim      << Attr.getName() << ExpectedFunction;
2058193326Sed    return;
2059193326Sed  }
2060193326Sed
2061252723Sdim  D->addAttr(::new (S.Context)
2062252723Sdim             ConstructorAttr(Attr.getRange(), S.Context, priority,
2063252723Sdim                             Attr.getAttributeSpellingListIndex()));
2064193326Sed}
2065193326Sed
2066224145Sdimstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2067193326Sed  // check the attribute arguments.
2068221345Sdim  if (Attr.getNumArgs() > 1) {
2069221345Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
2070193326Sed    return;
2071198092Srdivacky  }
2072193326Sed
2073193326Sed  int priority = 65535; // FIXME: Do not hardcode such constants.
2074193326Sed  if (Attr.getNumArgs() > 0) {
2075263509Sdim    Expr *E = Attr.getArgAsExpr(0);
2076193326Sed    llvm::APSInt Idx(32);
2077208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2078208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2079263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2080263509Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2081263509Sdim        << E->getSourceRange();
2082193326Sed      return;
2083193326Sed    }
2084193326Sed    priority = Idx.getZExtValue();
2085193326Sed  }
2086198092Srdivacky
2087224145Sdim  if (!isa<FunctionDecl>(D)) {
2088193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2089221345Sdim      << Attr.getName() << ExpectedFunction;
2090193326Sed    return;
2091193326Sed  }
2092193326Sed
2093252723Sdim  D->addAttr(::new (S.Context)
2094252723Sdim             DestructorAttr(Attr.getRange(), S.Context, priority,
2095252723Sdim                            Attr.getAttributeSpellingListIndex()));
2096193326Sed}
2097193326Sed
2098245431Sdimtemplate <typename AttrTy>
2099263509Sdimstatic void handleAttrWithMessage(Sema &S, Decl *D,
2100263509Sdim                                  const AttributeList &Attr) {
2101219077Sdim  unsigned NumArgs = Attr.getNumArgs();
2102219077Sdim  if (NumArgs > 1) {
2103221345Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
2104193326Sed    return;
2105193326Sed  }
2106245431Sdim
2107245431Sdim  // Handle the case where the attribute has a text message.
2108226890Sdim  StringRef Str;
2109263509Sdim  if (NumArgs == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str))
2110263509Sdim    return;
2111198092Srdivacky
2112252723Sdim  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
2113252723Sdim                                      Attr.getAttributeSpellingListIndex()));
2114193326Sed}
2115193326Sed
2116224145Sdimstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
2117224145Sdim                                            const AttributeList &Attr) {
2118252723Sdim  D->addAttr(::new (S.Context)
2119252723Sdim             ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
2120252723Sdim                                       Attr.getAttributeSpellingListIndex()));
2121224145Sdim}
2122224145Sdim
2123235633Sdimstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
2124235633Sdim                                    const AttributeList &Attr) {
2125235633Sdim  if (!isa<ObjCInterfaceDecl>(D)) {
2126263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2127263509Sdim      << Attr.getName() << ExpectedObjectiveCInterface;
2128235633Sdim    return;
2129235633Sdim  }
2130235633Sdim
2131252723Sdim  D->addAttr(::new (S.Context)
2132252723Sdim             ObjCRootClassAttr(Attr.getRange(), S.Context,
2133252723Sdim                               Attr.getAttributeSpellingListIndex()));
2134235633Sdim}
2135235633Sdim
2136252723Sdimstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
2137252723Sdim                                               const AttributeList &Attr) {
2138235633Sdim  if (!isa<ObjCInterfaceDecl>(D)) {
2139235633Sdim    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
2140235633Sdim    return;
2141235633Sdim  }
2142235633Sdim
2143252723Sdim  D->addAttr(::new (S.Context)
2144252723Sdim             ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
2145252723Sdim                                          Attr.getAttributeSpellingListIndex()));
2146235633Sdim}
2147235633Sdim
2148245431Sdimstatic bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2149245431Sdim                                  IdentifierInfo *Platform,
2150245431Sdim                                  VersionTuple Introduced,
2151245431Sdim                                  VersionTuple Deprecated,
2152245431Sdim                                  VersionTuple Obsoleted) {
2153245431Sdim  StringRef PlatformName
2154245431Sdim    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2155245431Sdim  if (PlatformName.empty())
2156245431Sdim    PlatformName = Platform->getName();
2157245431Sdim
2158245431Sdim  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2159245431Sdim  // of these steps are needed).
2160245431Sdim  if (!Introduced.empty() && !Deprecated.empty() &&
2161245431Sdim      !(Introduced <= Deprecated)) {
2162245431Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2163245431Sdim      << 1 << PlatformName << Deprecated.getAsString()
2164245431Sdim      << 0 << Introduced.getAsString();
2165245431Sdim    return true;
2166245431Sdim  }
2167245431Sdim
2168245431Sdim  if (!Introduced.empty() && !Obsoleted.empty() &&
2169245431Sdim      !(Introduced <= Obsoleted)) {
2170245431Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2171245431Sdim      << 2 << PlatformName << Obsoleted.getAsString()
2172245431Sdim      << 0 << Introduced.getAsString();
2173245431Sdim    return true;
2174245431Sdim  }
2175245431Sdim
2176245431Sdim  if (!Deprecated.empty() && !Obsoleted.empty() &&
2177245431Sdim      !(Deprecated <= Obsoleted)) {
2178245431Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2179245431Sdim      << 2 << PlatformName << Obsoleted.getAsString()
2180245431Sdim      << 1 << Deprecated.getAsString();
2181245431Sdim    return true;
2182245431Sdim  }
2183245431Sdim
2184245431Sdim  return false;
2185245431Sdim}
2186245431Sdim
2187252723Sdim/// \brief Check whether the two versions match.
2188252723Sdim///
2189252723Sdim/// If either version tuple is empty, then they are assumed to match. If
2190252723Sdim/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2191252723Sdimstatic bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2192252723Sdim                          bool BeforeIsOkay) {
2193252723Sdim  if (X.empty() || Y.empty())
2194252723Sdim    return true;
2195252723Sdim
2196252723Sdim  if (X == Y)
2197252723Sdim    return true;
2198252723Sdim
2199252723Sdim  if (BeforeIsOkay && X < Y)
2200252723Sdim    return true;
2201252723Sdim
2202252723Sdim  return false;
2203252723Sdim}
2204252723Sdim
2205252723SdimAvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
2206245431Sdim                                              IdentifierInfo *Platform,
2207245431Sdim                                              VersionTuple Introduced,
2208245431Sdim                                              VersionTuple Deprecated,
2209245431Sdim                                              VersionTuple Obsoleted,
2210245431Sdim                                              bool IsUnavailable,
2211252723Sdim                                              StringRef Message,
2212252723Sdim                                              bool Override,
2213252723Sdim                                              unsigned AttrSpellingListIndex) {
2214245431Sdim  VersionTuple MergedIntroduced = Introduced;
2215245431Sdim  VersionTuple MergedDeprecated = Deprecated;
2216245431Sdim  VersionTuple MergedObsoleted = Obsoleted;
2217245431Sdim  bool FoundAny = false;
2218245431Sdim
2219245431Sdim  if (D->hasAttrs()) {
2220245431Sdim    AttrVec &Attrs = D->getAttrs();
2221245431Sdim    for (unsigned i = 0, e = Attrs.size(); i != e;) {
2222245431Sdim      const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2223245431Sdim      if (!OldAA) {
2224245431Sdim        ++i;
2225245431Sdim        continue;
2226245431Sdim      }
2227245431Sdim
2228245431Sdim      IdentifierInfo *OldPlatform = OldAA->getPlatform();
2229245431Sdim      if (OldPlatform != Platform) {
2230245431Sdim        ++i;
2231245431Sdim        continue;
2232245431Sdim      }
2233245431Sdim
2234245431Sdim      FoundAny = true;
2235245431Sdim      VersionTuple OldIntroduced = OldAA->getIntroduced();
2236245431Sdim      VersionTuple OldDeprecated = OldAA->getDeprecated();
2237245431Sdim      VersionTuple OldObsoleted = OldAA->getObsoleted();
2238245431Sdim      bool OldIsUnavailable = OldAA->getUnavailable();
2239245431Sdim
2240252723Sdim      if (!versionsMatch(OldIntroduced, Introduced, Override) ||
2241252723Sdim          !versionsMatch(Deprecated, OldDeprecated, Override) ||
2242252723Sdim          !versionsMatch(Obsoleted, OldObsoleted, Override) ||
2243252723Sdim          !(OldIsUnavailable == IsUnavailable ||
2244252723Sdim            (Override && !OldIsUnavailable && IsUnavailable))) {
2245252723Sdim        if (Override) {
2246252723Sdim          int Which = -1;
2247252723Sdim          VersionTuple FirstVersion;
2248252723Sdim          VersionTuple SecondVersion;
2249252723Sdim          if (!versionsMatch(OldIntroduced, Introduced, Override)) {
2250252723Sdim            Which = 0;
2251252723Sdim            FirstVersion = OldIntroduced;
2252252723Sdim            SecondVersion = Introduced;
2253252723Sdim          } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) {
2254252723Sdim            Which = 1;
2255252723Sdim            FirstVersion = Deprecated;
2256252723Sdim            SecondVersion = OldDeprecated;
2257252723Sdim          } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) {
2258252723Sdim            Which = 2;
2259252723Sdim            FirstVersion = Obsoleted;
2260252723Sdim            SecondVersion = OldObsoleted;
2261252723Sdim          }
2262252723Sdim
2263252723Sdim          if (Which == -1) {
2264252723Sdim            Diag(OldAA->getLocation(),
2265252723Sdim                 diag::warn_mismatched_availability_override_unavail)
2266252723Sdim              << AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2267252723Sdim          } else {
2268252723Sdim            Diag(OldAA->getLocation(),
2269252723Sdim                 diag::warn_mismatched_availability_override)
2270252723Sdim              << Which
2271252723Sdim              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2272252723Sdim              << FirstVersion.getAsString() << SecondVersion.getAsString();
2273252723Sdim          }
2274252723Sdim          Diag(Range.getBegin(), diag::note_overridden_method);
2275252723Sdim        } else {
2276252723Sdim          Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2277252723Sdim          Diag(Range.getBegin(), diag::note_previous_attribute);
2278252723Sdim        }
2279252723Sdim
2280245431Sdim        Attrs.erase(Attrs.begin() + i);
2281245431Sdim        --e;
2282245431Sdim        continue;
2283245431Sdim      }
2284245431Sdim
2285245431Sdim      VersionTuple MergedIntroduced2 = MergedIntroduced;
2286245431Sdim      VersionTuple MergedDeprecated2 = MergedDeprecated;
2287245431Sdim      VersionTuple MergedObsoleted2 = MergedObsoleted;
2288245431Sdim
2289245431Sdim      if (MergedIntroduced2.empty())
2290245431Sdim        MergedIntroduced2 = OldIntroduced;
2291245431Sdim      if (MergedDeprecated2.empty())
2292245431Sdim        MergedDeprecated2 = OldDeprecated;
2293245431Sdim      if (MergedObsoleted2.empty())
2294245431Sdim        MergedObsoleted2 = OldObsoleted;
2295245431Sdim
2296245431Sdim      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2297245431Sdim                                MergedIntroduced2, MergedDeprecated2,
2298245431Sdim                                MergedObsoleted2)) {
2299245431Sdim        Attrs.erase(Attrs.begin() + i);
2300245431Sdim        --e;
2301245431Sdim        continue;
2302245431Sdim      }
2303245431Sdim
2304245431Sdim      MergedIntroduced = MergedIntroduced2;
2305245431Sdim      MergedDeprecated = MergedDeprecated2;
2306245431Sdim      MergedObsoleted = MergedObsoleted2;
2307245431Sdim      ++i;
2308245431Sdim    }
2309245431Sdim  }
2310245431Sdim
2311245431Sdim  if (FoundAny &&
2312245431Sdim      MergedIntroduced == Introduced &&
2313245431Sdim      MergedDeprecated == Deprecated &&
2314245431Sdim      MergedObsoleted == Obsoleted)
2315245431Sdim    return NULL;
2316245431Sdim
2317252723Sdim  // Only create a new attribute if !Override, but we want to do
2318252723Sdim  // the checking.
2319245431Sdim  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
2320252723Sdim                             MergedDeprecated, MergedObsoleted) &&
2321252723Sdim      !Override) {
2322245431Sdim    return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2323245431Sdim                                            Introduced, Deprecated,
2324252723Sdim                                            Obsoleted, IsUnavailable, Message,
2325252723Sdim                                            AttrSpellingListIndex);
2326245431Sdim  }
2327245431Sdim  return NULL;
2328245431Sdim}
2329245431Sdim
2330224145Sdimstatic void handleAvailabilityAttr(Sema &S, Decl *D,
2331224145Sdim                                   const AttributeList &Attr) {
2332263509Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
2333263509Sdim    return;
2334263509Sdim  IdentifierLoc *Platform = Attr.getArgAsIdent(0);
2335252723Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2336252723Sdim
2337263509Sdim  IdentifierInfo *II = Platform->Ident;
2338263509Sdim  if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2339263509Sdim    S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2340263509Sdim      << Platform->Ident;
2341221345Sdim
2342252723Sdim  NamedDecl *ND = dyn_cast<NamedDecl>(D);
2343252723Sdim  if (!ND) {
2344252723Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2345252723Sdim    return;
2346252723Sdim  }
2347252723Sdim
2348221345Sdim  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
2349221345Sdim  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
2350221345Sdim  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
2351221345Sdim  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
2352235633Sdim  StringRef Str;
2353263509Sdim  if (const StringLiteral *SE =
2354263509Sdim          dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr()))
2355235633Sdim    Str = SE->getString();
2356245431Sdim
2357263509Sdim  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
2358245431Sdim                                                      Introduced.Version,
2359245431Sdim                                                      Deprecated.Version,
2360245431Sdim                                                      Obsoleted.Version,
2361252723Sdim                                                      IsUnavailable, Str,
2362252723Sdim                                                      /*Override=*/false,
2363252723Sdim                                                      Index);
2364245431Sdim  if (NewAttr)
2365245431Sdim    D->addAttr(NewAttr);
2366221345Sdim}
2367221345Sdim
2368252723Sdimtemplate <class T>
2369252723Sdimstatic T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
2370252723Sdim                              typename T::VisibilityType value,
2371252723Sdim                              unsigned attrSpellingListIndex) {
2372252723Sdim  T *existingAttr = D->getAttr<T>();
2373252723Sdim  if (existingAttr) {
2374252723Sdim    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2375252723Sdim    if (existingValue == value)
2376252723Sdim      return NULL;
2377252723Sdim    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2378252723Sdim    S.Diag(range.getBegin(), diag::note_previous_attribute);
2379252723Sdim    D->dropAttr<T>();
2380252723Sdim  }
2381252723Sdim  return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
2382252723Sdim}
2383252723Sdim
2384245431SdimVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
2385252723Sdim                                          VisibilityAttr::VisibilityType Vis,
2386252723Sdim                                          unsigned AttrSpellingListIndex) {
2387252723Sdim  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
2388252723Sdim                                               AttrSpellingListIndex);
2389252723Sdim}
2390252723Sdim
2391252723SdimTypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
2392252723Sdim                                      TypeVisibilityAttr::VisibilityType Vis,
2393252723Sdim                                      unsigned AttrSpellingListIndex) {
2394252723Sdim  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
2395252723Sdim                                                   AttrSpellingListIndex);
2396252723Sdim}
2397252723Sdim
2398252723Sdimstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr,
2399252723Sdim                                 bool isTypeVisibility) {
2400252723Sdim  // Visibility attributes don't mean anything on a typedef.
2401245431Sdim  if (isa<TypedefNameDecl>(D)) {
2402252723Sdim    S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored)
2403252723Sdim      << Attr.getName();
2404252723Sdim    return;
2405245431Sdim  }
2406252723Sdim
2407252723Sdim  // 'type_visibility' can only go on a type or namespace.
2408252723Sdim  if (isTypeVisibility &&
2409252723Sdim      !(isa<TagDecl>(D) ||
2410252723Sdim        isa<ObjCInterfaceDecl>(D) ||
2411252723Sdim        isa<NamespaceDecl>(D))) {
2412252723Sdim    S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2413252723Sdim      << Attr.getName() << ExpectedTypeOrNamespace;
2414252723Sdim    return;
2415245431Sdim  }
2416245431Sdim
2417263509Sdim  // Check that the argument is a string literal.
2418263509Sdim  StringRef TypeStr;
2419263509Sdim  SourceLocation LiteralLoc;
2420263509Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc))
2421193326Sed    return;
2422198092Srdivacky
2423263509Sdim  VisibilityAttr::VisibilityType type;
2424263509Sdim  if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2425263509Sdim    S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
2426263509Sdim      << Attr.getName() << TypeStr;
2427193326Sed    return;
2428193326Sed  }
2429252723Sdim
2430263509Sdim  // Complain about attempts to use protected visibility on targets
2431263509Sdim  // (like Darwin) that don't support it.
2432263509Sdim  if (type == VisibilityAttr::Protected &&
2433263509Sdim      !S.Context.getTargetInfo().hasProtectedVisibility()) {
2434263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
2435212904Sdim    type = VisibilityAttr::Default;
2436193326Sed  }
2437198092Srdivacky
2438252723Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2439252723Sdim  clang::Attr *newAttr;
2440252723Sdim  if (isTypeVisibility) {
2441252723Sdim    newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(),
2442252723Sdim                                    (TypeVisibilityAttr::VisibilityType) type,
2443252723Sdim                                        Index);
2444252723Sdim  } else {
2445252723Sdim    newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index);
2446252723Sdim  }
2447252723Sdim  if (newAttr)
2448252723Sdim    D->addAttr(newAttr);
2449193326Sed}
2450193326Sed
2451224145Sdimstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
2452224145Sdim                                       const AttributeList &Attr) {
2453221345Sdim  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
2454221345Sdim  if (!method) {
2455224145Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2456221345Sdim      << ExpectedMethod;
2457221345Sdim    return;
2458221345Sdim  }
2459221345Sdim
2460263509Sdim  if (!Attr.isArgIdent(0)) {
2461263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2462263509Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2463221345Sdim    return;
2464221345Sdim  }
2465221345Sdim
2466263509Sdim  IdentifierLoc *IL = Attr.getArgAsIdent(0);
2467263509Sdim  ObjCMethodFamilyAttr::FamilyKind F;
2468263509Sdim  if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
2469263509Sdim    S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName()
2470263509Sdim      << IL->Ident;
2471221345Sdim    return;
2472221345Sdim  }
2473221345Sdim
2474263509Sdim  if (F == ObjCMethodFamilyAttr::OMF_init &&
2475224145Sdim      !method->getResultType()->isObjCObjectPointerType()) {
2476224145Sdim    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
2477224145Sdim      << method->getResultType();
2478224145Sdim    // Ignore the attribute.
2479224145Sdim    return;
2480224145Sdim  }
2481224145Sdim
2482226890Sdim  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
2483263509Sdim                                                       S.Context, F));
2484221345Sdim}
2485221345Sdim
2486224145Sdimstatic void handleObjCExceptionAttr(Sema &S, Decl *D,
2487224145Sdim                                    const AttributeList &Attr) {
2488193326Sed  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
2489193326Sed  if (OCI == 0) {
2490263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2491263509Sdim      << Attr.getName() << ExpectedObjectiveCInterface;
2492193326Sed    return;
2493193326Sed  }
2494198092Srdivacky
2495252723Sdim  D->addAttr(::new (S.Context)
2496252723Sdim             ObjCExceptionAttr(Attr.getRange(), S.Context,
2497252723Sdim                               Attr.getAttributeSpellingListIndex()));
2498193326Sed}
2499193326Sed
2500224145Sdimstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
2501221345Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2502193326Sed    QualType T = TD->getUnderlyingType();
2503245431Sdim    if (!T->isCARCBridgableType()) {
2504193326Sed      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2505193326Sed      return;
2506193326Sed    }
2507193326Sed  }
2508245431Sdim  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2509245431Sdim    QualType T = PD->getType();
2510245431Sdim    if (!T->isCARCBridgableType()) {
2511245431Sdim      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2512245431Sdim      return;
2513245431Sdim    }
2514245431Sdim  }
2515245431Sdim  else {
2516235633Sdim    // It is okay to include this attribute on properties, e.g.:
2517235633Sdim    //
2518235633Sdim    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2519235633Sdim    //
2520235633Sdim    // In this case it follows tradition and suppresses an error in the above
2521235633Sdim    // case.
2522235633Sdim    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2523235633Sdim  }
2524252723Sdim  D->addAttr(::new (S.Context)
2525252723Sdim             ObjCNSObjectAttr(Attr.getRange(), S.Context,
2526252723Sdim                              Attr.getAttributeSpellingListIndex()));
2527193326Sed}
2528193326Sed
2529198092Srdivackystatic void
2530224145SdimhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2531193326Sed  if (!isa<FunctionDecl>(D)) {
2532193326Sed    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
2533193326Sed    return;
2534193326Sed  }
2535193326Sed
2536252723Sdim  D->addAttr(::new (S.Context)
2537252723Sdim             OverloadableAttr(Attr.getRange(), S.Context,
2538252723Sdim                              Attr.getAttributeSpellingListIndex()));
2539193326Sed}
2540193326Sed
2541224145Sdimstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2542263509Sdim  if (!Attr.isArgIdent(0)) {
2543263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2544263509Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2545193326Sed    return;
2546193326Sed  }
2547198092Srdivacky
2548263509Sdim  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
2549212904Sdim  BlocksAttr::BlockType type;
2550263509Sdim  if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
2551193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
2552263509Sdim      << Attr.getName() << II;
2553193326Sed    return;
2554193326Sed  }
2555198092Srdivacky
2556252723Sdim  D->addAttr(::new (S.Context)
2557252723Sdim             BlocksAttr(Attr.getRange(), S.Context, type,
2558252723Sdim                        Attr.getAttributeSpellingListIndex()));
2559193326Sed}
2560193326Sed
2561224145Sdimstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2562193326Sed  // check the attribute arguments.
2563193326Sed  if (Attr.getNumArgs() > 2) {
2564221345Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
2565193326Sed    return;
2566198092Srdivacky  }
2567198092Srdivacky
2568226890Sdim  unsigned sentinel = 0;
2569193326Sed  if (Attr.getNumArgs() > 0) {
2570263509Sdim    Expr *E = Attr.getArgAsExpr(0);
2571193326Sed    llvm::APSInt Idx(32);
2572208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2573208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2574263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2575263509Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2576263509Sdim        << E->getSourceRange();
2577193326Sed      return;
2578193326Sed    }
2579198092Srdivacky
2580226890Sdim    if (Idx.isSigned() && Idx.isNegative()) {
2581193326Sed      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2582193326Sed        << E->getSourceRange();
2583193326Sed      return;
2584193326Sed    }
2585226890Sdim
2586226890Sdim    sentinel = Idx.getZExtValue();
2587193326Sed  }
2588193326Sed
2589226890Sdim  unsigned nullPos = 0;
2590193326Sed  if (Attr.getNumArgs() > 1) {
2591263509Sdim    Expr *E = Attr.getArgAsExpr(1);
2592193326Sed    llvm::APSInt Idx(32);
2593208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2594208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2595263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2596263509Sdim        << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
2597263509Sdim        << E->getSourceRange();
2598193326Sed      return;
2599193326Sed    }
2600193326Sed    nullPos = Idx.getZExtValue();
2601198092Srdivacky
2602226890Sdim    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2603193326Sed      // FIXME: This error message could be improved, it would be nice
2604193326Sed      // to say what the bounds actually are.
2605193326Sed      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2606193326Sed        << E->getSourceRange();
2607193326Sed      return;
2608193326Sed    }
2609193326Sed  }
2610193326Sed
2611224145Sdim  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2612226890Sdim    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2613193326Sed    if (isa<FunctionNoProtoType>(FT)) {
2614193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2615193326Sed      return;
2616193326Sed    }
2617198092Srdivacky
2618193326Sed    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2619193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2620193326Sed      return;
2621198092Srdivacky    }
2622224145Sdim  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2623193326Sed    if (!MD->isVariadic()) {
2624193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2625193326Sed      return;
2626193326Sed    }
2627235633Sdim  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2628235633Sdim    if (!BD->isVariadic()) {
2629235633Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2630235633Sdim      return;
2631235633Sdim    }
2632224145Sdim  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
2633193326Sed    QualType Ty = V->getType();
2634193326Sed    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
2635224145Sdim      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
2636218893Sdim       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
2637193326Sed      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2638193326Sed        int m = Ty->isFunctionPointerType() ? 0 : 1;
2639193326Sed        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
2640193326Sed        return;
2641193326Sed      }
2642198092Srdivacky    } else {
2643193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2644221345Sdim        << Attr.getName() << ExpectedFunctionMethodOrBlock;
2645193326Sed      return;
2646193326Sed    }
2647193326Sed  } else {
2648193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2649221345Sdim      << Attr.getName() << ExpectedFunctionMethodOrBlock;
2650193326Sed    return;
2651193326Sed  }
2652252723Sdim  D->addAttr(::new (S.Context)
2653252723Sdim             SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
2654252723Sdim                          Attr.getAttributeSpellingListIndex()));
2655193326Sed}
2656193326Sed
2657263509Sdimstatic void handleWarnUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2658263509Sdim  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
2659263509Sdim    RD->addAttr(::new (S.Context) WarnUnusedAttr(Attr.getRange(), S.Context));
2660263509Sdim  else
2661263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2662263509Sdim}
2663263509Sdim
2664224145Sdimstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2665252723Sdim  if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {
2666193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2667252723Sdim      << Attr.getName() << ExpectedFunctionMethodOrClass;
2668193326Sed    return;
2669193326Sed  }
2670198092Srdivacky
2671206084Srdivacky  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
2672206084Srdivacky    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2673206084Srdivacky      << Attr.getName() << 0;
2674201361Srdivacky    return;
2675201361Srdivacky  }
2676206084Srdivacky  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2677206084Srdivacky    if (MD->getResultType()->isVoidType()) {
2678206084Srdivacky      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2679206084Srdivacky      << Attr.getName() << 1;
2680206084Srdivacky      return;
2681206084Srdivacky    }
2682206084Srdivacky
2683252723Sdim  D->addAttr(::new (S.Context)
2684252723Sdim             WarnUnusedResultAttr(Attr.getRange(), S.Context,
2685252723Sdim                                  Attr.getAttributeSpellingListIndex()));
2686193326Sed}
2687193326Sed
2688224145Sdimstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2689224145Sdim  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
2690235633Sdim    if (isa<CXXRecordDecl>(D)) {
2691235633Sdim      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
2692235633Sdim      return;
2693235633Sdim    }
2694224145Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2695224145Sdim      << Attr.getName() << ExpectedVariableOrFunction;
2696198092Srdivacky    return;
2697198092Srdivacky  }
2698198092Srdivacky
2699224145Sdim  NamedDecl *nd = cast<NamedDecl>(D);
2700218893Sdim
2701252723Sdim  nd->addAttr(::new (S.Context)
2702252723Sdim              WeakAttr(Attr.getRange(), S.Context,
2703252723Sdim                       Attr.getAttributeSpellingListIndex()));
2704193326Sed}
2705193326Sed
2706224145Sdimstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2707193326Sed  // weak_import only applies to variable & function declarations.
2708193326Sed  bool isDef = false;
2709221345Sdim  if (!D->canBeWeakImported(isDef)) {
2710221345Sdim    if (isDef)
2711263509Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition)
2712263509Sdim        << "weak_import";
2713221345Sdim    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2714226890Sdim             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
2715235633Sdim              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2716221345Sdim      // Nothing to warn about here.
2717221345Sdim    } else
2718207619Srdivacky      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2719221345Sdim        << Attr.getName() << ExpectedVariableOrFunction;
2720193326Sed
2721193326Sed    return;
2722193326Sed  }
2723193326Sed
2724252723Sdim  D->addAttr(::new (S.Context)
2725252723Sdim             WeakImportAttr(Attr.getRange(), S.Context,
2726252723Sdim                            Attr.getAttributeSpellingListIndex()));
2727193326Sed}
2728193326Sed
2729245431Sdim// Handles reqd_work_group_size and work_group_size_hint.
2730245431Sdimstatic void handleWorkGroupSize(Sema &S, Decl *D,
2731245431Sdim                                const AttributeList &Attr) {
2732195099Sed  unsigned WGSize[3];
2733195099Sed  for (unsigned i = 0; i < 3; ++i) {
2734263509Sdim    Expr *E = Attr.getArgAsExpr(i);
2735195099Sed    llvm::APSInt ArgNum(32);
2736208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2737208600Srdivacky        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
2738263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
2739263509Sdim        << Attr.getName() << AANT_ArgumentIntegerConstant
2740263509Sdim        << E->getSourceRange();
2741195099Sed      return;
2742195099Sed    }
2743195099Sed    WGSize[i] = (unsigned) ArgNum.getZExtValue();
2744195099Sed  }
2745245431Sdim
2746245431Sdim  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
2747245431Sdim    && D->hasAttr<ReqdWorkGroupSizeAttr>()) {
2748245431Sdim      ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>();
2749245431Sdim      if (!(A->getXDim() == WGSize[0] &&
2750245431Sdim            A->getYDim() == WGSize[1] &&
2751245431Sdim            A->getZDim() == WGSize[2])) {
2752245431Sdim        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
2753245431Sdim          Attr.getName();
2754245431Sdim      }
2755245431Sdim  }
2756245431Sdim
2757245431Sdim  if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint
2758245431Sdim    && D->hasAttr<WorkGroupSizeHintAttr>()) {
2759245431Sdim      WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>();
2760245431Sdim      if (!(A->getXDim() == WGSize[0] &&
2761245431Sdim            A->getYDim() == WGSize[1] &&
2762245431Sdim            A->getZDim() == WGSize[2])) {
2763245431Sdim        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
2764245431Sdim          Attr.getName();
2765245431Sdim      }
2766245431Sdim  }
2767245431Sdim
2768245431Sdim  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
2769245431Sdim    D->addAttr(::new (S.Context)
2770245431Sdim                 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2771252723Sdim                                       WGSize[0], WGSize[1], WGSize[2],
2772252723Sdim                                       Attr.getAttributeSpellingListIndex()));
2773245431Sdim  else
2774245431Sdim    D->addAttr(::new (S.Context)
2775245431Sdim                 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
2776252723Sdim                                       WGSize[0], WGSize[1], WGSize[2],
2777252723Sdim                                       Attr.getAttributeSpellingListIndex()));
2778195099Sed}
2779195099Sed
2780252723Sdimstatic void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
2781252723Sdim  assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
2782252723Sdim
2783263509Sdim  if (!Attr.hasParsedType()) {
2784263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
2785263509Sdim      << Attr.getName() << 1;
2786252723Sdim    return;
2787263509Sdim  }
2788252723Sdim
2789263509Sdim  TypeSourceInfo *ParmTSI = 0;
2790263509Sdim  QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI);
2791263509Sdim  assert(ParmTSI && "no type source info for attribute argument");
2792252723Sdim
2793252723Sdim  if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
2794252723Sdim      (ParmType->isBooleanType() ||
2795252723Sdim       !ParmType->isIntegralType(S.getASTContext()))) {
2796252723Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint)
2797252723Sdim        << ParmType;
2798252723Sdim    return;
2799252723Sdim  }
2800252723Sdim
2801252723Sdim  if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
2802252723Sdim      D->hasAttr<VecTypeHintAttr>()) {
2803252723Sdim    VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>();
2804263509Sdim    if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
2805252723Sdim      S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
2806252723Sdim      return;
2807252723Sdim    }
2808252723Sdim  }
2809252723Sdim
2810252723Sdim  D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
2811263509Sdim                                               ParmTSI));
2812252723Sdim}
2813252723Sdim
2814245431SdimSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
2815252723Sdim                                    StringRef Name,
2816252723Sdim                                    unsigned AttrSpellingListIndex) {
2817245431Sdim  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2818245431Sdim    if (ExistingAttr->getName() == Name)
2819245431Sdim      return NULL;
2820245431Sdim    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2821245431Sdim    Diag(Range.getBegin(), diag::note_previous_attribute);
2822245431Sdim    return NULL;
2823245431Sdim  }
2824252723Sdim  return ::new (Context) SectionAttr(Range, Context, Name,
2825252723Sdim                                     AttrSpellingListIndex);
2826245431Sdim}
2827245431Sdim
2828224145Sdimstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2829193326Sed  // Make sure that there is a string literal as the sections's single
2830193326Sed  // argument.
2831263509Sdim  StringRef Str;
2832263509Sdim  SourceLocation LiteralLoc;
2833263509Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc))
2834193326Sed    return;
2835198092Srdivacky
2836198092Srdivacky  // If the target wants to validate the section specifier, make it happen.
2837263509Sdim  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str);
2838202379Srdivacky  if (!Error.empty()) {
2839263509Sdim    S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
2840202379Srdivacky    << Error;
2841198092Srdivacky    return;
2842198092Srdivacky  }
2843198092Srdivacky
2844202379Srdivacky  // This attribute cannot be applied to local variables.
2845202379Srdivacky  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
2846263509Sdim    S.Diag(LiteralLoc, diag::err_attribute_section_local_variable);
2847202379Srdivacky    return;
2848202379Srdivacky  }
2849252723Sdim
2850252723Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2851263509Sdim  SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index);
2852245431Sdim  if (NewAttr)
2853245431Sdim    D->addAttr(NewAttr);
2854193326Sed}
2855193326Sed
2856199482Srdivacky
2857224145Sdimstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2858224145Sdim  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
2859224145Sdim    if (Existing->getLocation().isInvalid())
2860226890Sdim      Existing->setRange(Attr.getRange());
2861224145Sdim  } else {
2862252723Sdim    D->addAttr(::new (S.Context)
2863252723Sdim               NoThrowAttr(Attr.getRange(), S.Context,
2864252723Sdim                           Attr.getAttributeSpellingListIndex()));
2865224145Sdim  }
2866193326Sed}
2867193326Sed
2868224145Sdimstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2869224145Sdim  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
2870224145Sdim   if (Existing->getLocation().isInvalid())
2871226890Sdim     Existing->setRange(Attr.getRange());
2872224145Sdim  } else {
2873252723Sdim    D->addAttr(::new (S.Context)
2874252723Sdim               ConstAttr(Attr.getRange(), S.Context,
2875252723Sdim                         Attr.getAttributeSpellingListIndex() ));
2876224145Sdim  }
2877193326Sed}
2878193326Sed
2879224145Sdimstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2880252723Sdim  D->addAttr(::new (S.Context)
2881252723Sdim             PureAttr(Attr.getRange(), S.Context,
2882252723Sdim                      Attr.getAttributeSpellingListIndex()));
2883193326Sed}
2884193326Sed
2885224145Sdimstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2886224145Sdim  VarDecl *VD = dyn_cast<VarDecl>(D);
2887193326Sed  if (!VD || !VD->hasLocalStorage()) {
2888263509Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2889193326Sed    return;
2890193326Sed  }
2891198092Srdivacky
2892263509Sdim  Expr *E = Attr.getArgAsExpr(0);
2893263509Sdim  SourceLocation Loc = E->getExprLoc();
2894263509Sdim  FunctionDecl *FD = 0;
2895263509Sdim  DeclarationNameInfo NI;
2896198092Srdivacky
2897263509Sdim  // gcc only allows for simple identifiers. Since we support more than gcc, we
2898263509Sdim  // will warn the user.
2899263509Sdim  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
2900263509Sdim    if (DRE->hasQualifier())
2901263509Sdim      S.Diag(Loc, diag::warn_cleanup_ext);
2902263509Sdim    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2903263509Sdim    NI = DRE->getNameInfo();
2904263509Sdim    if (!FD) {
2905263509Sdim      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
2906263509Sdim        << NI.getName();
2907263509Sdim      return;
2908263509Sdim    }
2909263509Sdim  } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
2910263509Sdim    if (ULE->hasExplicitTemplateArgs())
2911263509Sdim      S.Diag(Loc, diag::warn_cleanup_ext);
2912263509Sdim    FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
2913263509Sdim    NI = ULE->getNameInfo();
2914263509Sdim    if (!FD) {
2915263509Sdim      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
2916263509Sdim        << NI.getName();
2917263509Sdim      if (ULE->getType() == S.Context.OverloadTy)
2918263509Sdim        S.NoteAllOverloadCandidates(ULE);
2919263509Sdim      return;
2920263509Sdim    }
2921263509Sdim  } else {
2922263509Sdim    S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
2923193326Sed    return;
2924193326Sed  }
2925193326Sed
2926193326Sed  if (FD->getNumParams() != 1) {
2927263509Sdim    S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
2928263509Sdim      << NI.getName();
2929193326Sed    return;
2930193326Sed  }
2931198092Srdivacky
2932193326Sed  // We're currently more strict than GCC about what function types we accept.
2933193326Sed  // If this ever proves to be a problem it should be easy to fix.
2934193326Sed  QualType Ty = S.Context.getPointerType(VD->getType());
2935193326Sed  QualType ParamTy = FD->getParamDecl(0)->getType();
2936218893Sdim  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2937218893Sdim                                   ParamTy, Ty) != Sema::Compatible) {
2938263509Sdim    S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
2939263509Sdim      << NI.getName() << ParamTy << Ty;
2940193326Sed    return;
2941193326Sed  }
2942198092Srdivacky
2943252723Sdim  D->addAttr(::new (S.Context)
2944252723Sdim             CleanupAttr(Attr.getRange(), S.Context, FD,
2945252723Sdim                         Attr.getAttributeSpellingListIndex()));
2946193326Sed}
2947193326Sed
2948198092Srdivacky/// Handle __attribute__((format_arg((idx)))) attribute based on
2949198092Srdivacky/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
2950224145Sdimstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2951224145Sdim  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
2952193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2953221345Sdim      << Attr.getName() << ExpectedFunction;
2954193326Sed    return;
2955193326Sed  }
2956218893Sdim
2957263509Sdim  Expr *IdxExpr = Attr.getArgAsExpr(0);
2958263509Sdim  uint64_t ArgIdx;
2959263509Sdim  if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
2960263509Sdim                                          Attr.getLoc(), 1, IdxExpr, ArgIdx))
2961193326Sed    return;
2962198092Srdivacky
2963193326Sed  // make sure the format string is really a string
2964224145Sdim  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
2965198092Srdivacky
2966193326Sed  bool not_nsstring_type = !isNSStringType(Ty, S.Context);
2967193326Sed  if (not_nsstring_type &&
2968193326Sed      !isCFStringType(Ty, S.Context) &&
2969193326Sed      (!Ty->isPointerType() ||
2970198092Srdivacky       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
2971193326Sed    // FIXME: Should highlight the actual expression that has the wrong type.
2972193326Sed    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2973198092Srdivacky    << (not_nsstring_type ? "a string type" : "an NSString")
2974193326Sed       << IdxExpr->getSourceRange();
2975193326Sed    return;
2976198092Srdivacky  }
2977224145Sdim  Ty = getFunctionOrMethodResultType(D);
2978193326Sed  if (!isNSStringType(Ty, S.Context) &&
2979193326Sed      !isCFStringType(Ty, S.Context) &&
2980193326Sed      (!Ty->isPointerType() ||
2981198092Srdivacky       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
2982193326Sed    // FIXME: Should highlight the actual expression that has the wrong type.
2983193326Sed    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2984198092Srdivacky    << (not_nsstring_type ? "string type" : "NSString")
2985193326Sed       << IdxExpr->getSourceRange();
2986193326Sed    return;
2987198092Srdivacky  }
2988198092Srdivacky
2989263509Sdim  // We cannot use the ArgIdx returned from checkFunctionOrMethodArgumentIndex
2990263509Sdim  // because that has corrected for the implicit this parameter, and is zero-
2991263509Sdim  // based.  The attribute expects what the user wrote explicitly.
2992263509Sdim  llvm::APSInt Val;
2993263509Sdim  IdxExpr->EvaluateAsInt(Val, S.Context);
2994263509Sdim
2995252723Sdim  D->addAttr(::new (S.Context)
2996263509Sdim             FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(),
2997252723Sdim                           Attr.getAttributeSpellingListIndex()));
2998193326Sed}
2999193326Sed
3000198398Srdivackyenum FormatAttrKind {
3001198398Srdivacky  CFStringFormat,
3002198398Srdivacky  NSStringFormat,
3003198398Srdivacky  StrftimeFormat,
3004198398Srdivacky  SupportedFormat,
3005206084Srdivacky  IgnoredFormat,
3006198398Srdivacky  InvalidFormat
3007198398Srdivacky};
3008198398Srdivacky
3009198398Srdivacky/// getFormatAttrKind - Map from format attribute names to supported format
3010198398Srdivacky/// types.
3011226890Sdimstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
3012245431Sdim  return llvm::StringSwitch<FormatAttrKind>(Format)
3013245431Sdim    // Check for formats that get handled specially.
3014245431Sdim    .Case("NSString", NSStringFormat)
3015245431Sdim    .Case("CFString", CFStringFormat)
3016245431Sdim    .Case("strftime", StrftimeFormat)
3017198398Srdivacky
3018245431Sdim    // Otherwise, check for supported formats.
3019245431Sdim    .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
3020245431Sdim    .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
3021245431Sdim    .Case("kprintf", SupportedFormat) // OpenBSD.
3022198398Srdivacky
3023245431Sdim    .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
3024245431Sdim    .Default(InvalidFormat);
3025198398Srdivacky}
3026198398Srdivacky
3027210299Sed/// Handle __attribute__((init_priority(priority))) attributes based on
3028210299Sed/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3029224145Sdimstatic void handleInitPriorityAttr(Sema &S, Decl *D,
3030224145Sdim                                   const AttributeList &Attr) {
3031235633Sdim  if (!S.getLangOpts().CPlusPlus) {
3032210299Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
3033210299Sed    return;
3034210299Sed  }
3035210299Sed
3036224145Sdim  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
3037210299Sed    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
3038210299Sed    Attr.setInvalid();
3039210299Sed    return;
3040210299Sed  }
3041224145Sdim  QualType T = dyn_cast<VarDecl>(D)->getType();
3042210299Sed  if (S.Context.getAsArrayType(T))
3043210299Sed    T = S.Context.getBaseElementType(T);
3044210299Sed  if (!T->getAs<RecordType>()) {
3045210299Sed    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
3046210299Sed    Attr.setInvalid();
3047210299Sed    return;
3048210299Sed  }
3049210299Sed
3050263509Sdim  Expr *priorityExpr = Attr.getArgAsExpr(0);
3051210299Sed
3052210299Sed  llvm::APSInt priority(32);
3053210299Sed  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
3054210299Sed      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
3055263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3056263509Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
3057263509Sdim      << priorityExpr->getSourceRange();
3058210299Sed    Attr.setInvalid();
3059210299Sed    return;
3060210299Sed  }
3061210299Sed  unsigned prioritynum = priority.getZExtValue();
3062210299Sed  if (prioritynum < 101 || prioritynum > 65535) {
3063210299Sed    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
3064210299Sed    <<  priorityExpr->getSourceRange();
3065210299Sed    Attr.setInvalid();
3066210299Sed    return;
3067210299Sed  }
3068252723Sdim  D->addAttr(::new (S.Context)
3069252723Sdim             InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
3070252723Sdim                              Attr.getAttributeSpellingListIndex()));
3071210299Sed}
3072210299Sed
3073263509SdimFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
3074263509Sdim                                  IdentifierInfo *Format, int FormatIdx,
3075263509Sdim                                  int FirstArg,
3076252723Sdim                                  unsigned AttrSpellingListIndex) {
3077245431Sdim  // Check whether we already have an equivalent format attribute.
3078245431Sdim  for (specific_attr_iterator<FormatAttr>
3079245431Sdim         i = D->specific_attr_begin<FormatAttr>(),
3080245431Sdim         e = D->specific_attr_end<FormatAttr>();
3081245431Sdim       i != e ; ++i) {
3082245431Sdim    FormatAttr *f = *i;
3083245431Sdim    if (f->getType() == Format &&
3084245431Sdim        f->getFormatIdx() == FormatIdx &&
3085245431Sdim        f->getFirstArg() == FirstArg) {
3086245431Sdim      // If we don't have a valid location for this attribute, adopt the
3087245431Sdim      // location.
3088245431Sdim      if (f->getLocation().isInvalid())
3089245431Sdim        f->setRange(Range);
3090245431Sdim      return NULL;
3091245431Sdim    }
3092245431Sdim  }
3093245431Sdim
3094263509Sdim  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
3095263509Sdim                                    FirstArg, AttrSpellingListIndex);
3096245431Sdim}
3097245431Sdim
3098198092Srdivacky/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
3099198092Srdivacky/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3100224145Sdimstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3101263509Sdim  if (!Attr.isArgIdent(0)) {
3102263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3103263509Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
3104193326Sed    return;
3105193326Sed  }
3106193326Sed
3107224145Sdim  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
3108193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3109221345Sdim      << Attr.getName() << ExpectedFunction;
3110193326Sed    return;
3111193326Sed  }
3112193326Sed
3113218893Sdim  // In C++ the implicit 'this' function parameter also counts, and they are
3114218893Sdim  // counted from one.
3115224145Sdim  bool HasImplicitThisParam = isInstanceMethod(D);
3116224145Sdim  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
3117193326Sed  unsigned FirstIdx = 1;
3118193326Sed
3119263509Sdim  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
3120263509Sdim  StringRef Format = II->getName();
3121193326Sed
3122193326Sed  // Normalize the argument, __foo__ becomes foo.
3123263509Sdim  if (Format.startswith("__") && Format.endswith("__")) {
3124198398Srdivacky    Format = Format.substr(2, Format.size() - 4);
3125263509Sdim    // If we've modified the string name, we need a new identifier for it.
3126263509Sdim    II = &S.Context.Idents.get(Format);
3127263509Sdim  }
3128193326Sed
3129198398Srdivacky  // Check for supported formats.
3130198398Srdivacky  FormatAttrKind Kind = getFormatAttrKind(Format);
3131206084Srdivacky
3132206084Srdivacky  if (Kind == IgnoredFormat)
3133206084Srdivacky    return;
3134206084Srdivacky
3135198398Srdivacky  if (Kind == InvalidFormat) {
3136193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
3137263509Sdim      << "format" << II->getName();
3138193326Sed    return;
3139193326Sed  }
3140193326Sed
3141193326Sed  // checks for the 2nd argument
3142263509Sdim  Expr *IdxExpr = Attr.getArgAsExpr(1);
3143193326Sed  llvm::APSInt Idx(32);
3144208600Srdivacky  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
3145208600Srdivacky      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
3146263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3147263509Sdim      << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
3148263509Sdim      << IdxExpr->getSourceRange();
3149193326Sed    return;
3150193326Sed  }
3151193326Sed
3152193326Sed  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
3153193326Sed    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
3154193326Sed      << "format" << 2 << IdxExpr->getSourceRange();
3155193326Sed    return;
3156193326Sed  }
3157193326Sed
3158193326Sed  // FIXME: Do we need to bounds check?
3159193326Sed  unsigned ArgIdx = Idx.getZExtValue() - 1;
3160198092Srdivacky
3161199482Srdivacky  if (HasImplicitThisParam) {
3162199482Srdivacky    if (ArgIdx == 0) {
3163218893Sdim      S.Diag(Attr.getLoc(),
3164218893Sdim             diag::err_format_attribute_implicit_this_format_string)
3165218893Sdim        << IdxExpr->getSourceRange();
3166199482Srdivacky      return;
3167199482Srdivacky    }
3168199482Srdivacky    ArgIdx--;
3169199482Srdivacky  }
3170198092Srdivacky
3171193326Sed  // make sure the format string is really a string
3172224145Sdim  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
3173193326Sed
3174198398Srdivacky  if (Kind == CFStringFormat) {
3175193326Sed    if (!isCFStringType(Ty, S.Context)) {
3176193326Sed      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3177193326Sed        << "a CFString" << IdxExpr->getSourceRange();
3178193326Sed      return;
3179193326Sed    }
3180198398Srdivacky  } else if (Kind == NSStringFormat) {
3181193326Sed    // FIXME: do we need to check if the type is NSString*?  What are the
3182193326Sed    // semantics?
3183193326Sed    if (!isNSStringType(Ty, S.Context)) {
3184193326Sed      // FIXME: Should highlight the actual expression that has the wrong type.
3185193326Sed      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3186193326Sed        << "an NSString" << IdxExpr->getSourceRange();
3187193326Sed      return;
3188198092Srdivacky    }
3189193326Sed  } else if (!Ty->isPointerType() ||
3190198092Srdivacky             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
3191193326Sed    // FIXME: Should highlight the actual expression that has the wrong type.
3192193326Sed    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
3193193326Sed      << "a string type" << IdxExpr->getSourceRange();
3194193326Sed    return;
3195193326Sed  }
3196193326Sed
3197193326Sed  // check the 3rd argument
3198263509Sdim  Expr *FirstArgExpr = Attr.getArgAsExpr(2);
3199193326Sed  llvm::APSInt FirstArg(32);
3200208600Srdivacky  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
3201208600Srdivacky      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
3202263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3203263509Sdim      << Attr.getName() << 3 << AANT_ArgumentIntegerConstant
3204263509Sdim      << FirstArgExpr->getSourceRange();
3205193326Sed    return;
3206193326Sed  }
3207193326Sed
3208193326Sed  // check if the function is variadic if the 3rd argument non-zero
3209193326Sed  if (FirstArg != 0) {
3210224145Sdim    if (isFunctionOrMethodVariadic(D)) {
3211193326Sed      ++NumArgs; // +1 for ...
3212193326Sed    } else {
3213224145Sdim      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
3214193326Sed      return;
3215193326Sed    }
3216193326Sed  }
3217193326Sed
3218193326Sed  // strftime requires FirstArg to be 0 because it doesn't read from any
3219193326Sed  // variable the input is just the current time + the format string.
3220198398Srdivacky  if (Kind == StrftimeFormat) {
3221193326Sed    if (FirstArg != 0) {
3222193326Sed      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
3223193326Sed        << FirstArgExpr->getSourceRange();
3224193326Sed      return;
3225193326Sed    }
3226193326Sed  // if 0 it disables parameter checking (to use with e.g. va_list)
3227193326Sed  } else if (FirstArg != 0 && FirstArg != NumArgs) {
3228193326Sed    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
3229193326Sed      << "format" << 3 << FirstArgExpr->getSourceRange();
3230193326Sed    return;
3231193326Sed  }
3232193326Sed
3233263509Sdim  FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II,
3234212904Sdim                                          Idx.getZExtValue(),
3235252723Sdim                                          FirstArg.getZExtValue(),
3236252723Sdim                                          Attr.getAttributeSpellingListIndex());
3237245431Sdim  if (NewAttr)
3238245431Sdim    D->addAttr(NewAttr);
3239193326Sed}
3240193326Sed
3241224145Sdimstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
3242224145Sdim                                       const AttributeList &Attr) {
3243193326Sed  // Try to find the underlying union declaration.
3244193326Sed  RecordDecl *RD = 0;
3245224145Sdim  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
3246193326Sed  if (TD && TD->getUnderlyingType()->isUnionType())
3247193326Sed    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
3248193326Sed  else
3249224145Sdim    RD = dyn_cast<RecordDecl>(D);
3250193326Sed
3251193326Sed  if (!RD || !RD->isUnion()) {
3252193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3253221345Sdim      << Attr.getName() << ExpectedUnion;
3254193326Sed    return;
3255193326Sed  }
3256193326Sed
3257226890Sdim  if (!RD->isCompleteDefinition()) {
3258198092Srdivacky    S.Diag(Attr.getLoc(),
3259193326Sed        diag::warn_transparent_union_attribute_not_definition);
3260193326Sed    return;
3261193326Sed  }
3262193326Sed
3263195341Sed  RecordDecl::field_iterator Field = RD->field_begin(),
3264195341Sed                          FieldEnd = RD->field_end();
3265193326Sed  if (Field == FieldEnd) {
3266193326Sed    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
3267193326Sed    return;
3268193326Sed  }
3269193326Sed
3270193326Sed  FieldDecl *FirstField = *Field;
3271193326Sed  QualType FirstType = FirstField->getType();
3272210299Sed  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
3273198092Srdivacky    S.Diag(FirstField->getLocation(),
3274210299Sed           diag::warn_transparent_union_attribute_floating)
3275210299Sed      << FirstType->isVectorType() << FirstType;
3276193326Sed    return;
3277193326Sed  }
3278193326Sed
3279193326Sed  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
3280193326Sed  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
3281193326Sed  for (; Field != FieldEnd; ++Field) {
3282193326Sed    QualType FieldType = Field->getType();
3283193326Sed    if (S.Context.getTypeSize(FieldType) != FirstSize ||
3284193326Sed        S.Context.getTypeAlign(FieldType) != FirstAlign) {
3285193326Sed      // Warn if we drop the attribute.
3286193326Sed      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
3287198092Srdivacky      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
3288193326Sed                                 : S.Context.getTypeAlign(FieldType);
3289198092Srdivacky      S.Diag(Field->getLocation(),
3290193326Sed          diag::warn_transparent_union_attribute_field_size_align)
3291193326Sed        << isSize << Field->getDeclName() << FieldBits;
3292193326Sed      unsigned FirstBits = isSize? FirstSize : FirstAlign;
3293198092Srdivacky      S.Diag(FirstField->getLocation(),
3294193326Sed             diag::note_transparent_union_first_field_size_align)
3295193326Sed        << isSize << FirstBits;
3296193326Sed      return;
3297193326Sed    }
3298193326Sed  }
3299193326Sed
3300252723Sdim  RD->addAttr(::new (S.Context)
3301252723Sdim              TransparentUnionAttr(Attr.getRange(), S.Context,
3302252723Sdim                                   Attr.getAttributeSpellingListIndex()));
3303193326Sed}
3304193326Sed
3305224145Sdimstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3306193326Sed  // Make sure that there is a string literal as the annotation's single
3307193326Sed  // argument.
3308263509Sdim  StringRef Str;
3309263509Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
3310193326Sed    return;
3311226890Sdim
3312226890Sdim  // Don't duplicate annotations that are already set.
3313226890Sdim  for (specific_attr_iterator<AnnotateAttr>
3314226890Sdim       i = D->specific_attr_begin<AnnotateAttr>(),
3315226890Sdim       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
3316263509Sdim    if ((*i)->getAnnotation() == Str)
3317263509Sdim      return;
3318226890Sdim  }
3319252723Sdim
3320252723Sdim  D->addAttr(::new (S.Context)
3321263509Sdim             AnnotateAttr(Attr.getRange(), S.Context, Str,
3322252723Sdim                          Attr.getAttributeSpellingListIndex()));
3323193326Sed}
3324193326Sed
3325224145Sdimstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3326193326Sed  // check the attribute arguments.
3327193326Sed  if (Attr.getNumArgs() > 1) {
3328263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
3329263509Sdim      << Attr.getName() << 1;
3330193326Sed    return;
3331193326Sed  }
3332245431Sdim
3333193326Sed  if (Attr.getNumArgs() == 0) {
3334252723Sdim    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
3335252723Sdim               true, 0, Attr.getAttributeSpellingListIndex()));
3336193326Sed    return;
3337193326Sed  }
3338198092Srdivacky
3339263509Sdim  Expr *E = Attr.getArgAsExpr(0);
3340252723Sdim  if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
3341252723Sdim    S.Diag(Attr.getEllipsisLoc(),
3342252723Sdim           diag::err_pack_expansion_without_parameter_packs);
3343252723Sdim    return;
3344252723Sdim  }
3345210299Sed
3346252723Sdim  if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
3347235633Sdim    return;
3348235633Sdim
3349252723Sdim  S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(),
3350252723Sdim                   Attr.isPackExpansion());
3351252723Sdim}
3352252723Sdim
3353252723Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
3354252723Sdim                          unsigned SpellingListIndex, bool IsPackExpansion) {
3355252723Sdim  AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex);
3356252723Sdim  SourceLocation AttrLoc = AttrRange.getBegin();
3357252723Sdim
3358252723Sdim  // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
3359252723Sdim  if (TmpAttr.isAlignas()) {
3360252723Sdim    // C++11 [dcl.align]p1:
3361252723Sdim    //   An alignment-specifier may be applied to a variable or to a class
3362252723Sdim    //   data member, but it shall not be applied to a bit-field, a function
3363252723Sdim    //   parameter, the formal parameter of a catch clause, or a variable
3364252723Sdim    //   declared with the register storage class specifier. An
3365252723Sdim    //   alignment-specifier may also be applied to the declaration of a class
3366252723Sdim    //   or enumeration type.
3367252723Sdim    // C11 6.7.5/2:
3368252723Sdim    //   An alignment attribute shall not be specified in a declaration of
3369252723Sdim    //   a typedef, or a bit-field, or a function, or a parameter, or an
3370252723Sdim    //   object declared with the register storage-class specifier.
3371252723Sdim    int DiagKind = -1;
3372252723Sdim    if (isa<ParmVarDecl>(D)) {
3373252723Sdim      DiagKind = 0;
3374252723Sdim    } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3375252723Sdim      if (VD->getStorageClass() == SC_Register)
3376252723Sdim        DiagKind = 1;
3377252723Sdim      if (VD->isExceptionVariable())
3378252723Sdim        DiagKind = 2;
3379252723Sdim    } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
3380252723Sdim      if (FD->isBitField())
3381252723Sdim        DiagKind = 3;
3382252723Sdim    } else if (!isa<TagDecl>(D)) {
3383252723Sdim      Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
3384252723Sdim        << (TmpAttr.isC11() ? "'_Alignas'" : "'alignas'")
3385252723Sdim        << (TmpAttr.isC11() ? ExpectedVariableOrField
3386252723Sdim                            : ExpectedVariableFieldOrTag);
3387252723Sdim      return;
3388252723Sdim    }
3389252723Sdim    if (DiagKind != -1) {
3390252723Sdim      Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
3391252723Sdim        << TmpAttr.isC11() << DiagKind;
3392252723Sdim      return;
3393252723Sdim    }
3394252723Sdim  }
3395252723Sdim
3396210299Sed  if (E->isTypeDependent() || E->isValueDependent()) {
3397210299Sed    // Save dependent expressions in the AST to be instantiated.
3398252723Sdim    AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
3399252723Sdim    AA->setPackExpansion(IsPackExpansion);
3400252723Sdim    D->addAttr(AA);
3401210299Sed    return;
3402210299Sed  }
3403252723Sdim
3404212904Sdim  // FIXME: Cache the number on the Attr object?
3405193326Sed  llvm::APSInt Alignment(32);
3406245431Sdim  ExprResult ICE
3407245431Sdim    = VerifyIntegerConstantExpression(E, &Alignment,
3408245431Sdim        diag::err_aligned_attribute_argument_not_int,
3409245431Sdim        /*AllowFold*/ false);
3410235633Sdim  if (ICE.isInvalid())
3411193326Sed    return;
3412252723Sdim
3413252723Sdim  // C++11 [dcl.align]p2:
3414252723Sdim  //   -- if the constant expression evaluates to zero, the alignment
3415252723Sdim  //      specifier shall have no effect
3416252723Sdim  // C11 6.7.5p6:
3417252723Sdim  //   An alignment specification of zero has no effect.
3418252723Sdim  if (!(TmpAttr.isAlignas() && !Alignment) &&
3419252723Sdim      !llvm::isPowerOf2_64(Alignment.getZExtValue())) {
3420210299Sed    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
3421210299Sed      << E->getSourceRange();
3422193326Sed    return;
3423193326Sed  }
3424252723Sdim
3425252723Sdim  if (TmpAttr.isDeclspec()) {
3426245431Sdim    // We've already verified it's a power of 2, now let's make sure it's
3427245431Sdim    // 8192 or less.
3428245431Sdim    if (Alignment.getZExtValue() > 8192) {
3429252723Sdim      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
3430245431Sdim        << E->getSourceRange();
3431245431Sdim      return;
3432245431Sdim    }
3433245431Sdim  }
3434193326Sed
3435252723Sdim  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
3436252723Sdim                                                ICE.take(), SpellingListIndex);
3437252723Sdim  AA->setPackExpansion(IsPackExpansion);
3438252723Sdim  D->addAttr(AA);
3439193326Sed}
3440193326Sed
3441252723Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
3442252723Sdim                          unsigned SpellingListIndex, bool IsPackExpansion) {
3443212904Sdim  // FIXME: Cache the number on the Attr object if non-dependent?
3444212904Sdim  // FIXME: Perform checking of type validity
3445252723Sdim  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS,
3446252723Sdim                                                SpellingListIndex);
3447252723Sdim  AA->setPackExpansion(IsPackExpansion);
3448252723Sdim  D->addAttr(AA);
3449212904Sdim}
3450212904Sdim
3451252723Sdimvoid Sema::CheckAlignasUnderalignment(Decl *D) {
3452252723Sdim  assert(D->hasAttrs() && "no attributes on decl");
3453252723Sdim
3454252723Sdim  QualType Ty;
3455252723Sdim  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3456252723Sdim    Ty = VD->getType();
3457252723Sdim  else
3458252723Sdim    Ty = Context.getTagDeclType(cast<TagDecl>(D));
3459252723Sdim  if (Ty->isDependentType() || Ty->isIncompleteType())
3460252723Sdim    return;
3461252723Sdim
3462252723Sdim  // C++11 [dcl.align]p5, C11 6.7.5/4:
3463252723Sdim  //   The combined effect of all alignment attributes in a declaration shall
3464252723Sdim  //   not specify an alignment that is less strict than the alignment that
3465252723Sdim  //   would otherwise be required for the entity being declared.
3466252723Sdim  AlignedAttr *AlignasAttr = 0;
3467252723Sdim  unsigned Align = 0;
3468252723Sdim  for (specific_attr_iterator<AlignedAttr>
3469252723Sdim         I = D->specific_attr_begin<AlignedAttr>(),
3470252723Sdim         E = D->specific_attr_end<AlignedAttr>(); I != E; ++I) {
3471252723Sdim    if (I->isAlignmentDependent())
3472252723Sdim      return;
3473252723Sdim    if (I->isAlignas())
3474252723Sdim      AlignasAttr = *I;
3475252723Sdim    Align = std::max(Align, I->getAlignment(Context));
3476252723Sdim  }
3477252723Sdim
3478252723Sdim  if (AlignasAttr && Align) {
3479252723Sdim    CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
3480252723Sdim    CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty);
3481252723Sdim    if (NaturalAlign > RequestedAlign)
3482252723Sdim      Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
3483252723Sdim        << Ty << (unsigned)NaturalAlign.getQuantity();
3484252723Sdim  }
3485252723Sdim}
3486252723Sdim
3487224145Sdim/// handleModeAttr - This attribute modifies the width of a decl with primitive
3488198092Srdivacky/// type.
3489193326Sed///
3490198092Srdivacky/// Despite what would be logical, the mode attribute is a decl attribute, not a
3491198092Srdivacky/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
3492198092Srdivacky/// HImode, not an intermediate pointer.
3493224145Sdimstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3494193326Sed  // This attribute isn't documented, but glibc uses it.  It changes
3495193326Sed  // the width of an int or unsigned int to the specified size.
3496263509Sdim  if (!Attr.isArgIdent(0)) {
3497263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
3498263509Sdim      << AANT_ArgumentIdentifier;
3499193326Sed    return;
3500193326Sed  }
3501263509Sdim
3502263509Sdim  IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident;
3503263509Sdim  StringRef Str = Name->getName();
3504193326Sed
3505193326Sed  // Normalize the attribute name, __foo__ becomes foo.
3506198398Srdivacky  if (Str.startswith("__") && Str.endswith("__"))
3507198398Srdivacky    Str = Str.substr(2, Str.size() - 4);
3508193326Sed
3509193326Sed  unsigned DestWidth = 0;
3510193326Sed  bool IntegerMode = true;
3511193326Sed  bool ComplexMode = false;
3512198398Srdivacky  switch (Str.size()) {
3513193326Sed  case 2:
3514193326Sed    switch (Str[0]) {
3515193326Sed    case 'Q': DestWidth = 8; break;
3516193326Sed    case 'H': DestWidth = 16; break;
3517193326Sed    case 'S': DestWidth = 32; break;
3518193326Sed    case 'D': DestWidth = 64; break;
3519193326Sed    case 'X': DestWidth = 96; break;
3520193326Sed    case 'T': DestWidth = 128; break;
3521193326Sed    }
3522193326Sed    if (Str[1] == 'F') {
3523193326Sed      IntegerMode = false;
3524193326Sed    } else if (Str[1] == 'C') {
3525193326Sed      IntegerMode = false;
3526193326Sed      ComplexMode = true;
3527193326Sed    } else if (Str[1] != 'I') {
3528193326Sed      DestWidth = 0;
3529193326Sed    }
3530193326Sed    break;
3531193326Sed  case 4:
3532193326Sed    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3533193326Sed    // pointer on PIC16 and other embedded platforms.
3534198398Srdivacky    if (Str == "word")
3535226890Sdim      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3536198398Srdivacky    else if (Str == "byte")
3537226890Sdim      DestWidth = S.Context.getTargetInfo().getCharWidth();
3538193326Sed    break;
3539193326Sed  case 7:
3540198398Srdivacky    if (Str == "pointer")
3541226890Sdim      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3542193326Sed    break;
3543252723Sdim  case 11:
3544252723Sdim    if (Str == "unwind_word")
3545252723Sdim      DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
3546252723Sdim    break;
3547193326Sed  }
3548193326Sed
3549193326Sed  QualType OldTy;
3550221345Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3551193326Sed    OldTy = TD->getUnderlyingType();
3552193326Sed  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3553193326Sed    OldTy = VD->getType();
3554193326Sed  else {
3555193326Sed    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
3556226890Sdim      << "mode" << Attr.getRange();
3557193326Sed    return;
3558193326Sed  }
3559193326Sed
3560198092Srdivacky  if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType())
3561193326Sed    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
3562193326Sed  else if (IntegerMode) {
3563210299Sed    if (!OldTy->isIntegralOrEnumerationType())
3564193326Sed      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3565193326Sed  } else if (ComplexMode) {
3566193326Sed    if (!OldTy->isComplexType())
3567193326Sed      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3568193326Sed  } else {
3569193326Sed    if (!OldTy->isFloatingType())
3570193326Sed      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3571193326Sed  }
3572193326Sed
3573193326Sed  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3574193326Sed  // and friends, at least with glibc.
3575193326Sed  // FIXME: Make sure floating-point mappings are accurate
3576193326Sed  // FIXME: Support XF and TF types
3577263509Sdim  if (!DestWidth) {
3578193326Sed    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
3579193326Sed    return;
3580263509Sdim  }
3581263509Sdim
3582263509Sdim  QualType NewTy;
3583263509Sdim
3584263509Sdim  if (IntegerMode)
3585263509Sdim    NewTy = S.Context.getIntTypeForBitwidth(DestWidth,
3586263509Sdim                                            OldTy->isSignedIntegerType());
3587263509Sdim  else
3588263509Sdim    NewTy = S.Context.getRealTypeForBitwidth(DestWidth);
3589263509Sdim
3590263509Sdim  if (NewTy.isNull()) {
3591193326Sed    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
3592193326Sed    return;
3593193326Sed  }
3594193326Sed
3595193326Sed  if (ComplexMode) {
3596193326Sed    NewTy = S.Context.getComplexType(NewTy);
3597193326Sed  }
3598193326Sed
3599193326Sed  // Install the new type.
3600263509Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3601263509Sdim    TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
3602263509Sdim  else
3603193326Sed    cast<ValueDecl>(D)->setType(NewTy);
3604263509Sdim
3605263509Sdim  D->addAttr(::new (S.Context)
3606263509Sdim             ModeAttr(Attr.getRange(), S.Context, Name,
3607263509Sdim                      Attr.getAttributeSpellingListIndex()));
3608193326Sed}
3609193326Sed
3610224145Sdimstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3611245431Sdim  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3612245431Sdim    if (!VD->hasGlobalStorage())
3613245431Sdim      S.Diag(Attr.getLoc(),
3614245431Sdim             diag::warn_attribute_requires_functions_or_static_globals)
3615245431Sdim        << Attr.getName();
3616245431Sdim  } else if (!isFunctionOrMethod(D)) {
3617245431Sdim    S.Diag(Attr.getLoc(),
3618245431Sdim           diag::warn_attribute_requires_functions_or_static_globals)
3619245431Sdim      << Attr.getName();
3620193326Sed    return;
3621193326Sed  }
3622198092Srdivacky
3623252723Sdim  D->addAttr(::new (S.Context)
3624252723Sdim             NoDebugAttr(Attr.getRange(), S.Context,
3625252723Sdim                         Attr.getAttributeSpellingListIndex()));
3626193326Sed}
3627193326Sed
3628224145Sdimstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3629224145Sdim  if (!isa<FunctionDecl>(D)) {
3630193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3631221345Sdim      << Attr.getName() << ExpectedFunction;
3632193326Sed    return;
3633193326Sed  }
3634198092Srdivacky
3635252723Sdim  D->addAttr(::new (S.Context)
3636252723Sdim             NoInlineAttr(Attr.getRange(), S.Context,
3637252723Sdim             Attr.getAttributeSpellingListIndex()));
3638193326Sed}
3639193326Sed
3640224145Sdimstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
3641224145Sdim                                           const AttributeList &Attr) {
3642224145Sdim  if (!isa<FunctionDecl>(D)) {
3643210299Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3644221345Sdim      << Attr.getName() << ExpectedFunction;
3645210299Sed    return;
3646210299Sed  }
3647210299Sed
3648252723Sdim  D->addAttr(::new (S.Context)
3649252723Sdim             NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
3650252723Sdim                                      Attr.getAttributeSpellingListIndex()));
3651210299Sed}
3652210299Sed
3653224145Sdimstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3654218893Sdim  if (S.LangOpts.CUDA) {
3655224145Sdim    if (!isa<VarDecl>(D)) {
3656218893Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3657221345Sdim        << Attr.getName() << ExpectedVariable;
3658218893Sdim      return;
3659218893Sdim    }
3660218893Sdim
3661252723Sdim    D->addAttr(::new (S.Context)
3662252723Sdim               CUDAConstantAttr(Attr.getRange(), S.Context,
3663252723Sdim                                Attr.getAttributeSpellingListIndex()));
3664218893Sdim  } else {
3665218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
3666218893Sdim  }
3667218893Sdim}
3668218893Sdim
3669224145Sdimstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3670218893Sdim  if (S.LangOpts.CUDA) {
3671218893Sdim    // check the attribute arguments.
3672218893Sdim    if (Attr.getNumArgs() != 0) {
3673263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
3674263509Sdim        << Attr.getName() << 0;
3675218893Sdim      return;
3676218893Sdim    }
3677218893Sdim
3678224145Sdim    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
3679218893Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3680221345Sdim        << Attr.getName() << ExpectedVariableOrFunction;
3681218893Sdim      return;
3682218893Sdim    }
3683218893Sdim
3684252723Sdim    D->addAttr(::new (S.Context)
3685252723Sdim               CUDADeviceAttr(Attr.getRange(), S.Context,
3686252723Sdim                              Attr.getAttributeSpellingListIndex()));
3687218893Sdim  } else {
3688218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
3689218893Sdim  }
3690218893Sdim}
3691218893Sdim
3692224145Sdimstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3693218893Sdim  if (S.LangOpts.CUDA) {
3694224145Sdim    if (!isa<FunctionDecl>(D)) {
3695218893Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3696221345Sdim        << Attr.getName() << ExpectedFunction;
3697218893Sdim      return;
3698218893Sdim    }
3699218893Sdim
3700224145Sdim    FunctionDecl *FD = cast<FunctionDecl>(D);
3701218893Sdim    if (!FD->getResultType()->isVoidType()) {
3702218893Sdim      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
3703252723Sdim      if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
3704218893Sdim        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3705218893Sdim          << FD->getType()
3706252723Sdim          << FixItHint::CreateReplacement(FTL.getResultLoc().getSourceRange(),
3707218893Sdim                                          "void");
3708218893Sdim      } else {
3709218893Sdim        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3710218893Sdim          << FD->getType();
3711218893Sdim      }
3712218893Sdim      return;
3713218893Sdim    }
3714218893Sdim
3715252723Sdim    D->addAttr(::new (S.Context)
3716252723Sdim               CUDAGlobalAttr(Attr.getRange(), S.Context,
3717252723Sdim                              Attr.getAttributeSpellingListIndex()));
3718218893Sdim  } else {
3719218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
3720218893Sdim  }
3721218893Sdim}
3722218893Sdim
3723224145Sdimstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3724218893Sdim  if (S.LangOpts.CUDA) {
3725224145Sdim    if (!isa<FunctionDecl>(D)) {
3726218893Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3727221345Sdim        << Attr.getName() << ExpectedFunction;
3728218893Sdim      return;
3729218893Sdim    }
3730218893Sdim
3731252723Sdim    D->addAttr(::new (S.Context)
3732252723Sdim               CUDAHostAttr(Attr.getRange(), S.Context,
3733252723Sdim                            Attr.getAttributeSpellingListIndex()));
3734218893Sdim  } else {
3735218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
3736218893Sdim  }
3737218893Sdim}
3738218893Sdim
3739224145Sdimstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3740218893Sdim  if (S.LangOpts.CUDA) {
3741224145Sdim    if (!isa<VarDecl>(D)) {
3742218893Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3743221345Sdim        << Attr.getName() << ExpectedVariable;
3744218893Sdim      return;
3745218893Sdim    }
3746218893Sdim
3747252723Sdim    D->addAttr(::new (S.Context)
3748252723Sdim               CUDASharedAttr(Attr.getRange(), S.Context,
3749252723Sdim                              Attr.getAttributeSpellingListIndex()));
3750218893Sdim  } else {
3751218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
3752218893Sdim  }
3753218893Sdim}
3754218893Sdim
3755224145Sdimstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3756224145Sdim  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
3757193326Sed  if (Fn == 0) {
3758193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3759221345Sdim      << Attr.getName() << ExpectedFunction;
3760193326Sed    return;
3761193326Sed  }
3762198092Srdivacky
3763198893Srdivacky  if (!Fn->isInlineSpecified()) {
3764193326Sed    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3765193326Sed    return;
3766193326Sed  }
3767198092Srdivacky
3768252723Sdim  D->addAttr(::new (S.Context)
3769252723Sdim             GNUInlineAttr(Attr.getRange(), S.Context,
3770252723Sdim                           Attr.getAttributeSpellingListIndex()));
3771193326Sed}
3772193326Sed
3773224145Sdimstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3774224145Sdim  if (hasDeclarator(D)) return;
3775218893Sdim
3776252723Sdim  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
3777224145Sdim  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3778207619Srdivacky  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3779218893Sdim  CallingConv CC;
3780252723Sdim  if (S.CheckCallingConvAttr(Attr, CC, FD))
3781218893Sdim    return;
3782207619Srdivacky
3783224145Sdim  if (!isa<ObjCMethodDecl>(D)) {
3784224145Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3785224145Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
3786218893Sdim    return;
3787218893Sdim  }
3788218893Sdim
3789224145Sdim  switch (Attr.getKind()) {
3790245431Sdim  case AttributeList::AT_FastCall:
3791252723Sdim    D->addAttr(::new (S.Context)
3792252723Sdim               FastCallAttr(Attr.getRange(), S.Context,
3793252723Sdim                            Attr.getAttributeSpellingListIndex()));
3794207619Srdivacky    return;
3795245431Sdim  case AttributeList::AT_StdCall:
3796252723Sdim    D->addAttr(::new (S.Context)
3797252723Sdim               StdCallAttr(Attr.getRange(), S.Context,
3798252723Sdim                           Attr.getAttributeSpellingListIndex()));
3799207619Srdivacky    return;
3800245431Sdim  case AttributeList::AT_ThisCall:
3801252723Sdim    D->addAttr(::new (S.Context)
3802252723Sdim               ThisCallAttr(Attr.getRange(), S.Context,
3803252723Sdim                            Attr.getAttributeSpellingListIndex()));
3804212904Sdim    return;
3805245431Sdim  case AttributeList::AT_CDecl:
3806252723Sdim    D->addAttr(::new (S.Context)
3807252723Sdim               CDeclAttr(Attr.getRange(), S.Context,
3808252723Sdim                         Attr.getAttributeSpellingListIndex()));
3809207619Srdivacky    return;
3810245431Sdim  case AttributeList::AT_Pascal:
3811252723Sdim    D->addAttr(::new (S.Context)
3812252723Sdim               PascalAttr(Attr.getRange(), S.Context,
3813252723Sdim                          Attr.getAttributeSpellingListIndex()));
3814212904Sdim    return;
3815256382Sdim  case AttributeList::AT_MSABI:
3816256382Sdim    D->addAttr(::new (S.Context)
3817256382Sdim               MSABIAttr(Attr.getRange(), S.Context,
3818256382Sdim                         Attr.getAttributeSpellingListIndex()));
3819256382Sdim    return;
3820256382Sdim  case AttributeList::AT_SysVABI:
3821256382Sdim    D->addAttr(::new (S.Context)
3822256382Sdim               SysVABIAttr(Attr.getRange(), S.Context,
3823256382Sdim                           Attr.getAttributeSpellingListIndex()));
3824256382Sdim    return;
3825245431Sdim  case AttributeList::AT_Pcs: {
3826221345Sdim    PcsAttr::PCSType PCS;
3827245431Sdim    switch (CC) {
3828245431Sdim    case CC_AAPCS:
3829221345Sdim      PCS = PcsAttr::AAPCS;
3830245431Sdim      break;
3831245431Sdim    case CC_AAPCS_VFP:
3832221345Sdim      PCS = PcsAttr::AAPCS_VFP;
3833245431Sdim      break;
3834245431Sdim    default:
3835245431Sdim      llvm_unreachable("unexpected calling convention in pcs attribute");
3836221345Sdim    }
3837221345Sdim
3838252723Sdim    D->addAttr(::new (S.Context)
3839252723Sdim               PcsAttr(Attr.getRange(), S.Context, PCS,
3840252723Sdim                       Attr.getAttributeSpellingListIndex()));
3841245431Sdim    return;
3842221345Sdim  }
3843245431Sdim  case AttributeList::AT_PnaclCall:
3844252723Sdim    D->addAttr(::new (S.Context)
3845252723Sdim               PnaclCallAttr(Attr.getRange(), S.Context,
3846252723Sdim                             Attr.getAttributeSpellingListIndex()));
3847245431Sdim    return;
3848252723Sdim  case AttributeList::AT_IntelOclBicc:
3849252723Sdim    D->addAttr(::new (S.Context)
3850252723Sdim               IntelOclBiccAttr(Attr.getRange(), S.Context,
3851252723Sdim                                Attr.getAttributeSpellingListIndex()));
3852252723Sdim    return;
3853245431Sdim
3854207619Srdivacky  default:
3855207619Srdivacky    llvm_unreachable("unexpected attribute kind");
3856207619Srdivacky  }
3857207619Srdivacky}
3858207619Srdivacky
3859224145Sdimstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
3860226890Sdim  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3861218893Sdim}
3862218893Sdim
3863252723Sdimstatic void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){
3864263509Sdim  Expr *E = Attr.getArgAsExpr(0);
3865252723Sdim  llvm::APSInt ArgNum(32);
3866252723Sdim  if (E->isTypeDependent() || E->isValueDependent() ||
3867252723Sdim      !E->isIntegerConstantExpr(ArgNum, S.Context)) {
3868263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3869263509Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
3870263509Sdim      << E->getSourceRange();
3871252723Sdim    return;
3872252723Sdim  }
3873252723Sdim
3874252723Sdim  D->addAttr(::new (S.Context) OpenCLImageAccessAttr(
3875252723Sdim    Attr.getRange(), S.Context, ArgNum.getZExtValue()));
3876252723Sdim}
3877252723Sdim
3878252723Sdimbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
3879252723Sdim                                const FunctionDecl *FD) {
3880218893Sdim  if (attr.isInvalid())
3881218893Sdim    return true;
3882218893Sdim
3883245431Sdim  unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
3884263509Sdim  if (!checkAttributeNumArgs(*this, attr, ReqArgs)) {
3885218893Sdim    attr.setInvalid();
3886218893Sdim    return true;
3887193326Sed  }
3888193326Sed
3889221345Sdim  // TODO: diagnose uses of these conventions on the wrong target. Or, better
3890221345Sdim  // move to TargetAttributesSema one day.
3891218893Sdim  switch (attr.getKind()) {
3892245431Sdim  case AttributeList::AT_CDecl: CC = CC_C; break;
3893245431Sdim  case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
3894245431Sdim  case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
3895245431Sdim  case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
3896245431Sdim  case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
3897256382Sdim  case AttributeList::AT_MSABI:
3898256382Sdim    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
3899256382Sdim                                                             CC_X86_64Win64;
3900256382Sdim    break;
3901256382Sdim  case AttributeList::AT_SysVABI:
3902256382Sdim    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
3903256382Sdim                                                             CC_C;
3904256382Sdim    break;
3905245431Sdim  case AttributeList::AT_Pcs: {
3906263509Sdim    StringRef StrRef;
3907263509Sdim    if (!checkStringLiteralArgumentAttr(attr, 0, StrRef)) {
3908221345Sdim      attr.setInvalid();
3909221345Sdim      return true;
3910221345Sdim    }
3911221345Sdim    if (StrRef == "aapcs") {
3912221345Sdim      CC = CC_AAPCS;
3913221345Sdim      break;
3914221345Sdim    } else if (StrRef == "aapcs-vfp") {
3915221345Sdim      CC = CC_AAPCS_VFP;
3916221345Sdim      break;
3917221345Sdim    }
3918245431Sdim
3919245431Sdim    attr.setInvalid();
3920245431Sdim    Diag(attr.getLoc(), diag::err_invalid_pcs);
3921245431Sdim    return true;
3922221345Sdim  }
3923245431Sdim  case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break;
3924252723Sdim  case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
3925235633Sdim  default: llvm_unreachable("unexpected attribute kind");
3926218893Sdim  }
3927218893Sdim
3928245431Sdim  const TargetInfo &TI = Context.getTargetInfo();
3929245431Sdim  TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
3930245431Sdim  if (A == TargetInfo::CCCR_Warning) {
3931245431Sdim    Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
3932252723Sdim
3933252723Sdim    TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
3934252723Sdim    if (FD)
3935252723Sdim      MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
3936252723Sdim                                    TargetInfo::CCMT_NonMember;
3937252723Sdim    CC = TI.getDefaultCallingConv(MT);
3938245431Sdim  }
3939245431Sdim
3940218893Sdim  return false;
3941218893Sdim}
3942218893Sdim
3943224145Sdimstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3944224145Sdim  if (hasDeclarator(D)) return;
3945218893Sdim
3946218893Sdim  unsigned numParams;
3947224145Sdim  if (S.CheckRegparmAttr(Attr, numParams))
3948193326Sed    return;
3949218893Sdim
3950224145Sdim  if (!isa<ObjCMethodDecl>(D)) {
3951224145Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3952224145Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
3953218893Sdim    return;
3954193326Sed  }
3955193326Sed
3956252723Sdim  D->addAttr(::new (S.Context)
3957252723Sdim             RegparmAttr(Attr.getRange(), S.Context, numParams,
3958252723Sdim                         Attr.getAttributeSpellingListIndex()));
3959218893Sdim}
3960218893Sdim
3961218893Sdim/// Checks a regparm attribute, returning true if it is ill-formed and
3962218893Sdim/// otherwise setting numParams to the appropriate value.
3963224145Sdimbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
3964224145Sdim  if (Attr.isInvalid())
3965218893Sdim    return true;
3966218893Sdim
3967263509Sdim  if (!checkAttributeNumArgs(*this, Attr, 1)) {
3968224145Sdim    Attr.setInvalid();
3969218893Sdim    return true;
3970218893Sdim  }
3971218893Sdim
3972263509Sdim  Expr *NumParamsExpr = Attr.getArgAsExpr(0);
3973193326Sed  llvm::APSInt NumParams(32);
3974208600Srdivacky  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3975218893Sdim      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
3976263509Sdim    Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3977263509Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
3978263509Sdim      << NumParamsExpr->getSourceRange();
3979224145Sdim    Attr.setInvalid();
3980218893Sdim    return true;
3981193326Sed  }
3982193326Sed
3983226890Sdim  if (Context.getTargetInfo().getRegParmMax() == 0) {
3984224145Sdim    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
3985193326Sed      << NumParamsExpr->getSourceRange();
3986224145Sdim    Attr.setInvalid();
3987218893Sdim    return true;
3988193326Sed  }
3989193326Sed
3990218893Sdim  numParams = NumParams.getZExtValue();
3991226890Sdim  if (numParams > Context.getTargetInfo().getRegParmMax()) {
3992224145Sdim    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3993226890Sdim      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
3994224145Sdim    Attr.setInvalid();
3995218893Sdim    return true;
3996193326Sed  }
3997193326Sed
3998218893Sdim  return false;
3999193326Sed}
4000193326Sed
4001224145Sdimstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
4002218893Sdim  if (S.LangOpts.CUDA) {
4003218893Sdim    // check the attribute arguments.
4004218893Sdim    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
4005221345Sdim      // FIXME: 0 is not okay.
4006221345Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
4007218893Sdim      return;
4008218893Sdim    }
4009199990Srdivacky
4010224145Sdim    if (!isFunctionOrMethod(D)) {
4011218893Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4012221345Sdim        << Attr.getName() << ExpectedFunctionOrMethod;
4013218893Sdim      return;
4014218893Sdim    }
4015218893Sdim
4016263509Sdim    Expr *MaxThreadsExpr = Attr.getArgAsExpr(0);
4017218893Sdim    llvm::APSInt MaxThreads(32);
4018218893Sdim    if (MaxThreadsExpr->isTypeDependent() ||
4019218893Sdim        MaxThreadsExpr->isValueDependent() ||
4020218893Sdim        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
4021263509Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4022263509Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
4023263509Sdim        << MaxThreadsExpr->getSourceRange();
4024218893Sdim      return;
4025218893Sdim    }
4026218893Sdim
4027218893Sdim    llvm::APSInt MinBlocks(32);
4028218893Sdim    if (Attr.getNumArgs() > 1) {
4029263509Sdim      Expr *MinBlocksExpr = Attr.getArgAsExpr(1);
4030218893Sdim      if (MinBlocksExpr->isTypeDependent() ||
4031218893Sdim          MinBlocksExpr->isValueDependent() ||
4032218893Sdim          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
4033263509Sdim        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4034263509Sdim          << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
4035263509Sdim          << MinBlocksExpr->getSourceRange();
4036218893Sdim        return;
4037218893Sdim      }
4038218893Sdim    }
4039218893Sdim
4040252723Sdim    D->addAttr(::new (S.Context)
4041252723Sdim               CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
4042252723Sdim                                    MaxThreads.getZExtValue(),
4043252723Sdim                                    MinBlocks.getZExtValue(),
4044252723Sdim                                    Attr.getAttributeSpellingListIndex()));
4045218893Sdim  } else {
4046218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
4047199990Srdivacky  }
4048199990Srdivacky}
4049199990Srdivacky
4050245431Sdimstatic void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
4051245431Sdim                                          const AttributeList &Attr) {
4052263509Sdim  if (!Attr.isArgIdent(0)) {
4053263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4054263509Sdim      << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier;
4055245431Sdim    return;
4056245431Sdim  }
4057263509Sdim
4058263509Sdim  if (!checkAttributeNumArgs(S, Attr, 3))
4059245431Sdim    return;
4060245431Sdim
4061263509Sdim  StringRef AttrName = Attr.getName()->getName();
4062263509Sdim  IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident;
4063245431Sdim
4064245431Sdim  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
4065245431Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
4066245431Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
4067245431Sdim    return;
4068245431Sdim  }
4069245431Sdim
4070245431Sdim  uint64_t ArgumentIdx;
4071245431Sdim  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
4072245431Sdim                                          Attr.getLoc(), 2,
4073263509Sdim                                          Attr.getArgAsExpr(1), ArgumentIdx))
4074245431Sdim    return;
4075245431Sdim
4076245431Sdim  uint64_t TypeTagIdx;
4077245431Sdim  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
4078245431Sdim                                          Attr.getLoc(), 3,
4079263509Sdim                                          Attr.getArgAsExpr(2), TypeTagIdx))
4080245431Sdim    return;
4081245431Sdim
4082245431Sdim  bool IsPointer = (AttrName == "pointer_with_type_tag");
4083245431Sdim  if (IsPointer) {
4084245431Sdim    // Ensure that buffer has a pointer type.
4085245431Sdim    QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
4086245431Sdim    if (!BufferTy->isPointerType()) {
4087245431Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
4088263509Sdim        << Attr.getName();
4089245431Sdim    }
4090245431Sdim  }
4091245431Sdim
4092252723Sdim  D->addAttr(::new (S.Context)
4093252723Sdim             ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
4094252723Sdim                                     ArgumentIdx, TypeTagIdx, IsPointer,
4095252723Sdim                                     Attr.getAttributeSpellingListIndex()));
4096245431Sdim}
4097245431Sdim
4098245431Sdimstatic void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
4099245431Sdim                                         const AttributeList &Attr) {
4100263509Sdim  if (!Attr.isArgIdent(0)) {
4101263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4102263509Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
4103245431Sdim    return;
4104245431Sdim  }
4105263509Sdim
4106263509Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
4107263509Sdim    return;
4108245431Sdim
4109263509Sdim  IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
4110263509Sdim  TypeSourceInfo *MatchingCTypeLoc = 0;
4111263509Sdim  S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc);
4112263509Sdim  assert(MatchingCTypeLoc && "no type source info for attribute argument");
4113245431Sdim
4114252723Sdim  D->addAttr(::new (S.Context)
4115252723Sdim             TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
4116263509Sdim                                    MatchingCTypeLoc,
4117252723Sdim                                    Attr.getLayoutCompatible(),
4118252723Sdim                                    Attr.getMustBeNull(),
4119252723Sdim                                    Attr.getAttributeSpellingListIndex()));
4120245431Sdim}
4121245431Sdim
4122193326Sed//===----------------------------------------------------------------------===//
4123218893Sdim// Checker-specific attribute handlers.
4124199990Srdivacky//===----------------------------------------------------------------------===//
4125199990Srdivacky
4126218893Sdimstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
4127226890Sdim  return type->isDependentType() ||
4128226890Sdim         type->isObjCObjectPointerType() ||
4129226890Sdim         S.Context.isObjCNSObjectType(type);
4130199990Srdivacky}
4131218893Sdimstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
4132226890Sdim  return type->isDependentType() ||
4133226890Sdim         type->isPointerType() ||
4134226890Sdim         isValidSubjectOfNSAttribute(S, type);
4135218893Sdim}
4136199990Srdivacky
4137224145Sdimstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4138224145Sdim  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
4139218893Sdim  if (!param) {
4140224145Sdim    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
4141226890Sdim      << Attr.getRange() << Attr.getName() << ExpectedParameter;
4142199990Srdivacky    return;
4143199990Srdivacky  }
4144199990Srdivacky
4145218893Sdim  bool typeOK, cf;
4146245431Sdim  if (Attr.getKind() == AttributeList::AT_NSConsumed) {
4147218893Sdim    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
4148218893Sdim    cf = false;
4149218893Sdim  } else {
4150218893Sdim    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
4151218893Sdim    cf = true;
4152199990Srdivacky  }
4153199990Srdivacky
4154218893Sdim  if (!typeOK) {
4155224145Sdim    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
4156226890Sdim      << Attr.getRange() << Attr.getName() << cf;
4157199990Srdivacky    return;
4158199990Srdivacky  }
4159199990Srdivacky
4160218893Sdim  if (cf)
4161252723Sdim    param->addAttr(::new (S.Context)
4162252723Sdim                   CFConsumedAttr(Attr.getRange(), S.Context,
4163252723Sdim                                  Attr.getAttributeSpellingListIndex()));
4164218893Sdim  else
4165252723Sdim    param->addAttr(::new (S.Context)
4166252723Sdim                   NSConsumedAttr(Attr.getRange(), S.Context,
4167252723Sdim                                  Attr.getAttributeSpellingListIndex()));
4168199990Srdivacky}
4169199990Srdivacky
4170224145Sdimstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D,
4171224145Sdim                                     const AttributeList &Attr) {
4172224145Sdim  if (!isa<ObjCMethodDecl>(D)) {
4173224145Sdim    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
4174226890Sdim      << Attr.getRange() << Attr.getName() << ExpectedMethod;
4175199990Srdivacky    return;
4176199990Srdivacky  }
4177199990Srdivacky
4178252723Sdim  D->addAttr(::new (S.Context)
4179252723Sdim             NSConsumesSelfAttr(Attr.getRange(), S.Context,
4180252723Sdim                                Attr.getAttributeSpellingListIndex()));
4181199990Srdivacky}
4182199990Srdivacky
4183224145Sdimstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
4184224145Sdim                                        const AttributeList &Attr) {
4185193326Sed
4186218893Sdim  QualType returnType;
4187198092Srdivacky
4188224145Sdim  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
4189218893Sdim    returnType = MD->getResultType();
4190245431Sdim  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
4191245431Sdim           (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
4192245431Sdim    return; // ignore: was handled as a type attribute
4193224145Sdim  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
4194224145Sdim    returnType = PD->getType();
4195224145Sdim  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4196218893Sdim    returnType = FD->getResultType();
4197193326Sed  else {
4198224145Sdim    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
4199226890Sdim        << Attr.getRange() << Attr.getName()
4200221345Sdim        << ExpectedFunctionOrMethod;
4201193326Sed    return;
4202193326Sed  }
4203198092Srdivacky
4204218893Sdim  bool typeOK;
4205218893Sdim  bool cf;
4206224145Sdim  switch (Attr.getKind()) {
4207235633Sdim  default: llvm_unreachable("invalid ownership attribute");
4208245431Sdim  case AttributeList::AT_NSReturnsAutoreleased:
4209245431Sdim  case AttributeList::AT_NSReturnsRetained:
4210245431Sdim  case AttributeList::AT_NSReturnsNotRetained:
4211218893Sdim    typeOK = isValidSubjectOfNSAttribute(S, returnType);
4212218893Sdim    cf = false;
4213218893Sdim    break;
4214218893Sdim
4215245431Sdim  case AttributeList::AT_CFReturnsRetained:
4216245431Sdim  case AttributeList::AT_CFReturnsNotRetained:
4217218893Sdim    typeOK = isValidSubjectOfCFAttribute(S, returnType);
4218218893Sdim    cf = true;
4219218893Sdim    break;
4220218893Sdim  }
4221218893Sdim
4222218893Sdim  if (!typeOK) {
4223224145Sdim    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4224226890Sdim      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
4225198092Srdivacky    return;
4226193326Sed  }
4227198092Srdivacky
4228224145Sdim  switch (Attr.getKind()) {
4229193326Sed    default:
4230226890Sdim      llvm_unreachable("invalid ownership attribute");
4231245431Sdim    case AttributeList::AT_NSReturnsAutoreleased:
4232252723Sdim      D->addAttr(::new (S.Context)
4233252723Sdim                 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
4234252723Sdim                                           Attr.getAttributeSpellingListIndex()));
4235218893Sdim      return;
4236245431Sdim    case AttributeList::AT_CFReturnsNotRetained:
4237252723Sdim      D->addAttr(::new (S.Context)
4238252723Sdim                 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4239252723Sdim                                          Attr.getAttributeSpellingListIndex()));
4240204643Srdivacky      return;
4241245431Sdim    case AttributeList::AT_NSReturnsNotRetained:
4242252723Sdim      D->addAttr(::new (S.Context)
4243252723Sdim                 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4244252723Sdim                                          Attr.getAttributeSpellingListIndex()));
4245204643Srdivacky      return;
4246245431Sdim    case AttributeList::AT_CFReturnsRetained:
4247252723Sdim      D->addAttr(::new (S.Context)
4248252723Sdim                 CFReturnsRetainedAttr(Attr.getRange(), S.Context,
4249252723Sdim                                       Attr.getAttributeSpellingListIndex()));
4250193326Sed      return;
4251245431Sdim    case AttributeList::AT_NSReturnsRetained:
4252252723Sdim      D->addAttr(::new (S.Context)
4253252723Sdim                 NSReturnsRetainedAttr(Attr.getRange(), S.Context,
4254252723Sdim                                       Attr.getAttributeSpellingListIndex()));
4255193326Sed      return;
4256193326Sed  };
4257193326Sed}
4258193326Sed
4259226890Sdimstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
4260226890Sdim                                              const AttributeList &attr) {
4261263509Sdim  const int EP_ObjCMethod = 1;
4262263509Sdim  const int EP_ObjCProperty = 2;
4263263509Sdim
4264226890Sdim  SourceLocation loc = attr.getLoc();
4265263509Sdim  QualType resultType;
4266263509Sdim
4267226890Sdim  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4268226890Sdim
4269245431Sdim  if (!method) {
4270263509Sdim    ObjCPropertyDecl *property = dyn_cast<ObjCPropertyDecl>(D);
4271263509Sdim    if (!property) {
4272263509Sdim      S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4273263509Sdim        << SourceRange(loc, loc) << attr.getName() << ExpectedMethodOrProperty;
4274263509Sdim      return;
4275263509Sdim    }
4276263509Sdim    resultType = property->getType();
4277226890Sdim  }
4278263509Sdim  else
4279263509Sdim    // Check that the method returns a normal pointer.
4280263509Sdim    resultType = method->getResultType();
4281226890Sdim
4282226890Sdim  if (!resultType->isReferenceType() &&
4283226890Sdim      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
4284263509Sdim    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4285226890Sdim      << SourceRange(loc)
4286263509Sdim    << attr.getName() << (method ? EP_ObjCMethod : EP_ObjCProperty)
4287263509Sdim    << /*non-retainable pointer*/ 2;
4288226890Sdim
4289226890Sdim    // Drop the attribute.
4290226890Sdim    return;
4291226890Sdim  }
4292226890Sdim
4293263509Sdim  D->addAttr(::new (S.Context)
4294252723Sdim                  ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
4295252723Sdim                                              attr.getAttributeSpellingListIndex()));
4296226890Sdim}
4297226890Sdim
4298245431Sdimstatic void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
4299245431Sdim                                        const AttributeList &attr) {
4300245431Sdim  SourceLocation loc = attr.getLoc();
4301245431Sdim  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4302245431Sdim
4303245431Sdim  if (!method) {
4304245431Sdim   S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4305245431Sdim   << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
4306245431Sdim    return;
4307245431Sdim  }
4308245431Sdim  DeclContext *DC = method->getDeclContext();
4309245431Sdim  if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
4310245431Sdim    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4311245431Sdim    << attr.getName() << 0;
4312245431Sdim    S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
4313245431Sdim    return;
4314245431Sdim  }
4315245431Sdim  if (method->getMethodFamily() == OMF_dealloc) {
4316245431Sdim    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4317245431Sdim    << attr.getName() << 1;
4318245431Sdim    return;
4319245431Sdim  }
4320245431Sdim
4321252723Sdim  method->addAttr(::new (S.Context)
4322252723Sdim                  ObjCRequiresSuperAttr(attr.getRange(), S.Context,
4323252723Sdim                                        attr.getAttributeSpellingListIndex()));
4324245431Sdim}
4325245431Sdim
4326226890Sdim/// Handle cf_audited_transfer and cf_unknown_transfer.
4327226890Sdimstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
4328226890Sdim  if (!isa<FunctionDecl>(D)) {
4329226890Sdim    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4330235633Sdim      << A.getRange() << A.getName() << ExpectedFunction;
4331226890Sdim    return;
4332226890Sdim  }
4333226890Sdim
4334245431Sdim  bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
4335226890Sdim
4336226890Sdim  // Check whether there's a conflicting attribute already present.
4337226890Sdim  Attr *Existing;
4338226890Sdim  if (IsAudited) {
4339226890Sdim    Existing = D->getAttr<CFUnknownTransferAttr>();
4340226890Sdim  } else {
4341226890Sdim    Existing = D->getAttr<CFAuditedTransferAttr>();
4342226890Sdim  }
4343226890Sdim  if (Existing) {
4344226890Sdim    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
4345226890Sdim      << A.getName()
4346226890Sdim      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
4347226890Sdim      << A.getRange() << Existing->getRange();
4348226890Sdim    return;
4349226890Sdim  }
4350226890Sdim
4351226890Sdim  // All clear;  add the attribute.
4352226890Sdim  if (IsAudited) {
4353252723Sdim    D->addAttr(::new (S.Context)
4354252723Sdim               CFAuditedTransferAttr(A.getRange(), S.Context,
4355252723Sdim                                     A.getAttributeSpellingListIndex()));
4356226890Sdim  } else {
4357252723Sdim    D->addAttr(::new (S.Context)
4358252723Sdim               CFUnknownTransferAttr(A.getRange(), S.Context,
4359252723Sdim                                     A.getAttributeSpellingListIndex()));
4360226890Sdim  }
4361226890Sdim}
4362226890Sdim
4363226890Sdimstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
4364226890Sdim                                const AttributeList &Attr) {
4365226890Sdim  RecordDecl *RD = dyn_cast<RecordDecl>(D);
4366226890Sdim  if (!RD || RD->isUnion()) {
4367226890Sdim    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4368235633Sdim      << Attr.getRange() << Attr.getName() << ExpectedStruct;
4369226890Sdim  }
4370226890Sdim
4371263509Sdim  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
4372226890Sdim
4373226890Sdim  // In Objective-C, verify that the type names an Objective-C type.
4374226890Sdim  // We don't want to check this outside of ObjC because people sometimes
4375226890Sdim  // do crazy C declarations of Objective-C types.
4376263509Sdim  if (Parm && S.getLangOpts().ObjC1) {
4377226890Sdim    // Check for an existing type with this name.
4378263509Sdim    LookupResult R(S, DeclarationName(Parm->Ident), Parm->Loc,
4379226890Sdim                   Sema::LookupOrdinaryName);
4380226890Sdim    if (S.LookupName(R, Sc)) {
4381226890Sdim      NamedDecl *Target = R.getFoundDecl();
4382226890Sdim      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
4383226890Sdim        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
4384226890Sdim        S.Diag(Target->getLocStart(), diag::note_declared_at);
4385226890Sdim      }
4386226890Sdim    }
4387226890Sdim  }
4388226890Sdim
4389252723Sdim  D->addAttr(::new (S.Context)
4390263509Sdim             NSBridgedAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
4391252723Sdim                           Attr.getAttributeSpellingListIndex()));
4392226890Sdim}
4393226890Sdim
4394263509Sdimstatic void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
4395263509Sdim                                const AttributeList &Attr) {
4396263509Sdim  if (!isa<RecordDecl>(D)) {
4397263509Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
4398263509Sdim    << Attr.getName()
4399263509Sdim    << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass
4400263509Sdim                                  : ExpectedStructOrUnion);
4401263509Sdim    return;
4402263509Sdim  }
4403263509Sdim
4404263509Sdim  if (Attr.getNumArgs() != 1) {
4405263509Sdim    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
4406263509Sdim    return;
4407263509Sdim  }
4408263509Sdim  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
4409263509Sdim  if (!Parm) {
4410263509Sdim    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
4411263509Sdim    return;
4412263509Sdim  }
4413263509Sdim
4414263509Sdim  D->addAttr(::new (S.Context)
4415263509Sdim             ObjCBridgeAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
4416263509Sdim                           Attr.getAttributeSpellingListIndex()));
4417263509Sdim}
4418263509Sdim
4419224145Sdimstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
4420224145Sdim                                    const AttributeList &Attr) {
4421224145Sdim  if (hasDeclarator(D)) return;
4422224145Sdim
4423224145Sdim  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4424235633Sdim    << Attr.getRange() << Attr.getName() << ExpectedVariable;
4425224145Sdim}
4426224145Sdim
4427224145Sdimstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
4428224145Sdim                                          const AttributeList &Attr) {
4429224145Sdim  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
4430224145Sdim    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4431235633Sdim      << Attr.getRange() << Attr.getName() << ExpectedVariable;
4432224145Sdim    return;
4433224145Sdim  }
4434224145Sdim
4435224145Sdim  ValueDecl *vd = cast<ValueDecl>(D);
4436224145Sdim  QualType type = vd->getType();
4437224145Sdim
4438224145Sdim  if (!type->isDependentType() &&
4439224145Sdim      !type->isObjCLifetimeType()) {
4440224145Sdim    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
4441224145Sdim      << type;
4442224145Sdim    return;
4443224145Sdim  }
4444224145Sdim
4445224145Sdim  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
4446224145Sdim
4447224145Sdim  // If we have no lifetime yet, check the lifetime we're presumably
4448224145Sdim  // going to infer.
4449224145Sdim  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
4450224145Sdim    lifetime = type->getObjCARCImplicitLifetime();
4451224145Sdim
4452224145Sdim  switch (lifetime) {
4453224145Sdim  case Qualifiers::OCL_None:
4454224145Sdim    assert(type->isDependentType() &&
4455224145Sdim           "didn't infer lifetime for non-dependent type?");
4456224145Sdim    break;
4457224145Sdim
4458224145Sdim  case Qualifiers::OCL_Weak:   // meaningful
4459224145Sdim  case Qualifiers::OCL_Strong: // meaningful
4460224145Sdim    break;
4461224145Sdim
4462224145Sdim  case Qualifiers::OCL_ExplicitNone:
4463224145Sdim  case Qualifiers::OCL_Autoreleasing:
4464224145Sdim    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
4465224145Sdim      << (lifetime == Qualifiers::OCL_Autoreleasing);
4466224145Sdim    break;
4467224145Sdim  }
4468224145Sdim
4469224145Sdim  D->addAttr(::new (S.Context)
4470252723Sdim             ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
4471252723Sdim                                     Attr.getAttributeSpellingListIndex()));
4472224145Sdim}
4473224145Sdim
4474193326Sed//===----------------------------------------------------------------------===//
4475218893Sdim// Microsoft specific attribute handlers.
4476218893Sdim//===----------------------------------------------------------------------===//
4477218893Sdim
4478263509Sdim// Check if MS extensions or some other language extensions are enabled.  If
4479263509Sdim// not, issue a diagnostic that the given attribute is unused.
4480263509Sdimstatic bool checkMicrosoftExt(Sema &S, const AttributeList &Attr,
4481263509Sdim                              bool OtherExtension = false) {
4482263509Sdim  if (S.LangOpts.MicrosoftExt || OtherExtension)
4483263509Sdim    return true;
4484263509Sdim  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4485263509Sdim  return false;
4486263509Sdim}
4487263509Sdim
4488224145Sdimstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4489263509Sdim  if (!checkMicrosoftExt(S, Attr, S.LangOpts.Borland))
4490263509Sdim    return;
4491224145Sdim
4492263509Sdim  StringRef StrRef;
4493263509Sdim  SourceLocation LiteralLoc;
4494263509Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc))
4495263509Sdim    return;
4496218893Sdim
4497263509Sdim  // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
4498263509Sdim  // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
4499263509Sdim  if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
4500263509Sdim    StrRef = StrRef.drop_front().drop_back();
4501218893Sdim
4502263509Sdim  // Validate GUID length.
4503263509Sdim  if (StrRef.size() != 36) {
4504263509Sdim    S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4505263509Sdim    return;
4506263509Sdim  }
4507235633Sdim
4508263509Sdim  for (unsigned i = 0; i < 36; ++i) {
4509263509Sdim    if (i == 8 || i == 13 || i == 18 || i == 23) {
4510263509Sdim      if (StrRef[i] != '-') {
4511263509Sdim        S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4512218893Sdim        return;
4513218893Sdim      }
4514263509Sdim    } else if (!isHexDigit(StrRef[i])) {
4515263509Sdim      S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4516263509Sdim      return;
4517218893Sdim    }
4518263509Sdim  }
4519218893Sdim
4520263509Sdim  D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef,
4521263509Sdim                                        Attr.getAttributeSpellingListIndex()));
4522218893Sdim}
4523218893Sdim
4524245431Sdimstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4525263509Sdim  if (!checkMicrosoftExt(S, Attr))
4526245431Sdim    return;
4527245431Sdim
4528245431Sdim  AttributeList::Kind Kind = Attr.getKind();
4529245431Sdim  if (Kind == AttributeList::AT_SingleInheritance)
4530245431Sdim    D->addAttr(
4531252723Sdim        ::new (S.Context)
4532252723Sdim               SingleInheritanceAttr(Attr.getRange(), S.Context,
4533252723Sdim                                     Attr.getAttributeSpellingListIndex()));
4534245431Sdim  else if (Kind == AttributeList::AT_MultipleInheritance)
4535245431Sdim    D->addAttr(
4536252723Sdim        ::new (S.Context)
4537252723Sdim               MultipleInheritanceAttr(Attr.getRange(), S.Context,
4538252723Sdim                                       Attr.getAttributeSpellingListIndex()));
4539245431Sdim  else if (Kind == AttributeList::AT_VirtualInheritance)
4540245431Sdim    D->addAttr(
4541252723Sdim        ::new (S.Context)
4542252723Sdim               VirtualInheritanceAttr(Attr.getRange(), S.Context,
4543252723Sdim                                      Attr.getAttributeSpellingListIndex()));
4544245431Sdim}
4545245431Sdim
4546245431Sdimstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4547263509Sdim  if (!checkMicrosoftExt(S, Attr))
4548263509Sdim    return;
4549263509Sdim
4550263509Sdim  AttributeList::Kind Kind = Attr.getKind();
4551263509Sdim    if (Kind == AttributeList::AT_Win64)
4552263509Sdim    D->addAttr(
4553263509Sdim        ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
4554263509Sdim                                    Attr.getAttributeSpellingListIndex()));
4555245431Sdim}
4556245431Sdim
4557245431Sdimstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4558263509Sdim  if (!checkMicrosoftExt(S, Attr))
4559263509Sdim    return;
4560263509Sdim  D->addAttr(::new (S.Context)
4561263509Sdim             ForceInlineAttr(Attr.getRange(), S.Context,
4562263509Sdim                             Attr.getAttributeSpellingListIndex()));
4563245431Sdim}
4564245431Sdim
4565263509Sdimstatic void handleSelectAnyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4566263509Sdim  if (!checkMicrosoftExt(S, Attr))
4567263509Sdim    return;
4568263509Sdim  // Check linkage after possibly merging declaratinos.  See
4569263509Sdim  // checkAttributesAfterMerging().
4570263509Sdim  D->addAttr(::new (S.Context)
4571263509Sdim             SelectAnyAttr(Attr.getRange(), S.Context,
4572263509Sdim                           Attr.getAttributeSpellingListIndex()));
4573263509Sdim}
4574263509Sdim
4575263509Sdim/// Handles semantic checking for features that are common to all attributes,
4576263509Sdim/// such as checking whether a parameter was properly specified, or the correct
4577263509Sdim/// number of arguments were passed, etc.
4578263509Sdimstatic bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
4579263509Sdim                                          const AttributeList &Attr) {
4580263509Sdim  // Several attributes carry different semantics than the parsing requires, so
4581263509Sdim  // those are opted out of the common handling.
4582263509Sdim  //
4583263509Sdim  // We also bail on unknown and ignored attributes because those are handled
4584263509Sdim  // as part of the target-specific handling logic.
4585263509Sdim  if (Attr.hasCustomParsing() ||
4586263509Sdim      Attr.getKind() == AttributeList::UnknownAttribute ||
4587263509Sdim      Attr.getKind() == AttributeList::IgnoredAttribute)
4588263509Sdim    return false;
4589263509Sdim
4590263509Sdim  // If there are no optional arguments, then checking for the argument count
4591263509Sdim  // is trivial.
4592263509Sdim  if (Attr.getMinArgs() == Attr.getMaxArgs() &&
4593263509Sdim      !checkAttributeNumArgs(S, Attr, Attr.getMinArgs()))
4594263509Sdim    return true;
4595263509Sdim  return false;
4596263509Sdim}
4597263509Sdim
4598218893Sdim//===----------------------------------------------------------------------===//
4599193326Sed// Top Level Sema Entry Points
4600193326Sed//===----------------------------------------------------------------------===//
4601193326Sed
4602263509Sdim/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
4603263509Sdim/// the attribute applies to decls.  If the attribute is a type attribute, just
4604263509Sdim/// silently ignore it if a GNU attribute.
4605263509Sdimstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
4606263509Sdim                                 const AttributeList &Attr,
4607263509Sdim                                 bool IncludeCXX11Attributes) {
4608263509Sdim  if (Attr.isInvalid())
4609263509Sdim    return;
4610207619Srdivacky
4611263509Sdim  // Ignore C++11 attributes on declarator chunks: they appertain to the type
4612263509Sdim  // instead.
4613263509Sdim  if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
4614263509Sdim    return;
4615263509Sdim
4616263509Sdim  if (handleCommonAttributeFeatures(S, scope, D, Attr))
4617263509Sdim    return;
4618263509Sdim
4619193326Sed  switch (Attr.getKind()) {
4620252723Sdim  case AttributeList::AT_IBAction:    handleIBAction(S, D, Attr); break;
4621252723Sdim  case AttributeList::AT_IBOutlet:    handleIBOutlet(S, D, Attr); break;
4622252723Sdim  case AttributeList::AT_IBOutletCollection:
4623252723Sdim    handleIBOutletCollection(S, D, Attr); break;
4624245431Sdim  case AttributeList::AT_AddressSpace:
4625245431Sdim  case AttributeList::AT_ObjCGC:
4626245431Sdim  case AttributeList::AT_VectorSize:
4627245431Sdim  case AttributeList::AT_NeonVectorType:
4628245431Sdim  case AttributeList::AT_NeonPolyVectorType:
4629263509Sdim  case AttributeList::AT_Ptr32:
4630263509Sdim  case AttributeList::AT_Ptr64:
4631263509Sdim  case AttributeList::AT_SPtr:
4632263509Sdim  case AttributeList::AT_UPtr:
4633198092Srdivacky    // Ignore these, these are type attributes, handled by
4634198092Srdivacky    // ProcessTypeAttributes.
4635193326Sed    break;
4636245431Sdim  case AttributeList::AT_Alias:       handleAliasAttr       (S, D, Attr); break;
4637245431Sdim  case AttributeList::AT_Aligned:     handleAlignedAttr     (S, D, Attr); break;
4638245431Sdim  case AttributeList::AT_AllocSize:   handleAllocSizeAttr   (S, D, Attr); break;
4639245431Sdim  case AttributeList::AT_AlwaysInline:
4640224145Sdim    handleAlwaysInlineAttr  (S, D, Attr); break;
4641245431Sdim  case AttributeList::AT_AnalyzerNoReturn:
4642224145Sdim    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
4643245431Sdim  case AttributeList::AT_TLSModel:    handleTLSModelAttr    (S, D, Attr); break;
4644245431Sdim  case AttributeList::AT_Annotate:    handleAnnotateAttr    (S, D, Attr); break;
4645245431Sdim  case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
4646245431Sdim  case AttributeList::AT_CarriesDependency:
4647252723Sdim    handleDependencyAttr(S, scope, D, Attr);
4648252723Sdim    break;
4649245431Sdim  case AttributeList::AT_Common:      handleCommonAttr      (S, D, Attr); break;
4650245431Sdim  case AttributeList::AT_CUDAConstant:handleConstantAttr    (S, D, Attr); break;
4651245431Sdim  case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
4652252723Sdim  case AttributeList::AT_CXX11NoReturn:
4653252723Sdim    handleCXX11NoReturnAttr(S, D, Attr);
4654252723Sdim    break;
4655245431Sdim  case AttributeList::AT_Deprecated:
4656263509Sdim    handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
4657245431Sdim    break;
4658245431Sdim  case AttributeList::AT_Destructor:  handleDestructorAttr  (S, D, Attr); break;
4659245431Sdim  case AttributeList::AT_ExtVectorType:
4660224145Sdim    handleExtVectorTypeAttr(S, scope, D, Attr);
4661193326Sed    break;
4662245431Sdim  case AttributeList::AT_MinSize:
4663245431Sdim    handleMinSizeAttr(S, D, Attr);
4664245431Sdim    break;
4665245431Sdim  case AttributeList::AT_Format:      handleFormatAttr      (S, D, Attr); break;
4666245431Sdim  case AttributeList::AT_FormatArg:   handleFormatArgAttr   (S, D, Attr); break;
4667245431Sdim  case AttributeList::AT_CUDAGlobal:  handleGlobalAttr      (S, D, Attr); break;
4668263509Sdim  case AttributeList::AT_CUDADevice:  handleDeviceAttr      (S, D, Attr); break;
4669263509Sdim  case AttributeList::AT_CUDAHost:    handleHostAttr        (S, D, Attr); break;
4670245431Sdim  case AttributeList::AT_GNUInline:   handleGNUInlineAttr   (S, D, Attr); break;
4671245431Sdim  case AttributeList::AT_CUDALaunchBounds:
4672224145Sdim    handleLaunchBoundsAttr(S, D, Attr);
4673218893Sdim    break;
4674245431Sdim  case AttributeList::AT_Malloc:      handleMallocAttr      (S, D, Attr); break;
4675245431Sdim  case AttributeList::AT_MayAlias:    handleMayAliasAttr    (S, D, Attr); break;
4676263509Sdim  case AttributeList::AT_Mode:        handleModeAttr        (S, D, Attr); break;
4677245431Sdim  case AttributeList::AT_NoCommon:    handleNoCommonAttr    (S, D, Attr); break;
4678245431Sdim  case AttributeList::AT_NonNull:     handleNonNullAttr     (S, D, Attr); break;
4679263509Sdim  case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break;
4680212904Sdim  case AttributeList::AT_ownership_returns:
4681212904Sdim  case AttributeList::AT_ownership_takes:
4682212904Sdim  case AttributeList::AT_ownership_holds:
4683224145Sdim      handleOwnershipAttr     (S, D, Attr); break;
4684245431Sdim  case AttributeList::AT_Cold:        handleColdAttr        (S, D, Attr); break;
4685245431Sdim  case AttributeList::AT_Hot:         handleHotAttr         (S, D, Attr); break;
4686245431Sdim  case AttributeList::AT_Naked:       handleNakedAttr       (S, D, Attr); break;
4687245431Sdim  case AttributeList::AT_NoReturn:    handleNoReturnAttr    (S, D, Attr); break;
4688245431Sdim  case AttributeList::AT_NoThrow:     handleNothrowAttr     (S, D, Attr); break;
4689245431Sdim  case AttributeList::AT_CUDAShared:  handleSharedAttr      (S, D, Attr); break;
4690245431Sdim  case AttributeList::AT_VecReturn:   handleVecReturnAttr   (S, D, Attr); break;
4691193326Sed
4692245431Sdim  case AttributeList::AT_ObjCOwnership:
4693224145Sdim    handleObjCOwnershipAttr(S, D, Attr); break;
4694245431Sdim  case AttributeList::AT_ObjCPreciseLifetime:
4695224145Sdim    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
4696224145Sdim
4697245431Sdim  case AttributeList::AT_ObjCReturnsInnerPointer:
4698226890Sdim    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
4699226890Sdim
4700245431Sdim  case AttributeList::AT_ObjCRequiresSuper:
4701245431Sdim      handleObjCRequiresSuperAttr(S, D, Attr); break;
4702245431Sdim
4703245431Sdim  case AttributeList::AT_NSBridged:
4704226890Sdim    handleNSBridgedAttr(S, scope, D, Attr); break;
4705263509Sdim
4706263509Sdim  case AttributeList::AT_ObjCBridge:
4707263509Sdim    handleObjCBridgeAttr(S, scope, D, Attr); break;
4708226890Sdim
4709245431Sdim  case AttributeList::AT_CFAuditedTransfer:
4710245431Sdim  case AttributeList::AT_CFUnknownTransfer:
4711226890Sdim    handleCFTransferAttr(S, D, Attr); break;
4712226890Sdim
4713193326Sed  // Checker-specific.
4714245431Sdim  case AttributeList::AT_CFConsumed:
4715245431Sdim  case AttributeList::AT_NSConsumed:  handleNSConsumedAttr  (S, D, Attr); break;
4716245431Sdim  case AttributeList::AT_NSConsumesSelf:
4717224145Sdim    handleNSConsumesSelfAttr(S, D, Attr); break;
4718218893Sdim
4719245431Sdim  case AttributeList::AT_NSReturnsAutoreleased:
4720245431Sdim  case AttributeList::AT_NSReturnsNotRetained:
4721245431Sdim  case AttributeList::AT_CFReturnsNotRetained:
4722245431Sdim  case AttributeList::AT_NSReturnsRetained:
4723245431Sdim  case AttributeList::AT_CFReturnsRetained:
4724224145Sdim    handleNSReturnsRetainedAttr(S, D, Attr); break;
4725193326Sed
4726245431Sdim  case AttributeList::AT_WorkGroupSizeHint:
4727245431Sdim  case AttributeList::AT_ReqdWorkGroupSize:
4728245431Sdim    handleWorkGroupSize(S, D, Attr); break;
4729195099Sed
4730252723Sdim  case AttributeList::AT_VecTypeHint:
4731252723Sdim    handleVecTypeHint(S, D, Attr); break;
4732252723Sdim
4733245431Sdim  case AttributeList::AT_InitPriority:
4734224145Sdim      handleInitPriorityAttr(S, D, Attr); break;
4735210299Sed
4736245431Sdim  case AttributeList::AT_Packed:      handlePackedAttr      (S, D, Attr); break;
4737245431Sdim  case AttributeList::AT_Section:     handleSectionAttr     (S, D, Attr); break;
4738245431Sdim  case AttributeList::AT_Unavailable:
4739263509Sdim    handleAttrWithMessage<UnavailableAttr>(S, D, Attr);
4740245431Sdim    break;
4741245431Sdim  case AttributeList::AT_ArcWeakrefUnavailable:
4742224145Sdim    handleArcWeakrefUnavailableAttr (S, D, Attr);
4743193326Sed    break;
4744245431Sdim  case AttributeList::AT_ObjCRootClass:
4745235633Sdim    handleObjCRootClassAttr(S, D, Attr);
4746235633Sdim    break;
4747245431Sdim  case AttributeList::AT_ObjCRequiresPropertyDefs:
4748235633Sdim    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
4749235633Sdim    break;
4750245431Sdim  case AttributeList::AT_Unused:      handleUnusedAttr      (S, D, Attr); break;
4751245431Sdim  case AttributeList::AT_ReturnsTwice:
4752226890Sdim    handleReturnsTwiceAttr(S, D, Attr);
4753226890Sdim    break;
4754245431Sdim  case AttributeList::AT_Used:        handleUsedAttr        (S, D, Attr); break;
4755252723Sdim  case AttributeList::AT_Visibility:
4756252723Sdim    handleVisibilityAttr(S, D, Attr, false);
4757252723Sdim    break;
4758252723Sdim  case AttributeList::AT_TypeVisibility:
4759252723Sdim    handleVisibilityAttr(S, D, Attr, true);
4760252723Sdim    break;
4761263509Sdim  case AttributeList::AT_WarnUnused:
4762263509Sdim    handleWarnUnusedAttr(S, D, Attr);
4763263509Sdim    break;
4764245431Sdim  case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
4765224145Sdim    break;
4766245431Sdim  case AttributeList::AT_Weak:        handleWeakAttr        (S, D, Attr); break;
4767245431Sdim  case AttributeList::AT_WeakRef:     handleWeakRefAttr     (S, D, Attr); break;
4768245431Sdim  case AttributeList::AT_WeakImport:  handleWeakImportAttr  (S, D, Attr); break;
4769245431Sdim  case AttributeList::AT_TransparentUnion:
4770224145Sdim    handleTransparentUnionAttr(S, D, Attr);
4771193326Sed    break;
4772245431Sdim  case AttributeList::AT_ObjCException:
4773224145Sdim    handleObjCExceptionAttr(S, D, Attr);
4774193326Sed    break;
4775245431Sdim  case AttributeList::AT_ObjCMethodFamily:
4776224145Sdim    handleObjCMethodFamilyAttr(S, D, Attr);
4777221345Sdim    break;
4778245431Sdim  case AttributeList::AT_ObjCNSObject:handleObjCNSObject    (S, D, Attr); break;
4779245431Sdim  case AttributeList::AT_Blocks:      handleBlocksAttr      (S, D, Attr); break;
4780245431Sdim  case AttributeList::AT_Sentinel:    handleSentinelAttr    (S, D, Attr); break;
4781245431Sdim  case AttributeList::AT_Const:       handleConstAttr       (S, D, Attr); break;
4782245431Sdim  case AttributeList::AT_Pure:        handlePureAttr        (S, D, Attr); break;
4783245431Sdim  case AttributeList::AT_Cleanup:     handleCleanupAttr     (S, D, Attr); break;
4784245431Sdim  case AttributeList::AT_NoDebug:     handleNoDebugAttr     (S, D, Attr); break;
4785245431Sdim  case AttributeList::AT_NoInline:    handleNoInlineAttr    (S, D, Attr); break;
4786245431Sdim  case AttributeList::AT_Regparm:     handleRegparmAttr     (S, D, Attr); break;
4787198092Srdivacky  case AttributeList::IgnoredAttribute:
4788193326Sed    // Just ignore
4789193326Sed    break;
4790245431Sdim  case AttributeList::AT_NoInstrumentFunction:  // Interacts with -pg.
4791224145Sdim    handleNoInstrumentFunctionAttr(S, D, Attr);
4792210299Sed    break;
4793245431Sdim  case AttributeList::AT_StdCall:
4794245431Sdim  case AttributeList::AT_CDecl:
4795245431Sdim  case AttributeList::AT_FastCall:
4796245431Sdim  case AttributeList::AT_ThisCall:
4797245431Sdim  case AttributeList::AT_Pascal:
4798256382Sdim  case AttributeList::AT_MSABI:
4799256382Sdim  case AttributeList::AT_SysVABI:
4800245431Sdim  case AttributeList::AT_Pcs:
4801245431Sdim  case AttributeList::AT_PnaclCall:
4802252723Sdim  case AttributeList::AT_IntelOclBicc:
4803224145Sdim    handleCallConvAttr(S, D, Attr);
4804203955Srdivacky    break;
4805245431Sdim  case AttributeList::AT_OpenCLKernel:
4806224145Sdim    handleOpenCLKernelAttr(S, D, Attr);
4807218893Sdim    break;
4808252723Sdim  case AttributeList::AT_OpenCLImageAccess:
4809252723Sdim    handleOpenCLImageAccessAttr(S, D, Attr);
4810252723Sdim    break;
4811245431Sdim
4812245431Sdim  // Microsoft attributes:
4813245431Sdim  case AttributeList::AT_MsStruct:
4814245431Sdim    handleMsStructAttr(S, D, Attr);
4815245431Sdim    break;
4816245431Sdim  case AttributeList::AT_Uuid:
4817224145Sdim    handleUuidAttr(S, D, Attr);
4818218893Sdim    break;
4819245431Sdim  case AttributeList::AT_SingleInheritance:
4820245431Sdim  case AttributeList::AT_MultipleInheritance:
4821245431Sdim  case AttributeList::AT_VirtualInheritance:
4822245431Sdim    handleInheritanceAttr(S, D, Attr);
4823245431Sdim    break;
4824245431Sdim  case AttributeList::AT_Win64:
4825245431Sdim    handlePortabilityAttr(S, D, Attr);
4826245431Sdim    break;
4827245431Sdim  case AttributeList::AT_ForceInline:
4828245431Sdim    handleForceInlineAttr(S, D, Attr);
4829245431Sdim    break;
4830263509Sdim  case AttributeList::AT_SelectAny:
4831263509Sdim    handleSelectAnyAttr(S, D, Attr);
4832263509Sdim    break;
4833226890Sdim
4834226890Sdim  // Thread safety attributes:
4835263509Sdim  case AttributeList::AT_AssertExclusiveLock:
4836263509Sdim    handleAssertExclusiveLockAttr(S, D, Attr);
4837263509Sdim    break;
4838263509Sdim  case AttributeList::AT_AssertSharedLock:
4839263509Sdim    handleAssertSharedLockAttr(S, D, Attr);
4840263509Sdim    break;
4841245431Sdim  case AttributeList::AT_GuardedVar:
4842226890Sdim    handleGuardedVarAttr(S, D, Attr);
4843226890Sdim    break;
4844245431Sdim  case AttributeList::AT_PtGuardedVar:
4845245431Sdim    handlePtGuardedVarAttr(S, D, Attr);
4846226890Sdim    break;
4847245431Sdim  case AttributeList::AT_ScopedLockable:
4848245431Sdim    handleScopedLockableAttr(S, D, Attr);
4849226890Sdim    break;
4850252723Sdim  case AttributeList::AT_NoSanitizeAddress:
4851252723Sdim    handleNoSanitizeAddressAttr(S, D, Attr);
4852235633Sdim    break;
4853245431Sdim  case AttributeList::AT_NoThreadSafetyAnalysis:
4854252723Sdim    handleNoThreadSafetyAnalysis(S, D, Attr);
4855226890Sdim    break;
4856252723Sdim  case AttributeList::AT_NoSanitizeThread:
4857252723Sdim    handleNoSanitizeThread(S, D, Attr);
4858252723Sdim    break;
4859252723Sdim  case AttributeList::AT_NoSanitizeMemory:
4860252723Sdim    handleNoSanitizeMemory(S, D, Attr);
4861252723Sdim    break;
4862245431Sdim  case AttributeList::AT_Lockable:
4863226890Sdim    handleLockableAttr(S, D, Attr);
4864226890Sdim    break;
4865245431Sdim  case AttributeList::AT_GuardedBy:
4866226890Sdim    handleGuardedByAttr(S, D, Attr);
4867226890Sdim    break;
4868245431Sdim  case AttributeList::AT_PtGuardedBy:
4869245431Sdim    handlePtGuardedByAttr(S, D, Attr);
4870226890Sdim    break;
4871245431Sdim  case AttributeList::AT_ExclusiveLockFunction:
4872245431Sdim    handleExclusiveLockFunctionAttr(S, D, Attr);
4873226890Sdim    break;
4874245431Sdim  case AttributeList::AT_ExclusiveLocksRequired:
4875245431Sdim    handleExclusiveLocksRequiredAttr(S, D, Attr);
4876226890Sdim    break;
4877245431Sdim  case AttributeList::AT_ExclusiveTrylockFunction:
4878245431Sdim    handleExclusiveTrylockFunctionAttr(S, D, Attr);
4879226890Sdim    break;
4880245431Sdim  case AttributeList::AT_LockReturned:
4881226890Sdim    handleLockReturnedAttr(S, D, Attr);
4882226890Sdim    break;
4883245431Sdim  case AttributeList::AT_LocksExcluded:
4884226890Sdim    handleLocksExcludedAttr(S, D, Attr);
4885226890Sdim    break;
4886245431Sdim  case AttributeList::AT_SharedLockFunction:
4887245431Sdim    handleSharedLockFunctionAttr(S, D, Attr);
4888226890Sdim    break;
4889245431Sdim  case AttributeList::AT_SharedLocksRequired:
4890245431Sdim    handleSharedLocksRequiredAttr(S, D, Attr);
4891226890Sdim    break;
4892245431Sdim  case AttributeList::AT_SharedTrylockFunction:
4893245431Sdim    handleSharedTrylockFunctionAttr(S, D, Attr);
4894226890Sdim    break;
4895245431Sdim  case AttributeList::AT_UnlockFunction:
4896226890Sdim    handleUnlockFunAttr(S, D, Attr);
4897226890Sdim    break;
4898245431Sdim  case AttributeList::AT_AcquiredBefore:
4899245431Sdim    handleAcquiredBeforeAttr(S, D, Attr);
4900226890Sdim    break;
4901245431Sdim  case AttributeList::AT_AcquiredAfter:
4902245431Sdim    handleAcquiredAfterAttr(S, D, Attr);
4903226890Sdim    break;
4904226890Sdim
4905263509Sdim  // Consumed analysis attributes.
4906263509Sdim  case AttributeList::AT_Consumable:
4907263509Sdim    handleConsumableAttr(S, D, Attr);
4908263509Sdim    break;
4909263509Sdim  case AttributeList::AT_CallableWhen:
4910263509Sdim    handleCallableWhenAttr(S, D, Attr);
4911263509Sdim    break;
4912263509Sdim  case AttributeList::AT_ParamTypestate:
4913263509Sdim    handleParamTypestateAttr(S, D, Attr);
4914263509Sdim    break;
4915263509Sdim  case AttributeList::AT_ReturnTypestate:
4916263509Sdim    handleReturnTypestateAttr(S, D, Attr);
4917263509Sdim    break;
4918263509Sdim  case AttributeList::AT_SetTypestate:
4919263509Sdim    handleSetTypestateAttr(S, D, Attr);
4920263509Sdim    break;
4921263509Sdim  case AttributeList::AT_TestTypestate:
4922263509Sdim    handleTestTypestateAttr(S, D, Attr);
4923263509Sdim    break;
4924263509Sdim
4925245431Sdim  // Type safety attributes.
4926245431Sdim  case AttributeList::AT_ArgumentWithTypeTag:
4927245431Sdim    handleArgumentWithTypeTagAttr(S, D, Attr);
4928245431Sdim    break;
4929245431Sdim  case AttributeList::AT_TypeTagForDatatype:
4930245431Sdim    handleTypeTagForDatatypeAttr(S, D, Attr);
4931245431Sdim    break;
4932245431Sdim
4933193326Sed  default:
4934202379Srdivacky    // Ask target about the attribute.
4935202379Srdivacky    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
4936202379Srdivacky    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
4937245431Sdim      S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
4938245431Sdim             diag::warn_unhandled_ms_attribute_ignored :
4939245431Sdim             diag::warn_unknown_attribute_ignored) << Attr.getName();
4940193326Sed    break;
4941193326Sed  }
4942193326Sed}
4943193326Sed
4944193326Sed/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
4945193326Sed/// attribute list to the specified decl, ignoring any type attributes.
4946218893Sdimvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
4947218893Sdim                                    const AttributeList *AttrList,
4948252723Sdim                                    bool IncludeCXX11Attributes) {
4949252723Sdim  for (const AttributeList* l = AttrList; l; l = l->getNext())
4950263509Sdim    ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes);
4951204643Srdivacky
4952204643Srdivacky  // GCC accepts
4953204643Srdivacky  // static int a9 __attribute__((weakref));
4954204643Srdivacky  // but that looks really pointless. We reject it.
4955263509Sdim  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
4956204643Srdivacky    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
4957252723Sdim    cast<NamedDecl>(D)->getNameAsString();
4958252723Sdim    D->dropAttr<WeakRefAttr>();
4959204643Srdivacky    return;
4960204643Srdivacky  }
4961193326Sed}
4962193326Sed
4963226890Sdim// Annotation attributes are the only attributes allowed after an access
4964226890Sdim// specifier.
4965226890Sdimbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
4966226890Sdim                                          const AttributeList *AttrList) {
4967226890Sdim  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
4968245431Sdim    if (l->getKind() == AttributeList::AT_Annotate) {
4969226890Sdim      handleAnnotateAttr(*this, ASDecl, *l);
4970226890Sdim    } else {
4971226890Sdim      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
4972226890Sdim      return true;
4973226890Sdim    }
4974226890Sdim  }
4975226890Sdim
4976226890Sdim  return false;
4977226890Sdim}
4978226890Sdim
4979226890Sdim/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4980226890Sdim/// contains any decl attributes that we should warn about.
4981226890Sdimstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4982226890Sdim  for ( ; A; A = A->getNext()) {
4983226890Sdim    // Only warn if the attribute is an unignored, non-type attribute.
4984252723Sdim    if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
4985226890Sdim    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4986226890Sdim
4987226890Sdim    if (A->getKind() == AttributeList::UnknownAttribute) {
4988226890Sdim      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4989226890Sdim        << A->getName() << A->getRange();
4990226890Sdim    } else {
4991226890Sdim      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4992226890Sdim        << A->getName() << A->getRange();
4993226890Sdim    }
4994226890Sdim  }
4995226890Sdim}
4996226890Sdim
4997226890Sdim/// checkUnusedDeclAttributes - Given a declarator which is not being
4998226890Sdim/// used to build a declaration, complain about any decl attributes
4999226890Sdim/// which might be lying around on it.
5000226890Sdimvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
5001226890Sdim  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
5002226890Sdim  ::checkUnusedDeclAttributes(*this, D.getAttributes());
5003226890Sdim  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
5004226890Sdim    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
5005226890Sdim}
5006226890Sdim
5007198092Srdivacky/// DeclClonePragmaWeak - clone existing decl (maybe definition),
5008245431Sdim/// \#pragma weak needs a non-definition decl and source may not have one.
5009226890SdimNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
5010226890Sdim                                      SourceLocation Loc) {
5011198092Srdivacky  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
5012198092Srdivacky  NamedDecl *NewD = 0;
5013198092Srdivacky  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
5014226890Sdim    FunctionDecl *NewFD;
5015226890Sdim    // FIXME: Missing call to CheckFunctionDeclaration().
5016226890Sdim    // FIXME: Mangling?
5017226890Sdim    // FIXME: Is the qualifier info correct?
5018226890Sdim    // FIXME: Is the DeclContext correct?
5019226890Sdim    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
5020226890Sdim                                 Loc, Loc, DeclarationName(II),
5021226890Sdim                                 FD->getType(), FD->getTypeSourceInfo(),
5022252723Sdim                                 SC_None, false/*isInlineSpecified*/,
5023226890Sdim                                 FD->hasPrototype(),
5024226890Sdim                                 false/*isConstexprSpecified*/);
5025226890Sdim    NewD = NewFD;
5026226890Sdim
5027226890Sdim    if (FD->getQualifier())
5028219077Sdim      NewFD->setQualifierInfo(FD->getQualifierLoc());
5029226890Sdim
5030226890Sdim    // Fake up parameter variables; they are declared as if this were
5031226890Sdim    // a typedef.
5032226890Sdim    QualType FDTy = FD->getType();
5033226890Sdim    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
5034226890Sdim      SmallVector<ParmVarDecl*, 16> Params;
5035226890Sdim      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
5036226890Sdim           AE = FT->arg_type_end(); AI != AE; ++AI) {
5037226890Sdim        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
5038226890Sdim        Param->setScopeInfo(0, Params.size());
5039226890Sdim        Params.push_back(Param);
5040226890Sdim      }
5041226890Sdim      NewFD->setParams(Params);
5042205219Srdivacky    }
5043198092Srdivacky  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
5044198092Srdivacky    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
5045221345Sdim                           VD->getInnerLocStart(), VD->getLocation(), II,
5046200583Srdivacky                           VD->getType(), VD->getTypeSourceInfo(),
5047252723Sdim                           VD->getStorageClass());
5048205219Srdivacky    if (VD->getQualifier()) {
5049205219Srdivacky      VarDecl *NewVD = cast<VarDecl>(NewD);
5050219077Sdim      NewVD->setQualifierInfo(VD->getQualifierLoc());
5051205219Srdivacky    }
5052198092Srdivacky  }
5053198092Srdivacky  return NewD;
5054198092Srdivacky}
5055198092Srdivacky
5056245431Sdim/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
5057198092Srdivacky/// applied to it, possibly with an alias.
5058198092Srdivackyvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
5059198092Srdivacky  if (W.getUsed()) return; // only do this once
5060198092Srdivacky  W.setUsed(true);
5061198092Srdivacky  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
5062198092Srdivacky    IdentifierInfo *NDId = ND->getIdentifier();
5063226890Sdim    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
5064212904Sdim    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
5065212904Sdim                                            NDId->getName()));
5066212904Sdim    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
5067198092Srdivacky    WeakTopLevelDecl.push_back(NewD);
5068198092Srdivacky    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
5069198092Srdivacky    // to insert Decl at TU scope, sorry.
5070198092Srdivacky    DeclContext *SavedContext = CurContext;
5071198092Srdivacky    CurContext = Context.getTranslationUnitDecl();
5072198092Srdivacky    PushOnScopeChains(NewD, S);
5073198092Srdivacky    CurContext = SavedContext;
5074198092Srdivacky  } else { // just add weak to existing
5075212904Sdim    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
5076198092Srdivacky  }
5077198092Srdivacky}
5078198092Srdivacky
5079252723Sdimvoid Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
5080218893Sdim  // It's valid to "forward-declare" #pragma weak, in which case we
5081218893Sdim  // have to do this.
5082252723Sdim  LoadExternalWeakUndeclaredIdentifiers();
5083252723Sdim  if (!WeakUndeclaredIdentifiers.empty()) {
5084252723Sdim    NamedDecl *ND = NULL;
5085252723Sdim    if (VarDecl *VD = dyn_cast<VarDecl>(D))
5086252723Sdim      if (VD->isExternC())
5087252723Sdim        ND = VD;
5088252723Sdim    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5089252723Sdim      if (FD->isExternC())
5090252723Sdim        ND = FD;
5091252723Sdim    if (ND) {
5092252723Sdim      if (IdentifierInfo *Id = ND->getIdentifier()) {
5093252723Sdim        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
5094252723Sdim          = WeakUndeclaredIdentifiers.find(Id);
5095252723Sdim        if (I != WeakUndeclaredIdentifiers.end()) {
5096252723Sdim          WeakInfo W = I->second;
5097252723Sdim          DeclApplyPragmaWeak(S, ND, W);
5098252723Sdim          WeakUndeclaredIdentifiers[Id] = W;
5099218893Sdim        }
5100198092Srdivacky      }
5101198092Srdivacky    }
5102198092Srdivacky  }
5103252723Sdim}
5104198092Srdivacky
5105252723Sdim/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
5106252723Sdim/// it, apply them to D.  This is a bit tricky because PD can have attributes
5107252723Sdim/// specified in many different places, and we need to find and apply them all.
5108263509Sdimvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
5109193326Sed  // Apply decl attributes from the DeclSpec if present.
5110218893Sdim  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
5111263509Sdim    ProcessDeclAttributeList(S, D, Attrs);
5112198092Srdivacky
5113193326Sed  // Walk the declarator structure, applying decl attributes that were in a type
5114193326Sed  // position to the decl itself.  This handles cases like:
5115193326Sed  //   int *__attr__(x)** D;
5116193326Sed  // when X is a decl attribute.
5117193326Sed  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
5118193326Sed    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
5119263509Sdim      ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false);
5120198092Srdivacky
5121193326Sed  // Finally, apply any attributes on the decl itself.
5122193326Sed  if (const AttributeList *Attrs = PD.getAttributes())
5123263509Sdim    ProcessDeclAttributeList(S, D, Attrs);
5124193326Sed}
5125198893Srdivacky
5126224145Sdim/// Is the given declaration allowed to use a forbidden type?
5127224145Sdimstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
5128224145Sdim  // Private ivars are always okay.  Unfortunately, people don't
5129224145Sdim  // always properly make their ivars private, even in system headers.
5130224145Sdim  // Plus we need to make fields okay, too.
5131226890Sdim  // Function declarations in sys headers will be marked unavailable.
5132226890Sdim  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
5133226890Sdim      !isa<FunctionDecl>(decl))
5134224145Sdim    return false;
5135224145Sdim
5136224145Sdim  // Require it to be declared in a system header.
5137224145Sdim  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
5138224145Sdim}
5139224145Sdim
5140224145Sdim/// Handle a delayed forbidden-type diagnostic.
5141224145Sdimstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
5142224145Sdim                                       Decl *decl) {
5143224145Sdim  if (decl && isForbiddenTypeAllowed(S, decl)) {
5144224145Sdim    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
5145224145Sdim                        "this system declaration uses an unsupported type"));
5146224145Sdim    return;
5147224145Sdim  }
5148235633Sdim  if (S.getLangOpts().ObjCAutoRefCount)
5149226890Sdim    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
5150245431Sdim      // FIXME: we may want to suppress diagnostics for all
5151226890Sdim      // kind of forbidden type messages on unavailable functions.
5152226890Sdim      if (FD->hasAttr<UnavailableAttr>() &&
5153226890Sdim          diag.getForbiddenTypeDiagnostic() ==
5154226890Sdim          diag::err_arc_array_param_no_ownership) {
5155226890Sdim        diag.Triggered = true;
5156226890Sdim        return;
5157226890Sdim      }
5158226890Sdim    }
5159224145Sdim
5160224145Sdim  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
5161224145Sdim    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
5162224145Sdim  diag.Triggered = true;
5163224145Sdim}
5164224145Sdim
5165245431Sdimvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
5166245431Sdim  assert(DelayedDiagnostics.getCurrentPool());
5167245431Sdim  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
5168245431Sdim  DelayedDiagnostics.popWithoutEmitting(state);
5169218893Sdim
5170245431Sdim  // When delaying diagnostics to run in the context of a parsed
5171245431Sdim  // declaration, we only want to actually emit anything if parsing
5172245431Sdim  // succeeds.
5173245431Sdim  if (!decl) return;
5174218893Sdim
5175245431Sdim  // We emit all the active diagnostics in this pool or any of its
5176245431Sdim  // parents.  In general, we'll get one pool for the decl spec
5177245431Sdim  // and a child pool for each declarator; in a decl group like:
5178245431Sdim  //   deprecated_typedef foo, *bar, baz();
5179245431Sdim  // only the declarator pops will be passed decls.  This is correct;
5180245431Sdim  // we really do need to consider delayed diagnostics from the decl spec
5181245431Sdim  // for each of the different declarations.
5182245431Sdim  const DelayedDiagnosticPool *pool = &poppedPool;
5183245431Sdim  do {
5184245431Sdim    for (DelayedDiagnosticPool::pool_iterator
5185245431Sdim           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
5186245431Sdim      // This const_cast is a bit lame.  Really, Triggered should be mutable.
5187245431Sdim      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
5188218893Sdim      if (diag.Triggered)
5189203955Srdivacky        continue;
5190198893Srdivacky
5191218893Sdim      switch (diag.Kind) {
5192203955Srdivacky      case DelayedDiagnostic::Deprecation:
5193235633Sdim        // Don't bother giving deprecation diagnostics if the decl is invalid.
5194235633Sdim        if (!decl->isInvalidDecl())
5195245431Sdim          HandleDelayedDeprecationCheck(diag, decl);
5196203955Srdivacky        break;
5197203955Srdivacky
5198203955Srdivacky      case DelayedDiagnostic::Access:
5199245431Sdim        HandleDelayedAccessCheck(diag, decl);
5200203955Srdivacky        break;
5201224145Sdim
5202224145Sdim      case DelayedDiagnostic::ForbiddenType:
5203245431Sdim        handleDelayedForbiddenType(*this, diag, decl);
5204224145Sdim        break;
5205198893Srdivacky      }
5206198893Srdivacky    }
5207245431Sdim  } while ((pool = pool->getParent()));
5208245431Sdim}
5209198893Srdivacky
5210245431Sdim/// Given a set of delayed diagnostics, re-emit them as if they had
5211245431Sdim/// been delayed in the current context instead of in the given pool.
5212245431Sdim/// Essentially, this just moves them to the current pool.
5213245431Sdimvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
5214245431Sdim  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
5215245431Sdim  assert(curPool && "re-emitting in undelayed context not supported");
5216245431Sdim  curPool->steal(pool);
5217198893Srdivacky}
5218198893Srdivacky
5219203955Srdivackystatic bool isDeclDeprecated(Decl *D) {
5220203955Srdivacky  do {
5221221345Sdim    if (D->isDeprecated())
5222203955Srdivacky      return true;
5223226890Sdim    // A category implicitly has the availability of the interface.
5224226890Sdim    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
5225226890Sdim      return CatD->getClassInterface()->isDeprecated();
5226203955Srdivacky  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
5227203955Srdivacky  return false;
5228203955Srdivacky}
5229203955Srdivacky
5230245431Sdimstatic void
5231245431SdimDoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
5232245431Sdim                         SourceLocation Loc,
5233245431Sdim                         const ObjCInterfaceDecl *UnknownObjCClass,
5234245431Sdim                         const ObjCPropertyDecl *ObjCPropery) {
5235245431Sdim  DeclarationName Name = D->getDeclName();
5236245431Sdim  if (!Message.empty()) {
5237245431Sdim    S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
5238245431Sdim    S.Diag(D->getLocation(),
5239245431Sdim           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5240245431Sdim                                  : diag::note_previous_decl) << Name;
5241245431Sdim    if (ObjCPropery)
5242245431Sdim      S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5243245431Sdim        << ObjCPropery->getDeclName() << 0;
5244245431Sdim  } else if (!UnknownObjCClass) {
5245245431Sdim    S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
5246245431Sdim    S.Diag(D->getLocation(),
5247245431Sdim           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5248245431Sdim                                  : diag::note_previous_decl) << Name;
5249245431Sdim    if (ObjCPropery)
5250245431Sdim      S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5251245431Sdim        << ObjCPropery->getDeclName() << 0;
5252245431Sdim  } else {
5253245431Sdim    S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
5254245431Sdim    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
5255245431Sdim  }
5256245431Sdim}
5257245431Sdim
5258212904Sdimvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
5259203955Srdivacky                                         Decl *Ctx) {
5260203955Srdivacky  if (isDeclDeprecated(Ctx))
5261203955Srdivacky    return;
5262203955Srdivacky
5263203955Srdivacky  DD.Triggered = true;
5264245431Sdim  DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
5265245431Sdim                           DD.getDeprecationMessage(), DD.Loc,
5266245431Sdim                           DD.getUnknownObjCClass(),
5267245431Sdim                           DD.getObjCProperty());
5268203955Srdivacky}
5269203955Srdivacky
5270226890Sdimvoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
5271218893Sdim                                  SourceLocation Loc,
5272245431Sdim                                  const ObjCInterfaceDecl *UnknownObjCClass,
5273245431Sdim                                  const ObjCPropertyDecl  *ObjCProperty) {
5274198893Srdivacky  // Delay if we're currently parsing a declaration.
5275218893Sdim  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
5276235633Sdim    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
5277235633Sdim                                                              UnknownObjCClass,
5278245431Sdim                                                              ObjCProperty,
5279235633Sdim                                                              Message));
5280198893Srdivacky    return;
5281198893Srdivacky  }
5282198893Srdivacky
5283198893Srdivacky  // Otherwise, don't warn if our current context is deprecated.
5284226890Sdim  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
5285198893Srdivacky    return;
5286245431Sdim  DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty);
5287198893Srdivacky}
5288