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"
17239462Sdim#include "clang/AST/CXXInheritance.h"
18212904Sdim#include "clang/AST/DeclCXX.h"
19249423Sdim#include "clang/AST/DeclObjC.h"
20226633Sdim#include "clang/AST/DeclTemplate.h"
21193326Sed#include "clang/AST/Expr.h"
22249423Sdim#include "clang/AST/Mangle.h"
23249423Sdim#include "clang/Basic/CharInfo.h"
24224145Sdim#include "clang/Basic/SourceManager.h"
25193326Sed#include "clang/Basic/TargetInfo.h"
26263508Sdim#include "clang/Lex/Preprocessor.h"
27212904Sdim#include "clang/Sema/DeclSpec.h"
28212904Sdim#include "clang/Sema/DelayedDiagnostic.h"
29226633Sdim#include "clang/Sema/Lookup.h"
30249423Sdim#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.
37226633Sdimenum AttributeDeclKind {
38221345Sdim  ExpectedFunction,
39221345Sdim  ExpectedUnion,
40221345Sdim  ExpectedVariableOrFunction,
41221345Sdim  ExpectedFunctionOrMethod,
42221345Sdim  ExpectedParameter,
43221345Sdim  ExpectedFunctionMethodOrBlock,
44249423Sdim  ExpectedFunctionMethodOrClass,
45221345Sdim  ExpectedFunctionMethodOrParameter,
46221345Sdim  ExpectedClass,
47221345Sdim  ExpectedVariable,
48221345Sdim  ExpectedMethod,
49226633Sdim  ExpectedVariableFunctionOrLabel,
50234353Sdim  ExpectedFieldOrGlobalVar,
51239462Sdim  ExpectedStruct,
52249423Sdim  ExpectedVariableFunctionOrTag,
53249423Sdim  ExpectedTLSVar,
54249423Sdim  ExpectedVariableOrField,
55249423Sdim  ExpectedVariableFieldOrTag,
56263508Sdim  ExpectedTypeOrNamespace,
57263508Sdim  ExpectedObjectiveCInterface,
58263508Sdim  ExpectedMethodOrProperty,
59263508Sdim  ExpectedStructOrUnion,
60263508Sdim  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) {
100239462Sdim  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
212263508Sdimstatic unsigned getNumAttributeArgs(const AttributeList &Attr) {
213263508Sdim  // FIXME: Include the type in the argument list.
214263508Sdim  return Attr.getNumArgs() + Attr.hasParsedType();
215263508Sdim}
216263508Sdim
217226633Sdim/// \brief Check if the attribute has exactly as many args as Num. May
218226633Sdim/// output an error.
219224145Sdimstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
220263508Sdim                                  unsigned Num) {
221263508Sdim  if (getNumAttributeArgs(Attr) != Num) {
222263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
223263508Sdim      << Attr.getName() << Num;
224224145Sdim    return false;
225224145Sdim  }
226224145Sdim
227224145Sdim  return true;
228224145Sdim}
229224145Sdim
230226633Sdim
231226633Sdim/// \brief Check if the attribute has at least as many args as Num. May
232226633Sdim/// output an error.
233226633Sdimstatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
234263508Sdim                                         unsigned Num) {
235263508Sdim  if (getNumAttributeArgs(Attr) < Num) {
236226633Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
237226633Sdim    return false;
238226633Sdim  }
239226633Sdim
240226633Sdim  return true;
241226633Sdim}
242226633Sdim
243239462Sdim/// \brief Check if IdxExpr is a valid argument index for a function or
244239462Sdim/// instance method D.  May output an error.
245226633Sdim///
246239462Sdim/// \returns true if IdxExpr is a valid index.
247239462Sdimstatic bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
248239462Sdim                                               StringRef AttrName,
249239462Sdim                                               SourceLocation AttrLoc,
250239462Sdim                                               unsigned AttrArgNum,
251239462Sdim                                               const Expr *IdxExpr,
252239462Sdim                                               uint64_t &Idx)
253239462Sdim{
254263508Sdim  assert(isFunctionOrMethod(D));
255239462Sdim
256239462Sdim  // In C++ the implicit 'this' function parameter also counts.
257239462Sdim  // Parameters are counted from one.
258263508Sdim  bool HP = hasFunctionProto(D);
259263508Sdim  bool HasImplicitThisParam = isInstanceMethod(D);
260263508Sdim  bool IV = HP && isFunctionOrMethodVariadic(D);
261263508Sdim  unsigned NumArgs = (HP ? getFunctionOrMethodNumArgs(D) : 0) +
262263508Sdim                     HasImplicitThisParam;
263239462Sdim
264239462Sdim  llvm::APSInt IdxInt;
265239462Sdim  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
266239462Sdim      !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
267263508Sdim    std::string Name = std::string("'") + AttrName.str() + std::string("'");
268263508Sdim    S.Diag(AttrLoc, diag::err_attribute_argument_n_type) << Name.c_str()
269263508Sdim      << AttrArgNum << AANT_ArgumentIntegerConstant << IdxExpr->getSourceRange();
270239462Sdim    return false;
271239462Sdim  }
272239462Sdim
273239462Sdim  Idx = IdxInt.getLimitedValue();
274263508Sdim  if (Idx < 1 || (!IV && Idx > NumArgs)) {
275239462Sdim    S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds)
276239462Sdim      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
277239462Sdim    return false;
278239462Sdim  }
279239462Sdim  Idx--; // Convert to zero-based.
280239462Sdim  if (HasImplicitThisParam) {
281239462Sdim    if (Idx == 0) {
282239462Sdim      S.Diag(AttrLoc,
283239462Sdim             diag::err_attribute_invalid_implicit_this_argument)
284239462Sdim        << AttrName << IdxExpr->getSourceRange();
285239462Sdim      return false;
286239462Sdim    }
287239462Sdim    --Idx;
288239462Sdim  }
289239462Sdim
290239462Sdim  return true;
291239462Sdim}
292239462Sdim
293263508Sdim/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
294263508Sdim/// If not emit an error and return false. If the argument is an identifier it
295263508Sdim/// will emit an error with a fixit hint and treat it as if it was a string
296263508Sdim/// literal.
297263508Sdimbool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr,
298263508Sdim                                          unsigned ArgNum, StringRef &Str,
299263508Sdim                                          SourceLocation *ArgLocation) {
300263508Sdim  // Look for identifiers. If we have one emit a hint to fix it to a literal.
301263508Sdim  if (Attr.isArgIdent(ArgNum)) {
302263508Sdim    IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
303263508Sdim    Diag(Loc->Loc, diag::err_attribute_argument_type)
304263508Sdim        << Attr.getName() << AANT_ArgumentString
305263508Sdim        << FixItHint::CreateInsertion(Loc->Loc, "\"")
306263508Sdim        << FixItHint::CreateInsertion(PP.getLocForEndOfToken(Loc->Loc), "\"");
307263508Sdim    Str = Loc->Ident->getName();
308263508Sdim    if (ArgLocation)
309263508Sdim      *ArgLocation = Loc->Loc;
310263508Sdim    return true;
311263508Sdim  }
312263508Sdim
313263508Sdim  // Now check for an actual string literal.
314263508Sdim  Expr *ArgExpr = Attr.getArgAsExpr(ArgNum);
315263508Sdim  StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
316263508Sdim  if (ArgLocation)
317263508Sdim    *ArgLocation = ArgExpr->getLocStart();
318263508Sdim
319263508Sdim  if (!Literal || !Literal->isAscii()) {
320263508Sdim    Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
321263508Sdim        << Attr.getName() << AANT_ArgumentString;
322263508Sdim    return false;
323263508Sdim  }
324263508Sdim
325263508Sdim  Str = Literal->getString();
326263508Sdim  return true;
327263508Sdim}
328263508Sdim
329239462Sdim///
330226633Sdim/// \brief Check if passed in Decl is a field or potentially shared global var
331226633Sdim/// \return true if the Decl is a field or potentially shared global variable
332226633Sdim///
333226633Sdimstatic bool mayBeSharedVariable(const Decl *D) {
334226633Sdim  if (isa<FieldDecl>(D))
335226633Sdim    return true;
336226633Sdim  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
337251662Sdim    return vd->hasGlobalStorage() && !vd->getTLSKind();
338226633Sdim
339226633Sdim  return false;
340226633Sdim}
341226633Sdim
342226633Sdim/// \brief Check if the passed-in expression is of type int or bool.
343226633Sdimstatic bool isIntOrBool(Expr *Exp) {
344226633Sdim  QualType QT = Exp->getType();
345226633Sdim  return QT->isBooleanType() || QT->isIntegerType();
346226633Sdim}
347226633Sdim
348239462Sdim
349239462Sdim// Check to see if the type is a smart pointer of some kind.  We assume
350239462Sdim// it's a smart pointer if it defines both operator-> and operator*.
351239462Sdimstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
352239462Sdim  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
353239462Sdim    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
354249423Sdim  if (Res1.empty())
355239462Sdim    return false;
356239462Sdim
357239462Sdim  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
358239462Sdim    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
359249423Sdim  if (Res2.empty())
360239462Sdim    return false;
361239462Sdim
362239462Sdim  return true;
363239462Sdim}
364239462Sdim
365226633Sdim/// \brief Check if passed in Decl is a pointer type.
366226633Sdim/// Note that this function may produce an error message.
367226633Sdim/// \return true if the Decl is a pointer type; false otherwise
368239462Sdimstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
369239462Sdim                                       const AttributeList &Attr) {
370226633Sdim  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
371226633Sdim    QualType QT = vd->getType();
372226633Sdim    if (QT->isAnyPointerType())
373226633Sdim      return true;
374239462Sdim
375239462Sdim    if (const RecordType *RT = QT->getAs<RecordType>()) {
376239462Sdim      // If it's an incomplete type, it could be a smart pointer; skip it.
377239462Sdim      // (We don't want to force template instantiation if we can avoid it,
378239462Sdim      // since that would alter the order in which templates are instantiated.)
379239462Sdim      if (RT->isIncompleteType())
380239462Sdim        return true;
381239462Sdim
382239462Sdim      if (threadSafetyCheckIsSmartPointer(S, RT))
383239462Sdim        return true;
384239462Sdim    }
385239462Sdim
386239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
387226633Sdim      << Attr.getName()->getName() << QT;
388226633Sdim  } else {
389226633Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
390226633Sdim      << Attr.getName();
391226633Sdim  }
392226633Sdim  return false;
393226633Sdim}
394226633Sdim
395226633Sdim/// \brief Checks that the passed in QualType either is of RecordType or points
396226633Sdim/// to RecordType. Returns the relevant RecordType, null if it does not exit.
397226633Sdimstatic const RecordType *getRecordType(QualType QT) {
398226633Sdim  if (const RecordType *RT = QT->getAs<RecordType>())
399226633Sdim    return RT;
400226633Sdim
401226633Sdim  // Now check if we point to record type.
402226633Sdim  if (const PointerType *PT = QT->getAs<PointerType>())
403226633Sdim    return PT->getPointeeType()->getAs<RecordType>();
404226633Sdim
405226633Sdim  return 0;
406226633Sdim}
407226633Sdim
408239462Sdim
409239462Sdimstatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
410239462Sdim                                             CXXBasePath &Path, void *Unused) {
411239462Sdim  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
412239462Sdim  if (RT->getDecl()->getAttr<LockableAttr>())
413239462Sdim    return true;
414239462Sdim  return false;
415239462Sdim}
416239462Sdim
417239462Sdim
418226633Sdim/// \brief Thread Safety Analysis: Checks that the passed in RecordType
419239462Sdim/// resolves to a lockable object.
420234353Sdimstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
421234353Sdim                                   QualType Ty) {
422234353Sdim  const RecordType *RT = getRecordType(Ty);
423239462Sdim
424234353Sdim  // Warn if could not get record type for this argument.
425226633Sdim  if (!RT) {
426239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
427234353Sdim      << Attr.getName() << Ty.getAsString();
428234353Sdim    return;
429226633Sdim  }
430239462Sdim
431239462Sdim  // Don't check for lockable if the class hasn't been defined yet.
432234353Sdim  if (RT->isIncompleteType())
433234353Sdim    return;
434239462Sdim
435239462Sdim  // Allow smart pointers to be used as lockable objects.
436239462Sdim  // FIXME -- Check the type that the smart pointer points to.
437239462Sdim  if (threadSafetyCheckIsSmartPointer(S, RT))
438234353Sdim    return;
439239462Sdim
440239462Sdim  // Check if the type is lockable.
441239462Sdim  RecordDecl *RD = RT->getDecl();
442239462Sdim  if (RD->getAttr<LockableAttr>())
443239462Sdim    return;
444239462Sdim
445239462Sdim  // Else check if any base classes are lockable.
446239462Sdim  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
447239462Sdim    CXXBasePaths BPaths(false, false);
448239462Sdim    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
449239462Sdim      return;
450226633Sdim  }
451239462Sdim
452239462Sdim  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
453239462Sdim    << Attr.getName() << Ty.getAsString();
454226633Sdim}
455226633Sdim
456226633Sdim/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
457239462Sdim/// from Sidx, resolve to a lockable object.
458226633Sdim/// \param Sidx The attribute argument index to start checking with.
459226633Sdim/// \param ParamIdxOk Whether an argument can be indexing into a function
460226633Sdim/// parameter list.
461239462Sdimstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
462226633Sdim                                         const AttributeList &Attr,
463226633Sdim                                         SmallVectorImpl<Expr*> &Args,
464226633Sdim                                         int Sidx = 0,
465226633Sdim                                         bool ParamIdxOk = false) {
466226633Sdim  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
467263508Sdim    Expr *ArgExp = Attr.getArgAsExpr(Idx);
468226633Sdim
469226633Sdim    if (ArgExp->isTypeDependent()) {
470239462Sdim      // FIXME -- need to check this again on template instantiation
471226633Sdim      Args.push_back(ArgExp);
472226633Sdim      continue;
473226633Sdim    }
474226633Sdim
475239462Sdim    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
476243830Sdim      if (StrLit->getLength() == 0 ||
477263508Sdim          (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) {
478243830Sdim        // Pass empty strings to the analyzer without warnings.
479243830Sdim        // Treat "*" as the universal lock.
480243830Sdim        Args.push_back(ArgExp);
481239462Sdim        continue;
482243830Sdim      }
483239462Sdim
484239462Sdim      // We allow constant strings to be used as a placeholder for expressions
485239462Sdim      // that are not valid C++ syntax, but warn that they are ignored.
486239462Sdim      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
487239462Sdim        Attr.getName();
488243830Sdim      Args.push_back(ArgExp);
489239462Sdim      continue;
490239462Sdim    }
491239462Sdim
492226633Sdim    QualType ArgTy = ArgExp->getType();
493226633Sdim
494239462Sdim    // A pointer to member expression of the form  &MyClass::mu is treated
495239462Sdim    // specially -- we need to look at the type of the member.
496239462Sdim    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
497239462Sdim      if (UOp->getOpcode() == UO_AddrOf)
498239462Sdim        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
499239462Sdim          if (DRE->getDecl()->isCXXInstanceMember())
500239462Sdim            ArgTy = DRE->getDecl()->getType();
501239462Sdim
502226633Sdim    // First see if we can just cast to record type, or point to record type.
503226633Sdim    const RecordType *RT = getRecordType(ArgTy);
504226633Sdim
505226633Sdim    // Now check if we index into a record type function param.
506226633Sdim    if(!RT && ParamIdxOk) {
507226633Sdim      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
508226633Sdim      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
509226633Sdim      if(FD && IL) {
510226633Sdim        unsigned int NumParams = FD->getNumParams();
511226633Sdim        llvm::APInt ArgValue = IL->getValue();
512226633Sdim        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
513226633Sdim        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
514226633Sdim        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
515226633Sdim          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
516226633Sdim            << Attr.getName() << Idx + 1 << NumParams;
517239462Sdim          continue;
518226633Sdim        }
519226633Sdim        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
520226633Sdim      }
521226633Sdim    }
522226633Sdim
523234353Sdim    checkForLockableRecord(S, D, Attr, ArgTy);
524226633Sdim
525226633Sdim    Args.push_back(ArgExp);
526226633Sdim  }
527226633Sdim}
528226633Sdim
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
537239462Sdimenum ThreadAttributeDeclKind {
538239462Sdim  ThreadExpectedFieldOrGlobalVar,
539239462Sdim  ThreadExpectedFunctionOrMethod,
540239462Sdim  ThreadExpectedClassOrStruct
541239462Sdim};
542239462Sdim
543239462Sdimstatic bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
544239462Sdim                                      const AttributeList &Attr) {
545226633Sdim  // D must be either a member field or global (potentially shared) variable.
546226633Sdim  if (!mayBeSharedVariable(D)) {
547239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
548239462Sdim      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
549239462Sdim    return false;
550226633Sdim  }
551226633Sdim
552239462Sdim  return true;
553239462Sdim}
554239462Sdim
555239462Sdimstatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
556239462Sdim  if (!checkGuardedVarAttrCommon(S, D, Attr))
557226633Sdim    return;
558226633Sdim
559249423Sdim  D->addAttr(::new (S.Context)
560249423Sdim             GuardedVarAttr(Attr.getRange(), S.Context,
561249423Sdim                            Attr.getAttributeSpellingListIndex()));
562226633Sdim}
563226633Sdim
564239462Sdimstatic void handlePtGuardedVarAttr(Sema &S, Decl *D,
565249423Sdim                                   const AttributeList &Attr) {
566239462Sdim  if (!checkGuardedVarAttrCommon(S, D, Attr))
567239462Sdim    return;
568239462Sdim
569239462Sdim  if (!threadSafetyCheckIsPointer(S, D, Attr))
570239462Sdim    return;
571239462Sdim
572249423Sdim  D->addAttr(::new (S.Context)
573249423Sdim             PtGuardedVarAttr(Attr.getRange(), S.Context,
574249423Sdim                              Attr.getAttributeSpellingListIndex()));
575239462Sdim}
576239462Sdim
577239462Sdimstatic bool checkGuardedByAttrCommon(Sema &S, Decl *D,
578239462Sdim                                     const AttributeList &Attr,
579239462Sdim                                     Expr* &Arg) {
580226633Sdim  // D must be either a member field or global (potentially shared) variable.
581226633Sdim  if (!mayBeSharedVariable(D)) {
582239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
583239462Sdim      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
584239462Sdim    return false;
585226633Sdim  }
586226633Sdim
587239462Sdim  SmallVector<Expr*, 1> Args;
588239462Sdim  // check that all arguments are lockable objects
589239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
590239462Sdim  unsigned Size = Args.size();
591239462Sdim  if (Size != 1)
592239462Sdim    return false;
593239462Sdim
594239462Sdim  Arg = Args[0];
595239462Sdim
596239462Sdim  return true;
597239462Sdim}
598239462Sdim
599239462Sdimstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
600239462Sdim  Expr *Arg = 0;
601239462Sdim  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
602226633Sdim    return;
603226633Sdim
604239462Sdim  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
605239462Sdim}
606226633Sdim
607239462Sdimstatic void handlePtGuardedByAttr(Sema &S, Decl *D,
608239462Sdim                                  const AttributeList &Attr) {
609239462Sdim  Expr *Arg = 0;
610239462Sdim  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
611239462Sdim    return;
612239462Sdim
613239462Sdim  if (!threadSafetyCheckIsPointer(S, D, Attr))
614239462Sdim    return;
615239462Sdim
616239462Sdim  D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
617239462Sdim                                               S.Context, Arg));
618226633Sdim}
619226633Sdim
620239462Sdimstatic bool checkLockableAttrCommon(Sema &S, Decl *D,
621239462Sdim                                    const AttributeList &Attr) {
622226633Sdim  // FIXME: Lockable structs for C code.
623263508Sdim  if (!isa<RecordDecl>(D)) {
624239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
625239462Sdim      << Attr.getName() << ThreadExpectedClassOrStruct;
626239462Sdim    return false;
627226633Sdim  }
628226633Sdim
629239462Sdim  return true;
630226633Sdim}
631226633Sdim
632239462Sdimstatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
633239462Sdim  if (!checkLockableAttrCommon(S, D, Attr))
634239462Sdim    return;
635239462Sdim
636239462Sdim  D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
637239462Sdim}
638239462Sdim
639239462Sdimstatic void handleScopedLockableAttr(Sema &S, Decl *D,
640239462Sdim                             const AttributeList &Attr) {
641239462Sdim  if (!checkLockableAttrCommon(S, D, Attr))
642239462Sdim    return;
643239462Sdim
644249423Sdim  D->addAttr(::new (S.Context)
645249423Sdim             ScopedLockableAttr(Attr.getRange(), S.Context,
646249423Sdim                                Attr.getAttributeSpellingListIndex()));
647239462Sdim}
648239462Sdim
649249423Sdimstatic void handleNoThreadSafetyAnalysis(Sema &S, Decl *D,
650249423Sdim                                         const AttributeList &Attr) {
651226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
652239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
653239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
654226633Sdim    return;
655226633Sdim  }
656226633Sdim
657226633Sdim  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
658226633Sdim                                                          S.Context));
659226633Sdim}
660226633Sdim
661249423Sdimstatic void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
662239462Sdim                                      const AttributeList &Attr) {
663234353Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
664249423Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
665234353Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
666234353Sdim    return;
667234353Sdim  }
668234353Sdim
669249423Sdim  D->addAttr(::new (S.Context)
670249423Sdim             NoSanitizeAddressAttr(Attr.getRange(), S.Context,
671249423Sdim                                   Attr.getAttributeSpellingListIndex()));
672234353Sdim}
673234353Sdim
674249423Sdimstatic void handleNoSanitizeMemory(Sema &S, Decl *D,
675249423Sdim                                   const AttributeList &Attr) {
676249423Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
677249423Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
678249423Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
679249423Sdim    return;
680249423Sdim  }
681249423Sdim
682249423Sdim  D->addAttr(::new (S.Context) NoSanitizeMemoryAttr(Attr.getRange(),
683249423Sdim                                                         S.Context));
684249423Sdim}
685249423Sdim
686249423Sdimstatic void handleNoSanitizeThread(Sema &S, Decl *D,
687249423Sdim                                   const AttributeList &Attr) {
688249423Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
689249423Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
690249423Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
691249423Sdim    return;
692249423Sdim  }
693249423Sdim
694249423Sdim  D->addAttr(::new (S.Context) NoSanitizeThreadAttr(Attr.getRange(),
695249423Sdim                                                    S.Context));
696249423Sdim}
697249423Sdim
698239462Sdimstatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
699239462Sdim                                        const AttributeList &Attr,
700263508Sdim                                        SmallVectorImpl<Expr *> &Args) {
701226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
702239462Sdim    return false;
703226633Sdim
704226633Sdim  // D must be either a member field or global (potentially shared) variable.
705226633Sdim  ValueDecl *VD = dyn_cast<ValueDecl>(D);
706226633Sdim  if (!VD || !mayBeSharedVariable(D)) {
707239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
708239462Sdim      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
709239462Sdim    return false;
710226633Sdim  }
711226633Sdim
712239462Sdim  // Check that this attribute only applies to lockable types.
713226633Sdim  QualType QT = VD->getType();
714226633Sdim  if (!QT->isDependentType()) {
715226633Sdim    const RecordType *RT = getRecordType(QT);
716226633Sdim    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
717239462Sdim      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
718239462Sdim        << Attr.getName();
719239462Sdim      return false;
720226633Sdim    }
721226633Sdim  }
722226633Sdim
723239462Sdim  // Check that all arguments are lockable objects.
724239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
725251662Sdim  if (Args.empty())
726239462Sdim    return false;
727239462Sdim
728239462Sdim  return true;
729239462Sdim}
730239462Sdim
731239462Sdimstatic void handleAcquiredAfterAttr(Sema &S, Decl *D,
732239462Sdim                                    const AttributeList &Attr) {
733226633Sdim  SmallVector<Expr*, 1> Args;
734239462Sdim  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
735226633Sdim    return;
736226633Sdim
737239462Sdim  Expr **StartArg = &Args[0];
738249423Sdim  D->addAttr(::new (S.Context)
739249423Sdim             AcquiredAfterAttr(Attr.getRange(), S.Context,
740249423Sdim                               StartArg, Args.size(),
741249423Sdim                               Attr.getAttributeSpellingListIndex()));
742239462Sdim}
743226633Sdim
744239462Sdimstatic void handleAcquiredBeforeAttr(Sema &S, Decl *D,
745239462Sdim                                     const AttributeList &Attr) {
746239462Sdim  SmallVector<Expr*, 1> Args;
747239462Sdim  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
748239462Sdim    return;
749239462Sdim
750239462Sdim  Expr **StartArg = &Args[0];
751249423Sdim  D->addAttr(::new (S.Context)
752249423Sdim             AcquiredBeforeAttr(Attr.getRange(), S.Context,
753249423Sdim                                StartArg, Args.size(),
754249423Sdim                                Attr.getAttributeSpellingListIndex()));
755226633Sdim}
756226633Sdim
757239462Sdimstatic bool checkLockFunAttrCommon(Sema &S, Decl *D,
758239462Sdim                                   const AttributeList &Attr,
759263508Sdim                                   SmallVectorImpl<Expr *> &Args) {
760226633Sdim  // zero or more arguments ok
761226633Sdim
762226633Sdim  // check that the attribute is applied to a function
763226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
764239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
765239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
766239462Sdim    return false;
767226633Sdim  }
768226633Sdim
769226633Sdim  // check that all arguments are lockable objects
770239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
771239462Sdim
772239462Sdim  return true;
773239462Sdim}
774239462Sdim
775239462Sdimstatic void handleSharedLockFunctionAttr(Sema &S, Decl *D,
776239462Sdim                                         const AttributeList &Attr) {
777226633Sdim  SmallVector<Expr*, 1> Args;
778239462Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
779226633Sdim    return;
780226633Sdim
781226633Sdim  unsigned Size = Args.size();
782226633Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
783249423Sdim  D->addAttr(::new (S.Context)
784249423Sdim             SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
785249423Sdim                                    Attr.getAttributeSpellingListIndex()));
786239462Sdim}
787226633Sdim
788239462Sdimstatic void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
789239462Sdim                                            const AttributeList &Attr) {
790239462Sdim  SmallVector<Expr*, 1> Args;
791239462Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
792239462Sdim    return;
793239462Sdim
794239462Sdim  unsigned Size = Args.size();
795239462Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
796249423Sdim  D->addAttr(::new (S.Context)
797249423Sdim             ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
798249423Sdim                                       StartArg, Size,
799249423Sdim                                       Attr.getAttributeSpellingListIndex()));
800226633Sdim}
801226633Sdim
802263508Sdimstatic void handleAssertSharedLockAttr(Sema &S, Decl *D,
803263508Sdim                                       const AttributeList &Attr) {
804263508Sdim  SmallVector<Expr*, 1> Args;
805263508Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
806263508Sdim    return;
807263508Sdim
808263508Sdim  unsigned Size = Args.size();
809263508Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
810263508Sdim  D->addAttr(::new (S.Context)
811263508Sdim             AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size,
812263508Sdim                                  Attr.getAttributeSpellingListIndex()));
813263508Sdim}
814263508Sdim
815263508Sdimstatic void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
816263508Sdim                                          const AttributeList &Attr) {
817263508Sdim  SmallVector<Expr*, 1> Args;
818263508Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
819263508Sdim    return;
820263508Sdim
821263508Sdim  unsigned Size = Args.size();
822263508Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
823263508Sdim  D->addAttr(::new (S.Context)
824263508Sdim             AssertExclusiveLockAttr(Attr.getRange(), S.Context,
825263508Sdim                                     StartArg, Size,
826263508Sdim                                     Attr.getAttributeSpellingListIndex()));
827263508Sdim}
828263508Sdim
829263508Sdim
830239462Sdimstatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
831239462Sdim                                      const AttributeList &Attr,
832263508Sdim                                      SmallVectorImpl<Expr *> &Args) {
833226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
834239462Sdim    return false;
835226633Sdim
836226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
837239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
838239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
839239462Sdim    return false;
840226633Sdim  }
841226633Sdim
842263508Sdim  if (!isIntOrBool(Attr.getArgAsExpr(0))) {
843263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
844263508Sdim      << Attr.getName() << 1 << AANT_ArgumentIntOrBool;
845239462Sdim    return false;
846226633Sdim  }
847226633Sdim
848239462Sdim  // check that all arguments are lockable objects
849239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
850239462Sdim
851239462Sdim  return true;
852239462Sdim}
853239462Sdim
854239462Sdimstatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
855239462Sdim                                            const AttributeList &Attr) {
856226633Sdim  SmallVector<Expr*, 2> Args;
857239462Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
858226633Sdim    return;
859226633Sdim
860249423Sdim  D->addAttr(::new (S.Context)
861249423Sdim             SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
862263508Sdim                                       Attr.getArgAsExpr(0),
863263508Sdim                                       Args.data(), Args.size(),
864249423Sdim                                       Attr.getAttributeSpellingListIndex()));
865239462Sdim}
866226633Sdim
867239462Sdimstatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
868239462Sdim                                               const AttributeList &Attr) {
869239462Sdim  SmallVector<Expr*, 2> Args;
870239462Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
871239462Sdim    return;
872239462Sdim
873249423Sdim  D->addAttr(::new (S.Context)
874249423Sdim             ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
875263508Sdim                                          Attr.getArgAsExpr(0),
876263508Sdim                                          Args.data(), Args.size(),
877249423Sdim                                          Attr.getAttributeSpellingListIndex()));
878226633Sdim}
879226633Sdim
880239462Sdimstatic bool checkLocksRequiredCommon(Sema &S, Decl *D,
881239462Sdim                                     const AttributeList &Attr,
882263508Sdim                                     SmallVectorImpl<Expr *> &Args) {
883226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
884239462Sdim    return false;
885226633Sdim
886226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
887239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
888239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
889239462Sdim    return false;
890226633Sdim  }
891226633Sdim
892226633Sdim  // check that all arguments are lockable objects
893239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
894251662Sdim  if (Args.empty())
895239462Sdim    return false;
896239462Sdim
897239462Sdim  return true;
898239462Sdim}
899239462Sdim
900239462Sdimstatic void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
901239462Sdim                                             const AttributeList &Attr) {
902226633Sdim  SmallVector<Expr*, 1> Args;
903239462Sdim  if (!checkLocksRequiredCommon(S, D, Attr, Args))
904226633Sdim    return;
905226633Sdim
906239462Sdim  Expr **StartArg = &Args[0];
907249423Sdim  D->addAttr(::new (S.Context)
908249423Sdim             ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context,
909249423Sdim                                        StartArg, Args.size(),
910249423Sdim                                        Attr.getAttributeSpellingListIndex()));
911239462Sdim}
912226633Sdim
913239462Sdimstatic void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
914239462Sdim                                          const AttributeList &Attr) {
915239462Sdim  SmallVector<Expr*, 1> Args;
916239462Sdim  if (!checkLocksRequiredCommon(S, D, Attr, Args))
917239462Sdim    return;
918239462Sdim
919239462Sdim  Expr **StartArg = &Args[0];
920249423Sdim  D->addAttr(::new (S.Context)
921249423Sdim             SharedLocksRequiredAttr(Attr.getRange(), S.Context,
922249423Sdim                                     StartArg, Args.size(),
923249423Sdim                                     Attr.getAttributeSpellingListIndex()));
924226633Sdim}
925226633Sdim
926226633Sdimstatic void handleUnlockFunAttr(Sema &S, Decl *D,
927226633Sdim                                const AttributeList &Attr) {
928226633Sdim  // zero or more arguments ok
929226633Sdim
930226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
931239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
932239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
933226633Sdim    return;
934226633Sdim  }
935226633Sdim
936226633Sdim  // check that all arguments are lockable objects
937226633Sdim  SmallVector<Expr*, 1> Args;
938239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
939226633Sdim  unsigned Size = Args.size();
940226633Sdim  Expr **StartArg = Size == 0 ? 0 : &Args[0];
941226633Sdim
942249423Sdim  D->addAttr(::new (S.Context)
943249423Sdim             UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
944249423Sdim                                Attr.getAttributeSpellingListIndex()));
945226633Sdim}
946226633Sdim
947226633Sdimstatic void handleLockReturnedAttr(Sema &S, Decl *D,
948226633Sdim                                   const AttributeList &Attr) {
949226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
950239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
951239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
952226633Sdim    return;
953226633Sdim  }
954226633Sdim
955226633Sdim  // check that the argument is lockable object
956239462Sdim  SmallVector<Expr*, 1> Args;
957239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
958239462Sdim  unsigned Size = Args.size();
959239462Sdim  if (Size == 0)
960239462Sdim    return;
961226633Sdim
962249423Sdim  D->addAttr(::new (S.Context)
963249423Sdim             LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
964249423Sdim                              Attr.getAttributeSpellingListIndex()));
965226633Sdim}
966226633Sdim
967226633Sdimstatic void handleLocksExcludedAttr(Sema &S, Decl *D,
968226633Sdim                                    const AttributeList &Attr) {
969226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
970226633Sdim    return;
971226633Sdim
972226633Sdim  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
973239462Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
974239462Sdim      << Attr.getName() << ThreadExpectedFunctionOrMethod;
975226633Sdim    return;
976226633Sdim  }
977226633Sdim
978226633Sdim  // check that all arguments are lockable objects
979226633Sdim  SmallVector<Expr*, 1> Args;
980239462Sdim  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
981239462Sdim  unsigned Size = Args.size();
982239462Sdim  if (Size == 0)
983226633Sdim    return;
984239462Sdim  Expr **StartArg = &Args[0];
985226633Sdim
986249423Sdim  D->addAttr(::new (S.Context)
987249423Sdim             LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
988249423Sdim                               Attr.getAttributeSpellingListIndex()));
989226633Sdim}
990226633Sdim
991263508Sdimstatic void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
992263508Sdim  ConsumableAttr::ConsumedState DefaultState;
993226633Sdim
994263508Sdim  if (Attr.isArgIdent(0)) {
995263508Sdim    IdentifierLoc *IL = Attr.getArgAsIdent(0);
996263508Sdim    if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
997263508Sdim                                                   DefaultState)) {
998263508Sdim      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
999263508Sdim        << Attr.getName() << IL->Ident;
1000263508Sdim      return;
1001263508Sdim    }
1002263508Sdim  } else {
1003263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
1004263508Sdim        << Attr.getName() << AANT_ArgumentIdentifier;
1005263508Sdim    return;
1006263508Sdim  }
1007263508Sdim
1008263508Sdim  if (!isa<CXXRecordDecl>(D)) {
1009263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1010263508Sdim      Attr.getName() << ExpectedClass;
1011263508Sdim    return;
1012263508Sdim  }
1013263508Sdim
1014263508Sdim  D->addAttr(::new (S.Context)
1015263508Sdim             ConsumableAttr(Attr.getRange(), S.Context, DefaultState,
1016263508Sdim                            Attr.getAttributeSpellingListIndex()));
1017263508Sdim}
1018263508Sdim
1019263508Sdimstatic bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1020263508Sdim                                        const AttributeList &Attr) {
1021263508Sdim  ASTContext &CurrContext = S.getASTContext();
1022263508Sdim  QualType ThisType = MD->getThisType(CurrContext)->getPointeeType();
1023263508Sdim
1024263508Sdim  if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1025263508Sdim    if (!RD->hasAttr<ConsumableAttr>()) {
1026263508Sdim      S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) <<
1027263508Sdim        RD->getNameAsString();
1028263508Sdim
1029263508Sdim      return false;
1030263508Sdim    }
1031263508Sdim  }
1032263508Sdim
1033263508Sdim  return true;
1034263508Sdim}
1035263508Sdim
1036263508Sdim
1037263508Sdimstatic void handleCallableWhenAttr(Sema &S, Decl *D,
1038263508Sdim                                   const AttributeList &Attr) {
1039263508Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1040263508Sdim    return;
1041263508Sdim
1042263508Sdim  if (!isa<CXXMethodDecl>(D)) {
1043263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1044263508Sdim      Attr.getName() << ExpectedMethod;
1045263508Sdim    return;
1046263508Sdim  }
1047263508Sdim
1048263508Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1049263508Sdim    return;
1050263508Sdim
1051263508Sdim  SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1052263508Sdim  for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) {
1053263508Sdim    CallableWhenAttr::ConsumedState CallableState;
1054263508Sdim
1055263508Sdim    StringRef StateString;
1056263508Sdim    SourceLocation Loc;
1057263508Sdim    if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc))
1058263508Sdim      return;
1059263508Sdim
1060263508Sdim    if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1061263508Sdim                                                     CallableState)) {
1062263508Sdim      S.Diag(Loc, diag::warn_attribute_type_not_supported)
1063263508Sdim        << Attr.getName() << StateString;
1064263508Sdim      return;
1065263508Sdim    }
1066263508Sdim
1067263508Sdim    States.push_back(CallableState);
1068263508Sdim  }
1069263508Sdim
1070263508Sdim  D->addAttr(::new (S.Context)
1071263508Sdim             CallableWhenAttr(Attr.getRange(), S.Context, States.data(),
1072263508Sdim               States.size(), Attr.getAttributeSpellingListIndex()));
1073263508Sdim}
1074263508Sdim
1075263508Sdim
1076263508Sdimstatic void handleParamTypestateAttr(Sema &S, Decl *D,
1077263508Sdim                                    const AttributeList &Attr) {
1078263508Sdim  if (!checkAttributeNumArgs(S, Attr, 1)) return;
1079263508Sdim
1080263508Sdim  if (!isa<ParmVarDecl>(D)) {
1081263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1082263508Sdim      Attr.getName() << ExpectedParameter;
1083263508Sdim    return;
1084263508Sdim  }
1085263508Sdim
1086263508Sdim  ParamTypestateAttr::ConsumedState ParamState;
1087263508Sdim
1088263508Sdim  if (Attr.isArgIdent(0)) {
1089263508Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1090263508Sdim    StringRef StateString = Ident->Ident->getName();
1091263508Sdim
1092263508Sdim    if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1093263508Sdim                                                       ParamState)) {
1094263508Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1095263508Sdim        << Attr.getName() << StateString;
1096263508Sdim      return;
1097263508Sdim    }
1098263508Sdim  } else {
1099263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1100263508Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1101263508Sdim    return;
1102263508Sdim  }
1103263508Sdim
1104263508Sdim  // FIXME: This check is currently being done in the analysis.  It can be
1105263508Sdim  //        enabled here only after the parser propagates attributes at
1106263508Sdim  //        template specialization definition, not declaration.
1107263508Sdim  //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1108263508Sdim  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1109263508Sdim  //
1110263508Sdim  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1111263508Sdim  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1112263508Sdim  //      ReturnType.getAsString();
1113263508Sdim  //    return;
1114263508Sdim  //}
1115263508Sdim
1116263508Sdim  D->addAttr(::new (S.Context)
1117263508Sdim             ParamTypestateAttr(Attr.getRange(), S.Context, ParamState,
1118263508Sdim                                Attr.getAttributeSpellingListIndex()));
1119263508Sdim}
1120263508Sdim
1121263508Sdim
1122263508Sdimstatic void handleReturnTypestateAttr(Sema &S, Decl *D,
1123263508Sdim                                      const AttributeList &Attr) {
1124263508Sdim  if (!checkAttributeNumArgs(S, Attr, 1)) return;
1125263508Sdim
1126263508Sdim  if (!(isa<FunctionDecl>(D) || isa<ParmVarDecl>(D))) {
1127263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1128263508Sdim      Attr.getName() << ExpectedFunctionMethodOrParameter;
1129263508Sdim    return;
1130263508Sdim  }
1131263508Sdim
1132263508Sdim  ReturnTypestateAttr::ConsumedState ReturnState;
1133263508Sdim
1134263508Sdim  if (Attr.isArgIdent(0)) {
1135263508Sdim    IdentifierLoc *IL = Attr.getArgAsIdent(0);
1136263508Sdim    if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1137263508Sdim                                                        ReturnState)) {
1138263508Sdim      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
1139263508Sdim        << Attr.getName() << IL->Ident;
1140263508Sdim      return;
1141263508Sdim    }
1142263508Sdim  } else {
1143263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1144263508Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1145263508Sdim    return;
1146263508Sdim  }
1147263508Sdim
1148263508Sdim  // FIXME: This check is currently being done in the analysis.  It can be
1149263508Sdim  //        enabled here only after the parser propagates attributes at
1150263508Sdim  //        template specialization definition, not declaration.
1151263508Sdim  //QualType ReturnType;
1152263508Sdim  //
1153263508Sdim  //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1154263508Sdim  //  ReturnType = Param->getType();
1155263508Sdim  //
1156263508Sdim  //} else if (const CXXConstructorDecl *Constructor =
1157263508Sdim  //             dyn_cast<CXXConstructorDecl>(D)) {
1158263508Sdim  //  ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType();
1159263508Sdim  //
1160263508Sdim  //} else {
1161263508Sdim  //
1162263508Sdim  //  ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1163263508Sdim  //}
1164263508Sdim  //
1165263508Sdim  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1166263508Sdim  //
1167263508Sdim  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1168263508Sdim  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1169263508Sdim  //      ReturnType.getAsString();
1170263508Sdim  //    return;
1171263508Sdim  //}
1172263508Sdim
1173263508Sdim  D->addAttr(::new (S.Context)
1174263508Sdim             ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState,
1175263508Sdim                                 Attr.getAttributeSpellingListIndex()));
1176263508Sdim}
1177263508Sdim
1178263508Sdim
1179263508Sdimstatic void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1180263508Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
1181263508Sdim    return;
1182263508Sdim
1183263508Sdim  if (!isa<CXXMethodDecl>(D)) {
1184263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1185263508Sdim      Attr.getName() << ExpectedMethod;
1186263508Sdim    return;
1187263508Sdim  }
1188263508Sdim
1189263508Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1190263508Sdim    return;
1191263508Sdim
1192263508Sdim  SetTypestateAttr::ConsumedState NewState;
1193263508Sdim  if (Attr.isArgIdent(0)) {
1194263508Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1195263508Sdim    StringRef Param = Ident->Ident->getName();
1196263508Sdim    if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1197263508Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1198263508Sdim        << Attr.getName() << Param;
1199263508Sdim      return;
1200263508Sdim    }
1201263508Sdim  } else {
1202263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1203263508Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1204263508Sdim    return;
1205263508Sdim  }
1206263508Sdim
1207263508Sdim  D->addAttr(::new (S.Context)
1208263508Sdim             SetTypestateAttr(Attr.getRange(), S.Context, NewState,
1209263508Sdim                              Attr.getAttributeSpellingListIndex()));
1210263508Sdim}
1211263508Sdim
1212263508Sdimstatic void handleTestTypestateAttr(Sema &S, Decl *D,
1213263508Sdim                                    const AttributeList &Attr) {
1214263508Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
1215263508Sdim    return;
1216263508Sdim
1217263508Sdim  if (!isa<CXXMethodDecl>(D)) {
1218263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
1219263508Sdim      Attr.getName() << ExpectedMethod;
1220263508Sdim    return;
1221263508Sdim  }
1222263508Sdim
1223263508Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1224263508Sdim    return;
1225263508Sdim
1226263508Sdim  TestTypestateAttr::ConsumedState TestState;
1227263508Sdim  if (Attr.isArgIdent(0)) {
1228263508Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1229263508Sdim    StringRef Param = Ident->Ident->getName();
1230263508Sdim    if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1231263508Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1232263508Sdim        << Attr.getName() << Param;
1233263508Sdim      return;
1234263508Sdim    }
1235263508Sdim  } else {
1236263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1237263508Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1238263508Sdim    return;
1239263508Sdim  }
1240263508Sdim
1241263508Sdim  D->addAttr(::new (S.Context)
1242263508Sdim             TestTypestateAttr(Attr.getRange(), S.Context, TestState,
1243263508Sdim                                Attr.getAttributeSpellingListIndex()));
1244263508Sdim}
1245263508Sdim
1246224145Sdimstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
1247224145Sdim                                    const AttributeList &Attr) {
1248249423Sdim  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
1249249423Sdim  if (TD == 0) {
1250249423Sdim    // __attribute__((ext_vector_type(N))) can only be applied to typedefs
1251249423Sdim    // and type-ids.
1252193326Sed    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
1253193326Sed    return;
1254193326Sed  }
1255198092Srdivacky
1256249423Sdim  // Remember this typedef decl, we will need it later for diagnostics.
1257249423Sdim  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))
1262226633Sdim    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.
1266243830Sdim    if (!FD->getType()->isDependentType() &&
1267243830Sdim        !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
1272249423Sdim      FD->addAttr(::new (S.Context)
1273249423Sdim                  PackedAttr(Attr.getRange(), S.Context,
1274249423Sdim                             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) {
1280243830Sdim  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
1281249423Sdim    RD->addAttr(::new (S.Context)
1282249423Sdim                MsStructAttr(Attr.getRange(), S.Context,
1283249423Sdim                             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()) {
1292249423Sdim      D->addAttr(::new (S.Context)
1293249423Sdim                 IBActionAttr(Attr.getRange(), S.Context,
1294249423Sdim                              Attr.getAttributeSpellingListIndex()));
1295204643Srdivacky      return;
1296204643Srdivacky    }
1297204643Srdivacky
1298218893Sdim  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
1299204643Srdivacky}
1300204643Srdivacky
1301226633Sdimstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
1302226633Sdim  // The IBOutlet/IBOutletCollection attributes only apply to instance
1303226633Sdim  // variables or properties of Objective-C classes.  The outlet must also
1304226633Sdim  // have an object reference type.
1305226633Sdim  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
1306226633Sdim    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1307234353Sdim      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
1308226633Sdim        << Attr.getName() << VD->getType() << 0;
1309226633Sdim      return false;
1310226633Sdim    }
1311226633Sdim  }
1312226633Sdim  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1313226633Sdim    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1314234353Sdim      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
1315226633Sdim        << Attr.getName() << PD->getType() << 1;
1316226633Sdim      return false;
1317226633Sdim    }
1318226633Sdim  }
1319226633Sdim  else {
1320226633Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
1321226633Sdim    return false;
1322226633Sdim  }
1323234353Sdim
1324226633Sdim  return true;
1325226633Sdim}
1326226633Sdim
1327224145Sdimstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
1328226633Sdim  if (!checkIBOutletCommon(S, D, Attr))
1329204643Srdivacky    return;
1330204643Srdivacky
1331249423Sdim  D->addAttr(::new (S.Context)
1332249423Sdim             IBOutletAttr(Attr.getRange(), S.Context,
1333249423Sdim                          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.
1340263508Sdim  if (Attr.getNumArgs() > 1) {
1341263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1342263508Sdim      << Attr.getName() << 1;
1343208600Srdivacky    return;
1344208600Srdivacky  }
1345208600Srdivacky
1346226633Sdim  if (!checkIBOutletCommon(S, D, Attr))
1347208600Srdivacky    return;
1348226633Sdim
1349263508Sdim  ParsedType PT;
1350263508Sdim
1351263508Sdim  if (Attr.hasParsedType())
1352263508Sdim    PT = Attr.getTypeArg();
1353263508Sdim  else {
1354263508Sdim    PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(),
1355263508Sdim                       S.getScopeForContext(D->getDeclContext()->getParent()));
1356263508Sdim    if (!PT) {
1357263508Sdim      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1358263508Sdim      return;
1359263508Sdim    }
1360212904Sdim  }
1361263508Sdim
1362263508Sdim  TypeSourceInfo *QTLoc = 0;
1363263508Sdim  QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1364263508Sdim  if (!QTLoc)
1365263508Sdim    QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
1366263508Sdim
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())).
1371234353Sdim  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1372263508Sdim    S.Diag(Attr.getLoc(),
1373263508Sdim           QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1374263508Sdim                               : diag::err_iboutletcollection_type) << QT;
1375212904Sdim    return;
1376212904Sdim  }
1377263508Sdim
1378249423Sdim  D->addAttr(::new (S.Context)
1379263508Sdim             IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc,
1380249423Sdim                                    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
1398239462Sdimstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1399239462Sdim  if (!isFunctionOrMethod(D)) {
1400239462Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1401263508Sdim    << Attr.getName() << ExpectedFunctionOrMethod;
1402239462Sdim    return;
1403239462Sdim  }
1404239462Sdim
1405239462Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
1406239462Sdim    return;
1407239462Sdim
1408239462Sdim  SmallVector<unsigned, 8> SizeArgs;
1409263508Sdim  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
1410263508Sdim    Expr *Ex = Attr.getArgAsExpr(i);
1411263508Sdim    uint64_t Idx;
1412263508Sdim    if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
1413263508Sdim                                            Attr.getLoc(), i + 1, Ex, Idx))
1414239462Sdim      return;
1415239462Sdim
1416239462Sdim    // check if the function argument is of an integer type
1417263508Sdim    QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType();
1418239462Sdim    if (!T->isIntegerType()) {
1419263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
1420263508Sdim        << Attr.getName() << AANT_ArgumentIntegerConstant
1421263508Sdim        << Ex->getSourceRange();
1422239462Sdim      return;
1423239462Sdim    }
1424263508Sdim    SizeArgs.push_back(Idx);
1425239462Sdim  }
1426239462Sdim
1427239462Sdim  // check if the function returns a pointer
1428239462Sdim  if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
1429239462Sdim    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
1430263508Sdim    << Attr.getName() << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
1431239462Sdim  }
1432239462Sdim
1433249423Sdim  D->addAttr(::new (S.Context)
1434249423Sdim             AllocSizeAttr(Attr.getRange(), S.Context,
1435249423Sdim                           SizeArgs.data(), SizeArgs.size(),
1436249423Sdim                           Attr.getAttributeSpellingListIndex()));
1437239462Sdim}
1438239462Sdim
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
1448263508Sdim  SmallVector<unsigned, 8> NonNullArgs;
1449263508Sdim  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
1450263508Sdim    Expr *Ex = Attr.getArgAsExpr(i);
1451263508Sdim    uint64_t Idx;
1452263508Sdim    if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
1453263508Sdim                                            Attr.getLoc(), i + 1, Ex, Idx))
1454193326Sed      return;
1455198092Srdivacky
1456193326Sed    // Is the function argument a pointer type?
1457263508Sdim    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
1467263508Sdim    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()) {
1473249423Sdim    for (unsigned i = 0, e = getFunctionOrMethodNumArgs(D); i != e; ++i) {
1474249423Sdim      QualType T = getFunctionOrMethodArgType(D, i).getNonReferenceType();
1475224145Sdim      possibleTransparentUnionPointerType(T);
1476198092Srdivacky      if (T->isAnyPointerType() || T->isBlockPointerType())
1477249423Sdim        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
1490249423Sdim  unsigned *start = &NonNullArgs[0];
1491193326Sed  unsigned size = NonNullArgs.size();
1492212904Sdim  llvm::array_pod_sort(start, start + size);
1493249423Sdim  D->addAttr(::new (S.Context)
1494249423Sdim             NonNullAttr(Attr.getRange(), S.Context, start, size,
1495249423Sdim                         Attr.getAttributeSpellingListIndex()));
1496193326Sed}
1497193326Sed
1498263508Sdimstatic const char *ownershipKindToDiagName(OwnershipAttr::OwnershipKind K) {
1499263508Sdim  switch (K) {
1500263508Sdim    case OwnershipAttr::Holds:    return "'ownership_holds'";
1501263508Sdim    case OwnershipAttr::Takes:    return "'ownership_takes'";
1502263508Sdim    case OwnershipAttr::Returns:  return "'ownership_returns'";
1503263508Sdim  }
1504263508Sdim  llvm_unreachable("unknown ownership");
1505263508Sdim}
1506263508Sdim
1507224145Sdimstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1508263508Sdim  // This attribute must be applied to a function declaration. The first
1509263508Sdim  // argument to the attribute must be an identifier, the name of the resource,
1510263508Sdim  // for example: malloc. The following arguments must be argument indexes, the
1511263508Sdim  // 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
1513263508Sdim  // after being held. free() should be __attribute((ownership_takes)), whereas
1514212904Sdim  // a list append function may well be __attribute((ownership_holds)).
1515212904Sdim
1516263508Sdim  if (!AL.isArgIdent(0)) {
1517263508Sdim    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1518263508Sdim      << AL.getName() << 1 << AANT_ArgumentIdentifier;
1519212904Sdim    return;
1520212904Sdim  }
1521263508Sdim
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;
1527263508Sdim    if (AL.getNumArgs() < 2) {
1528263508Sdim      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;
1534263508Sdim    if (AL.getNumArgs() < 2) {
1535263508Sdim      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;
1541263508Sdim
1542263508Sdim    if (AL.getNumArgs() > 2) {
1543263508Sdim      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
1558263508Sdim  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
1564263508Sdim  SmallVector<unsigned, 8> OwnershipArgs;
1565263508Sdim  for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1566263508Sdim    Expr *Ex = AL.getArgAsExpr(i);
1567263508Sdim    uint64_t Idx;
1568263508Sdim    if (!checkFunctionOrMethodArgumentIndex(S, D, AL.getName()->getName(),
1569263508Sdim                                            AL.getLoc(), i, Ex, Idx))
1570263508Sdim      return;
1571212904Sdim
1572263508Sdim    // Is the function argument a pointer type?
1573263508Sdim    QualType T = getFunctionOrMethodArgType(D, Idx);
1574263508Sdim    int Err = -1;  // No error
1575212904Sdim    switch (K) {
1576263508Sdim      case OwnershipAttr::Takes:
1577263508Sdim      case OwnershipAttr::Holds:
1578263508Sdim        if (!T->isAnyPointerType() && !T->isBlockPointerType())
1579263508Sdim          Err = 0;
1580263508Sdim        break;
1581263508Sdim      case OwnershipAttr::Returns:
1582263508Sdim        if (!T->isIntegerType())
1583263508Sdim          Err = 1;
1584263508Sdim        break;
1585212904Sdim    }
1586263508Sdim    if (-1 != Err) {
1587263508Sdim      S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err
1588263508Sdim        << Ex->getSourceRange();
1589263508Sdim      return;
1590212904Sdim    }
1591212904Sdim
1592212904Sdim    // Check we don't have a conflict with another ownership attribute.
1593212904Sdim    for (specific_attr_iterator<OwnershipAttr>
1594263508Sdim         i = D->specific_attr_begin<OwnershipAttr>(),
1595263508Sdim         e = D->specific_attr_end<OwnershipAttr>(); i != e; ++i) {
1596263508Sdim      if ((*i)->getOwnKind() != K && (*i)->args_end() !=
1597263508Sdim          std::find((*i)->args_begin(), (*i)->args_end(), Idx)) {
1598263508Sdim        S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1599263508Sdim          << AL.getName() << ownershipKindToDiagName((*i)->getOwnKind());
1600263508Sdim        return;
1601212904Sdim      }
1602212904Sdim    }
1603263508Sdim    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
1610249423Sdim  D->addAttr(::new (S.Context)
1611249423Sdim             OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size,
1612249423Sdim                           AL.getAttributeSpellingListIndex()));
1613212904Sdim}
1614212904Sdim
1615224145Sdimstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1616204643Srdivacky  // Check the attribute arguments.
1617204643Srdivacky  if (Attr.getNumArgs() > 1) {
1618263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1619263508Sdim      << 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
1670263508Sdim  // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1671263508Sdim  // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
1672263508Sdim  // StringRef parameter it was given anyway.
1673263508Sdim  StringRef Str;
1674263508Sdim  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?
1677263508Sdim    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1678263508Sdim                                        Attr.getAttributeSpellingListIndex()));
1679204643Srdivacky
1680249423Sdim  D->addAttr(::new (S.Context)
1681249423Sdim             WeakRefAttr(Attr.getRange(), S.Context,
1682249423Sdim                         Attr.getAttributeSpellingListIndex()));
1683204643Srdivacky}
1684204643Srdivacky
1685224145Sdimstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1686263508Sdim  StringRef Str;
1687263508Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
1688193326Sed    return;
1689198092Srdivacky
1690226633Sdim  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
1697263508Sdim  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1698249423Sdim                                         Attr.getAttributeSpellingListIndex()));
1699193326Sed}
1700193326Sed
1701243830Sdimstatic void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1702243830Sdim  if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
1703243830Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1704243830Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
1705243830Sdim    return;
1706243830Sdim  }
1707243830Sdim
1708249423Sdim  D->addAttr(::new (S.Context)
1709249423Sdim             MinSizeAttr(Attr.getRange(), S.Context,
1710249423Sdim                         Attr.getAttributeSpellingListIndex()));
1711243830Sdim}
1712243830Sdim
1713239462Sdimstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1714239462Sdim  if (!isa<FunctionDecl>(D)) {
1715239462Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1716239462Sdim      << Attr.getName() << ExpectedFunction;
1717239462Sdim    return;
1718239462Sdim  }
1719239462Sdim
1720239462Sdim  if (D->hasAttr<HotAttr>()) {
1721239462Sdim    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1722239462Sdim      << Attr.getName() << "hot";
1723239462Sdim    return;
1724239462Sdim  }
1725239462Sdim
1726249423Sdim  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
1727249423Sdim                                        Attr.getAttributeSpellingListIndex()));
1728239462Sdim}
1729239462Sdim
1730239462Sdimstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1731239462Sdim  if (!isa<FunctionDecl>(D)) {
1732239462Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1733239462Sdim      << Attr.getName() << ExpectedFunction;
1734239462Sdim    return;
1735239462Sdim  }
1736239462Sdim
1737239462Sdim  if (D->hasAttr<ColdAttr>()) {
1738239462Sdim    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
1739239462Sdim      << Attr.getName() << "cold";
1740239462Sdim    return;
1741239462Sdim  }
1742239462Sdim
1743249423Sdim  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
1744249423Sdim                                       Attr.getAttributeSpellingListIndex()));
1745239462Sdim}
1746239462Sdim
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
1754249423Sdim  D->addAttr(::new (S.Context)
1755249423Sdim             NakedAttr(Attr.getRange(), S.Context,
1756249423Sdim                       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
1767249423Sdim  D->addAttr(::new (S.Context)
1768249423Sdim             AlwaysInlineAttr(Attr.getRange(), S.Context,
1769249423Sdim                              Attr.getAttributeSpellingListIndex()));
1770193326Sed}
1771193326Sed
1772239462Sdimstatic void handleTLSModelAttr(Sema &S, Decl *D,
1773239462Sdim                               const AttributeList &Attr) {
1774263508Sdim  StringRef Model;
1775263508Sdim  SourceLocation LiteralLoc;
1776239462Sdim  // Check that it is a string.
1777263508Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc))
1778239462Sdim    return;
1779239462Sdim
1780251662Sdim  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) {
1781239462Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1782239462Sdim      << Attr.getName() << ExpectedTLSVar;
1783239462Sdim    return;
1784239462Sdim  }
1785239462Sdim
1786239462Sdim  // Check that the value.
1787239462Sdim  if (Model != "global-dynamic" && Model != "local-dynamic"
1788239462Sdim      && Model != "initial-exec" && Model != "local-exec") {
1789263508Sdim    S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
1790239462Sdim    return;
1791239462Sdim  }
1792239462Sdim
1793249423Sdim  D->addAttr(::new (S.Context)
1794249423Sdim             TLSModelAttr(Attr.getRange(), S.Context, Model,
1795249423Sdim                          Attr.getAttributeSpellingListIndex()));
1796239462Sdim}
1797239462Sdim
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()) {
1802249423Sdim      D->addAttr(::new (S.Context)
1803249423Sdim                 MallocAttr(Attr.getRange(), S.Context,
1804249423Sdim                            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) {
1813249423Sdim  D->addAttr(::new (S.Context)
1814249423Sdim             MayAliasAttr(Attr.getRange(), S.Context,
1815249423Sdim                          Attr.getAttributeSpellingListIndex()));
1816218893Sdim}
1817218893Sdim
1818224145Sdimstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1819224145Sdim  if (isa<VarDecl>(D))
1820249423Sdim    D->addAttr(::new (S.Context)
1821249423Sdim               NoCommonAttr(Attr.getRange(), S.Context,
1822249423Sdim                            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) {
1829263508Sdim  if (S.LangOpts.CPlusPlus) {
1830263508Sdim    S.Diag(Attr.getLoc(), diag::err_common_not_supported_cplusplus);
1831263508Sdim    return;
1832263508Sdim  }
1833263508Sdim
1834224145Sdim  if (isa<VarDecl>(D))
1835249423Sdim    D->addAttr(::new (S.Context)
1836249423Sdim               CommonAttr(Attr.getRange(), S.Context,
1837249423Sdim                          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
1854249423Sdim  D->addAttr(::new (S.Context)
1855249423Sdim             NoReturnAttr(attr.getRange(), S.Context,
1856249423Sdim                          attr.getAttributeSpellingListIndex()));
1857218893Sdim}
1858218893Sdim
1859218893Sdimbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1860263508Sdim  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(),
1878249423Sdim             Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
1879212904Sdim             : diag::warn_attribute_wrong_decl_type)
1880221345Sdim        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1881212904Sdim      return;
1882193326Sed    }
1883193326Sed  }
1884212904Sdim
1885249423Sdim  D->addAttr(::new (S.Context)
1886249423Sdim             AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
1887249423Sdim                                  Attr.getAttributeSpellingListIndex()));
1888193326Sed}
1889193326Sed
1890249423Sdimstatic void handleCXX11NoReturnAttr(Sema &S, Decl *D,
1891249423Sdim                                    const AttributeList &Attr) {
1892249423Sdim  // C++11 [dcl.attr.noreturn]p1:
1893249423Sdim  //   The attribute may be applied to the declarator-id in a function
1894249423Sdim  //   declaration.
1895249423Sdim  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
1896249423Sdim  if (!FD) {
1897249423Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1898249423Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
1899249423Sdim    return;
1900249423Sdim  }
1901249423Sdim
1902249423Sdim  D->addAttr(::new (S.Context)
1903249423Sdim             CXX11NoReturnAttr(Attr.getRange(), S.Context,
1904249423Sdim                               Attr.getAttributeSpellingListIndex()));
1905249423Sdim}
1906249423Sdim
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
1965249423Sdim  D->addAttr(::new (S.Context)
1966249423Sdim             VecReturnAttr(Attr.getRange(), S.Context,
1967249423Sdim                           Attr.getAttributeSpellingListIndex()));
1968193326Sed}
1969193326Sed
1970249423Sdimstatic void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
1971249423Sdim                                 const AttributeList &Attr) {
1972249423Sdim  if (isa<ParmVarDecl>(D)) {
1973249423Sdim    // [[carries_dependency]] can only be applied to a parameter if it is a
1974249423Sdim    // parameter of a function declaration or lambda.
1975249423Sdim    if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
1976249423Sdim      S.Diag(Attr.getLoc(),
1977249423Sdim             diag::err_carries_dependency_param_not_function_decl);
1978249423Sdim      return;
1979249423Sdim    }
1980249423Sdim  } else if (!isa<FunctionDecl>(D)) {
1981199990Srdivacky    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
1982221345Sdim      << Attr.getName() << ExpectedFunctionMethodOrParameter;
1983199990Srdivacky    return;
1984199990Srdivacky  }
1985249423Sdim
1986249423Sdim  D->addAttr(::new (S.Context) CarriesDependencyAttr(
1987249423Sdim                                   Attr.getRange(), S.Context,
1988249423Sdim                                   Attr.getAttributeSpellingListIndex()));
1989199990Srdivacky}
1990199990Srdivacky
1991224145Sdimstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1992224145Sdim  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
1993239462Sdim      !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
1999249423Sdim  D->addAttr(::new (S.Context)
2000249423Sdim             UnusedAttr(Attr.getRange(), S.Context,
2001249423Sdim                        Attr.getAttributeSpellingListIndex()));
2002193326Sed}
2003193326Sed
2004226633Sdimstatic void handleReturnsTwiceAttr(Sema &S, Decl *D,
2005226633Sdim                                   const AttributeList &Attr) {
2006226633Sdim  if (!isa<FunctionDecl>(D)) {
2007226633Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2008226633Sdim      << Attr.getName() << ExpectedFunction;
2009226633Sdim    return;
2010226633Sdim  }
2011226633Sdim
2012249423Sdim  D->addAttr(::new (S.Context)
2013249423Sdim             ReturnsTwiceAttr(Attr.getRange(), S.Context,
2014249423Sdim                              Attr.getAttributeSpellingListIndex()));
2015226633Sdim}
2016226633Sdim
2017224145Sdimstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2018224145Sdim  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
2019263508Sdim    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
2029249423Sdim  D->addAttr(::new (S.Context)
2030249423Sdim             UsedAttr(Attr.getRange(), S.Context,
2031249423Sdim                      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) {
2043263508Sdim    Expr *E = Attr.getArgAsExpr(0);
2044193326Sed    llvm::APSInt Idx(32);
2045208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2046208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2047263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2048263508Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2049263508Sdim        << 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
2061249423Sdim  D->addAttr(::new (S.Context)
2062249423Sdim             ConstructorAttr(Attr.getRange(), S.Context, priority,
2063249423Sdim                             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) {
2075263508Sdim    Expr *E = Attr.getArgAsExpr(0);
2076193326Sed    llvm::APSInt Idx(32);
2077208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2078208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2079263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2080263508Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2081263508Sdim        << 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
2093249423Sdim  D->addAttr(::new (S.Context)
2094249423Sdim             DestructorAttr(Attr.getRange(), S.Context, priority,
2095249423Sdim                            Attr.getAttributeSpellingListIndex()));
2096193326Sed}
2097193326Sed
2098239462Sdimtemplate <typename AttrTy>
2099263508Sdimstatic void handleAttrWithMessage(Sema &S, Decl *D,
2100263508Sdim                                  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  }
2106239462Sdim
2107239462Sdim  // Handle the case where the attribute has a text message.
2108226633Sdim  StringRef Str;
2109263508Sdim  if (NumArgs == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str))
2110263508Sdim    return;
2111198092Srdivacky
2112249423Sdim  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
2113249423Sdim                                      Attr.getAttributeSpellingListIndex()));
2114193326Sed}
2115193326Sed
2116224145Sdimstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D,
2117224145Sdim                                            const AttributeList &Attr) {
2118249423Sdim  D->addAttr(::new (S.Context)
2119249423Sdim             ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
2120249423Sdim                                       Attr.getAttributeSpellingListIndex()));
2121224145Sdim}
2122224145Sdim
2123234353Sdimstatic void handleObjCRootClassAttr(Sema &S, Decl *D,
2124234353Sdim                                    const AttributeList &Attr) {
2125234353Sdim  if (!isa<ObjCInterfaceDecl>(D)) {
2126263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2127263508Sdim      << Attr.getName() << ExpectedObjectiveCInterface;
2128234353Sdim    return;
2129234353Sdim  }
2130234353Sdim
2131249423Sdim  D->addAttr(::new (S.Context)
2132249423Sdim             ObjCRootClassAttr(Attr.getRange(), S.Context,
2133249423Sdim                               Attr.getAttributeSpellingListIndex()));
2134234353Sdim}
2135234353Sdim
2136249423Sdimstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
2137249423Sdim                                               const AttributeList &Attr) {
2138234353Sdim  if (!isa<ObjCInterfaceDecl>(D)) {
2139234353Sdim    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
2140234353Sdim    return;
2141234353Sdim  }
2142234353Sdim
2143249423Sdim  D->addAttr(::new (S.Context)
2144249423Sdim             ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
2145249423Sdim                                          Attr.getAttributeSpellingListIndex()));
2146234353Sdim}
2147234353Sdim
2148239462Sdimstatic bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2149239462Sdim                                  IdentifierInfo *Platform,
2150239462Sdim                                  VersionTuple Introduced,
2151239462Sdim                                  VersionTuple Deprecated,
2152239462Sdim                                  VersionTuple Obsoleted) {
2153239462Sdim  StringRef PlatformName
2154239462Sdim    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2155239462Sdim  if (PlatformName.empty())
2156239462Sdim    PlatformName = Platform->getName();
2157239462Sdim
2158239462Sdim  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2159239462Sdim  // of these steps are needed).
2160239462Sdim  if (!Introduced.empty() && !Deprecated.empty() &&
2161239462Sdim      !(Introduced <= Deprecated)) {
2162239462Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2163239462Sdim      << 1 << PlatformName << Deprecated.getAsString()
2164239462Sdim      << 0 << Introduced.getAsString();
2165239462Sdim    return true;
2166239462Sdim  }
2167239462Sdim
2168239462Sdim  if (!Introduced.empty() && !Obsoleted.empty() &&
2169239462Sdim      !(Introduced <= Obsoleted)) {
2170239462Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2171239462Sdim      << 2 << PlatformName << Obsoleted.getAsString()
2172239462Sdim      << 0 << Introduced.getAsString();
2173239462Sdim    return true;
2174239462Sdim  }
2175239462Sdim
2176239462Sdim  if (!Deprecated.empty() && !Obsoleted.empty() &&
2177239462Sdim      !(Deprecated <= Obsoleted)) {
2178239462Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2179239462Sdim      << 2 << PlatformName << Obsoleted.getAsString()
2180239462Sdim      << 1 << Deprecated.getAsString();
2181239462Sdim    return true;
2182239462Sdim  }
2183239462Sdim
2184239462Sdim  return false;
2185239462Sdim}
2186239462Sdim
2187249423Sdim/// \brief Check whether the two versions match.
2188249423Sdim///
2189249423Sdim/// If either version tuple is empty, then they are assumed to match. If
2190249423Sdim/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2191249423Sdimstatic bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2192249423Sdim                          bool BeforeIsOkay) {
2193249423Sdim  if (X.empty() || Y.empty())
2194249423Sdim    return true;
2195249423Sdim
2196249423Sdim  if (X == Y)
2197249423Sdim    return true;
2198249423Sdim
2199249423Sdim  if (BeforeIsOkay && X < Y)
2200249423Sdim    return true;
2201249423Sdim
2202249423Sdim  return false;
2203249423Sdim}
2204249423Sdim
2205249423SdimAvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
2206239462Sdim                                              IdentifierInfo *Platform,
2207239462Sdim                                              VersionTuple Introduced,
2208239462Sdim                                              VersionTuple Deprecated,
2209239462Sdim                                              VersionTuple Obsoleted,
2210239462Sdim                                              bool IsUnavailable,
2211249423Sdim                                              StringRef Message,
2212249423Sdim                                              bool Override,
2213249423Sdim                                              unsigned AttrSpellingListIndex) {
2214239462Sdim  VersionTuple MergedIntroduced = Introduced;
2215239462Sdim  VersionTuple MergedDeprecated = Deprecated;
2216239462Sdim  VersionTuple MergedObsoleted = Obsoleted;
2217239462Sdim  bool FoundAny = false;
2218239462Sdim
2219239462Sdim  if (D->hasAttrs()) {
2220239462Sdim    AttrVec &Attrs = D->getAttrs();
2221239462Sdim    for (unsigned i = 0, e = Attrs.size(); i != e;) {
2222239462Sdim      const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2223239462Sdim      if (!OldAA) {
2224239462Sdim        ++i;
2225239462Sdim        continue;
2226239462Sdim      }
2227239462Sdim
2228239462Sdim      IdentifierInfo *OldPlatform = OldAA->getPlatform();
2229239462Sdim      if (OldPlatform != Platform) {
2230239462Sdim        ++i;
2231239462Sdim        continue;
2232239462Sdim      }
2233239462Sdim
2234239462Sdim      FoundAny = true;
2235239462Sdim      VersionTuple OldIntroduced = OldAA->getIntroduced();
2236239462Sdim      VersionTuple OldDeprecated = OldAA->getDeprecated();
2237239462Sdim      VersionTuple OldObsoleted = OldAA->getObsoleted();
2238239462Sdim      bool OldIsUnavailable = OldAA->getUnavailable();
2239239462Sdim
2240249423Sdim      if (!versionsMatch(OldIntroduced, Introduced, Override) ||
2241249423Sdim          !versionsMatch(Deprecated, OldDeprecated, Override) ||
2242249423Sdim          !versionsMatch(Obsoleted, OldObsoleted, Override) ||
2243249423Sdim          !(OldIsUnavailable == IsUnavailable ||
2244249423Sdim            (Override && !OldIsUnavailable && IsUnavailable))) {
2245249423Sdim        if (Override) {
2246249423Sdim          int Which = -1;
2247249423Sdim          VersionTuple FirstVersion;
2248249423Sdim          VersionTuple SecondVersion;
2249249423Sdim          if (!versionsMatch(OldIntroduced, Introduced, Override)) {
2250249423Sdim            Which = 0;
2251249423Sdim            FirstVersion = OldIntroduced;
2252249423Sdim            SecondVersion = Introduced;
2253249423Sdim          } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) {
2254249423Sdim            Which = 1;
2255249423Sdim            FirstVersion = Deprecated;
2256249423Sdim            SecondVersion = OldDeprecated;
2257249423Sdim          } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) {
2258249423Sdim            Which = 2;
2259249423Sdim            FirstVersion = Obsoleted;
2260249423Sdim            SecondVersion = OldObsoleted;
2261249423Sdim          }
2262249423Sdim
2263249423Sdim          if (Which == -1) {
2264249423Sdim            Diag(OldAA->getLocation(),
2265249423Sdim                 diag::warn_mismatched_availability_override_unavail)
2266249423Sdim              << AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2267249423Sdim          } else {
2268249423Sdim            Diag(OldAA->getLocation(),
2269249423Sdim                 diag::warn_mismatched_availability_override)
2270249423Sdim              << Which
2271249423Sdim              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2272249423Sdim              << FirstVersion.getAsString() << SecondVersion.getAsString();
2273249423Sdim          }
2274249423Sdim          Diag(Range.getBegin(), diag::note_overridden_method);
2275249423Sdim        } else {
2276249423Sdim          Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2277249423Sdim          Diag(Range.getBegin(), diag::note_previous_attribute);
2278249423Sdim        }
2279249423Sdim
2280239462Sdim        Attrs.erase(Attrs.begin() + i);
2281239462Sdim        --e;
2282239462Sdim        continue;
2283239462Sdim      }
2284239462Sdim
2285239462Sdim      VersionTuple MergedIntroduced2 = MergedIntroduced;
2286239462Sdim      VersionTuple MergedDeprecated2 = MergedDeprecated;
2287239462Sdim      VersionTuple MergedObsoleted2 = MergedObsoleted;
2288239462Sdim
2289239462Sdim      if (MergedIntroduced2.empty())
2290239462Sdim        MergedIntroduced2 = OldIntroduced;
2291239462Sdim      if (MergedDeprecated2.empty())
2292239462Sdim        MergedDeprecated2 = OldDeprecated;
2293239462Sdim      if (MergedObsoleted2.empty())
2294239462Sdim        MergedObsoleted2 = OldObsoleted;
2295239462Sdim
2296239462Sdim      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2297239462Sdim                                MergedIntroduced2, MergedDeprecated2,
2298239462Sdim                                MergedObsoleted2)) {
2299239462Sdim        Attrs.erase(Attrs.begin() + i);
2300239462Sdim        --e;
2301239462Sdim        continue;
2302239462Sdim      }
2303239462Sdim
2304239462Sdim      MergedIntroduced = MergedIntroduced2;
2305239462Sdim      MergedDeprecated = MergedDeprecated2;
2306239462Sdim      MergedObsoleted = MergedObsoleted2;
2307239462Sdim      ++i;
2308239462Sdim    }
2309239462Sdim  }
2310239462Sdim
2311239462Sdim  if (FoundAny &&
2312239462Sdim      MergedIntroduced == Introduced &&
2313239462Sdim      MergedDeprecated == Deprecated &&
2314239462Sdim      MergedObsoleted == Obsoleted)
2315239462Sdim    return NULL;
2316239462Sdim
2317251662Sdim  // Only create a new attribute if !Override, but we want to do
2318251662Sdim  // the checking.
2319239462Sdim  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
2320251662Sdim                             MergedDeprecated, MergedObsoleted) &&
2321251662Sdim      !Override) {
2322239462Sdim    return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2323239462Sdim                                            Introduced, Deprecated,
2324249423Sdim                                            Obsoleted, IsUnavailable, Message,
2325249423Sdim                                            AttrSpellingListIndex);
2326239462Sdim  }
2327239462Sdim  return NULL;
2328239462Sdim}
2329239462Sdim
2330224145Sdimstatic void handleAvailabilityAttr(Sema &S, Decl *D,
2331224145Sdim                                   const AttributeList &Attr) {
2332263508Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
2333263508Sdim    return;
2334263508Sdim  IdentifierLoc *Platform = Attr.getArgAsIdent(0);
2335249423Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2336249423Sdim
2337263508Sdim  IdentifierInfo *II = Platform->Ident;
2338263508Sdim  if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2339263508Sdim    S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2340263508Sdim      << Platform->Ident;
2341221345Sdim
2342249423Sdim  NamedDecl *ND = dyn_cast<NamedDecl>(D);
2343249423Sdim  if (!ND) {
2344249423Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2345249423Sdim    return;
2346249423Sdim  }
2347249423Sdim
2348221345Sdim  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
2349221345Sdim  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
2350221345Sdim  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
2351221345Sdim  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
2352234353Sdim  StringRef Str;
2353263508Sdim  if (const StringLiteral *SE =
2354263508Sdim          dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr()))
2355234353Sdim    Str = SE->getString();
2356239462Sdim
2357263508Sdim  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
2358239462Sdim                                                      Introduced.Version,
2359239462Sdim                                                      Deprecated.Version,
2360239462Sdim                                                      Obsoleted.Version,
2361249423Sdim                                                      IsUnavailable, Str,
2362249423Sdim                                                      /*Override=*/false,
2363249423Sdim                                                      Index);
2364239462Sdim  if (NewAttr)
2365239462Sdim    D->addAttr(NewAttr);
2366221345Sdim}
2367221345Sdim
2368249423Sdimtemplate <class T>
2369249423Sdimstatic T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
2370249423Sdim                              typename T::VisibilityType value,
2371249423Sdim                              unsigned attrSpellingListIndex) {
2372249423Sdim  T *existingAttr = D->getAttr<T>();
2373249423Sdim  if (existingAttr) {
2374249423Sdim    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2375249423Sdim    if (existingValue == value)
2376249423Sdim      return NULL;
2377249423Sdim    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2378249423Sdim    S.Diag(range.getBegin(), diag::note_previous_attribute);
2379249423Sdim    D->dropAttr<T>();
2380249423Sdim  }
2381249423Sdim  return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
2382249423Sdim}
2383249423Sdim
2384239462SdimVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
2385249423Sdim                                          VisibilityAttr::VisibilityType Vis,
2386249423Sdim                                          unsigned AttrSpellingListIndex) {
2387249423Sdim  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
2388249423Sdim                                               AttrSpellingListIndex);
2389249423Sdim}
2390249423Sdim
2391249423SdimTypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
2392249423Sdim                                      TypeVisibilityAttr::VisibilityType Vis,
2393249423Sdim                                      unsigned AttrSpellingListIndex) {
2394249423Sdim  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
2395249423Sdim                                                   AttrSpellingListIndex);
2396249423Sdim}
2397249423Sdim
2398249423Sdimstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr,
2399249423Sdim                                 bool isTypeVisibility) {
2400249423Sdim  // Visibility attributes don't mean anything on a typedef.
2401239462Sdim  if (isa<TypedefNameDecl>(D)) {
2402249423Sdim    S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored)
2403249423Sdim      << Attr.getName();
2404249423Sdim    return;
2405239462Sdim  }
2406249423Sdim
2407249423Sdim  // 'type_visibility' can only go on a type or namespace.
2408249423Sdim  if (isTypeVisibility &&
2409249423Sdim      !(isa<TagDecl>(D) ||
2410249423Sdim        isa<ObjCInterfaceDecl>(D) ||
2411249423Sdim        isa<NamespaceDecl>(D))) {
2412249423Sdim    S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2413249423Sdim      << Attr.getName() << ExpectedTypeOrNamespace;
2414249423Sdim    return;
2415239462Sdim  }
2416239462Sdim
2417263508Sdim  // Check that the argument is a string literal.
2418263508Sdim  StringRef TypeStr;
2419263508Sdim  SourceLocation LiteralLoc;
2420263508Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc))
2421193326Sed    return;
2422198092Srdivacky
2423263508Sdim  VisibilityAttr::VisibilityType type;
2424263508Sdim  if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2425263508Sdim    S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
2426263508Sdim      << Attr.getName() << TypeStr;
2427193326Sed    return;
2428193326Sed  }
2429249423Sdim
2430263508Sdim  // Complain about attempts to use protected visibility on targets
2431263508Sdim  // (like Darwin) that don't support it.
2432263508Sdim  if (type == VisibilityAttr::Protected &&
2433263508Sdim      !S.Context.getTargetInfo().hasProtectedVisibility()) {
2434263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
2435212904Sdim    type = VisibilityAttr::Default;
2436193326Sed  }
2437198092Srdivacky
2438249423Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2439249423Sdim  clang::Attr *newAttr;
2440249423Sdim  if (isTypeVisibility) {
2441249423Sdim    newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(),
2442249423Sdim                                    (TypeVisibilityAttr::VisibilityType) type,
2443249423Sdim                                        Index);
2444249423Sdim  } else {
2445249423Sdim    newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index);
2446249423Sdim  }
2447249423Sdim  if (newAttr)
2448249423Sdim    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
2460263508Sdim  if (!Attr.isArgIdent(0)) {
2461263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2462263508Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2463221345Sdim    return;
2464221345Sdim  }
2465221345Sdim
2466263508Sdim  IdentifierLoc *IL = Attr.getArgAsIdent(0);
2467263508Sdim  ObjCMethodFamilyAttr::FamilyKind F;
2468263508Sdim  if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
2469263508Sdim    S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName()
2470263508Sdim      << IL->Ident;
2471221345Sdim    return;
2472221345Sdim  }
2473221345Sdim
2474263508Sdim  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
2482226633Sdim  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
2483263508Sdim                                                       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) {
2490263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
2491263508Sdim      << Attr.getName() << ExpectedObjectiveCInterface;
2492193326Sed    return;
2493193326Sed  }
2494198092Srdivacky
2495249423Sdim  D->addAttr(::new (S.Context)
2496249423Sdim             ObjCExceptionAttr(Attr.getRange(), S.Context,
2497249423Sdim                               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();
2503243830Sdim    if (!T->isCARCBridgableType()) {
2504193326Sed      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2505193326Sed      return;
2506193326Sed    }
2507193326Sed  }
2508239462Sdim  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2509239462Sdim    QualType T = PD->getType();
2510243830Sdim    if (!T->isCARCBridgableType()) {
2511239462Sdim      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2512239462Sdim      return;
2513239462Sdim    }
2514239462Sdim  }
2515239462Sdim  else {
2516234353Sdim    // It is okay to include this attribute on properties, e.g.:
2517234353Sdim    //
2518234353Sdim    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2519234353Sdim    //
2520234353Sdim    // In this case it follows tradition and suppresses an error in the above
2521234353Sdim    // case.
2522234353Sdim    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2523234353Sdim  }
2524249423Sdim  D->addAttr(::new (S.Context)
2525249423Sdim             ObjCNSObjectAttr(Attr.getRange(), S.Context,
2526249423Sdim                              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
2536249423Sdim  D->addAttr(::new (S.Context)
2537249423Sdim             OverloadableAttr(Attr.getRange(), S.Context,
2538249423Sdim                              Attr.getAttributeSpellingListIndex()));
2539193326Sed}
2540193326Sed
2541224145Sdimstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2542263508Sdim  if (!Attr.isArgIdent(0)) {
2543263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2544263508Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2545193326Sed    return;
2546193326Sed  }
2547198092Srdivacky
2548263508Sdim  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
2549212904Sdim  BlocksAttr::BlockType type;
2550263508Sdim  if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
2551193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
2552263508Sdim      << Attr.getName() << II;
2553193326Sed    return;
2554193326Sed  }
2555198092Srdivacky
2556249423Sdim  D->addAttr(::new (S.Context)
2557249423Sdim             BlocksAttr(Attr.getRange(), S.Context, type,
2558249423Sdim                        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
2568226633Sdim  unsigned sentinel = 0;
2569193326Sed  if (Attr.getNumArgs() > 0) {
2570263508Sdim    Expr *E = Attr.getArgAsExpr(0);
2571193326Sed    llvm::APSInt Idx(32);
2572208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2573208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2574263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2575263508Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2576263508Sdim        << E->getSourceRange();
2577193326Sed      return;
2578193326Sed    }
2579198092Srdivacky
2580226633Sdim    if (Idx.isSigned() && Idx.isNegative()) {
2581193326Sed      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2582193326Sed        << E->getSourceRange();
2583193326Sed      return;
2584193326Sed    }
2585226633Sdim
2586226633Sdim    sentinel = Idx.getZExtValue();
2587193326Sed  }
2588193326Sed
2589226633Sdim  unsigned nullPos = 0;
2590193326Sed  if (Attr.getNumArgs() > 1) {
2591263508Sdim    Expr *E = Attr.getArgAsExpr(1);
2592193326Sed    llvm::APSInt Idx(32);
2593208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2594208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2595263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2596263508Sdim        << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
2597263508Sdim        << E->getSourceRange();
2598193326Sed      return;
2599193326Sed    }
2600193326Sed    nullPos = Idx.getZExtValue();
2601198092Srdivacky
2602226633Sdim    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)) {
2612226633Sdim    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    }
2627234353Sdim  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2628234353Sdim    if (!BD->isVariadic()) {
2629234353Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2630234353Sdim      return;
2631234353Sdim    }
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  }
2652249423Sdim  D->addAttr(::new (S.Context)
2653249423Sdim             SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
2654249423Sdim                          Attr.getAttributeSpellingListIndex()));
2655193326Sed}
2656193326Sed
2657263508Sdimstatic void handleWarnUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2658263508Sdim  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
2659263508Sdim    RD->addAttr(::new (S.Context) WarnUnusedAttr(Attr.getRange(), S.Context));
2660263508Sdim  else
2661263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2662263508Sdim}
2663263508Sdim
2664224145Sdimstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2665249423Sdim  if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {
2666193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2667249423Sdim      << 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
2683249423Sdim  D->addAttr(::new (S.Context)
2684249423Sdim             WarnUnusedResultAttr(Attr.getRange(), S.Context,
2685249423Sdim                                  Attr.getAttributeSpellingListIndex()));
2686193326Sed}
2687193326Sed
2688224145Sdimstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2689224145Sdim  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
2690234353Sdim    if (isa<CXXRecordDecl>(D)) {
2691234353Sdim      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
2692234353Sdim      return;
2693234353Sdim    }
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
2701249423Sdim  nd->addAttr(::new (S.Context)
2702249423Sdim              WeakAttr(Attr.getRange(), S.Context,
2703249423Sdim                       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)
2711263508Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition)
2712263508Sdim        << "weak_import";
2713221345Sdim    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2714226633Sdim             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
2715234353Sdim              (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
2724249423Sdim  D->addAttr(::new (S.Context)
2725249423Sdim             WeakImportAttr(Attr.getRange(), S.Context,
2726249423Sdim                            Attr.getAttributeSpellingListIndex()));
2727193326Sed}
2728193326Sed
2729239462Sdim// Handles reqd_work_group_size and work_group_size_hint.
2730239462Sdimstatic void handleWorkGroupSize(Sema &S, Decl *D,
2731239462Sdim                                const AttributeList &Attr) {
2732195099Sed  unsigned WGSize[3];
2733195099Sed  for (unsigned i = 0; i < 3; ++i) {
2734263508Sdim    Expr *E = Attr.getArgAsExpr(i);
2735195099Sed    llvm::APSInt ArgNum(32);
2736208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2737208600Srdivacky        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
2738263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
2739263508Sdim        << Attr.getName() << AANT_ArgumentIntegerConstant
2740263508Sdim        << E->getSourceRange();
2741195099Sed      return;
2742195099Sed    }
2743195099Sed    WGSize[i] = (unsigned) ArgNum.getZExtValue();
2744195099Sed  }
2745239462Sdim
2746239462Sdim  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
2747239462Sdim    && D->hasAttr<ReqdWorkGroupSizeAttr>()) {
2748239462Sdim      ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>();
2749239462Sdim      if (!(A->getXDim() == WGSize[0] &&
2750239462Sdim            A->getYDim() == WGSize[1] &&
2751239462Sdim            A->getZDim() == WGSize[2])) {
2752239462Sdim        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
2753239462Sdim          Attr.getName();
2754239462Sdim      }
2755239462Sdim  }
2756239462Sdim
2757239462Sdim  if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint
2758239462Sdim    && D->hasAttr<WorkGroupSizeHintAttr>()) {
2759239462Sdim      WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>();
2760239462Sdim      if (!(A->getXDim() == WGSize[0] &&
2761239462Sdim            A->getYDim() == WGSize[1] &&
2762239462Sdim            A->getZDim() == WGSize[2])) {
2763239462Sdim        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
2764239462Sdim          Attr.getName();
2765239462Sdim      }
2766239462Sdim  }
2767239462Sdim
2768239462Sdim  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
2769239462Sdim    D->addAttr(::new (S.Context)
2770239462Sdim                 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
2771249423Sdim                                       WGSize[0], WGSize[1], WGSize[2],
2772249423Sdim                                       Attr.getAttributeSpellingListIndex()));
2773239462Sdim  else
2774239462Sdim    D->addAttr(::new (S.Context)
2775239462Sdim                 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
2776249423Sdim                                       WGSize[0], WGSize[1], WGSize[2],
2777249423Sdim                                       Attr.getAttributeSpellingListIndex()));
2778195099Sed}
2779195099Sed
2780249423Sdimstatic void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
2781249423Sdim  assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
2782249423Sdim
2783263508Sdim  if (!Attr.hasParsedType()) {
2784263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
2785263508Sdim      << Attr.getName() << 1;
2786249423Sdim    return;
2787263508Sdim  }
2788249423Sdim
2789263508Sdim  TypeSourceInfo *ParmTSI = 0;
2790263508Sdim  QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI);
2791263508Sdim  assert(ParmTSI && "no type source info for attribute argument");
2792249423Sdim
2793249423Sdim  if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
2794249423Sdim      (ParmType->isBooleanType() ||
2795249423Sdim       !ParmType->isIntegralType(S.getASTContext()))) {
2796249423Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint)
2797249423Sdim        << ParmType;
2798249423Sdim    return;
2799249423Sdim  }
2800249423Sdim
2801249423Sdim  if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
2802249423Sdim      D->hasAttr<VecTypeHintAttr>()) {
2803249423Sdim    VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>();
2804263508Sdim    if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
2805249423Sdim      S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
2806249423Sdim      return;
2807249423Sdim    }
2808249423Sdim  }
2809249423Sdim
2810249423Sdim  D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
2811263508Sdim                                               ParmTSI));
2812249423Sdim}
2813249423Sdim
2814239462SdimSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
2815249423Sdim                                    StringRef Name,
2816249423Sdim                                    unsigned AttrSpellingListIndex) {
2817239462Sdim  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2818239462Sdim    if (ExistingAttr->getName() == Name)
2819239462Sdim      return NULL;
2820239462Sdim    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2821239462Sdim    Diag(Range.getBegin(), diag::note_previous_attribute);
2822239462Sdim    return NULL;
2823239462Sdim  }
2824249423Sdim  return ::new (Context) SectionAttr(Range, Context, Name,
2825249423Sdim                                     AttrSpellingListIndex);
2826239462Sdim}
2827239462Sdim
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.
2831263508Sdim  StringRef Str;
2832263508Sdim  SourceLocation LiteralLoc;
2833263508Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc))
2834193326Sed    return;
2835198092Srdivacky
2836198092Srdivacky  // If the target wants to validate the section specifier, make it happen.
2837263508Sdim  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str);
2838202379Srdivacky  if (!Error.empty()) {
2839263508Sdim    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()) {
2846263508Sdim    S.Diag(LiteralLoc, diag::err_attribute_section_local_variable);
2847202379Srdivacky    return;
2848202379Srdivacky  }
2849249423Sdim
2850249423Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2851263508Sdim  SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index);
2852239462Sdim  if (NewAttr)
2853239462Sdim    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())
2860226633Sdim      Existing->setRange(Attr.getRange());
2861224145Sdim  } else {
2862249423Sdim    D->addAttr(::new (S.Context)
2863249423Sdim               NoThrowAttr(Attr.getRange(), S.Context,
2864249423Sdim                           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())
2871226633Sdim     Existing->setRange(Attr.getRange());
2872224145Sdim  } else {
2873249423Sdim    D->addAttr(::new (S.Context)
2874249423Sdim               ConstAttr(Attr.getRange(), S.Context,
2875249423Sdim                         Attr.getAttributeSpellingListIndex() ));
2876224145Sdim  }
2877193326Sed}
2878193326Sed
2879224145Sdimstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2880249423Sdim  D->addAttr(::new (S.Context)
2881249423Sdim             PureAttr(Attr.getRange(), S.Context,
2882249423Sdim                      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()) {
2888263508Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2889193326Sed    return;
2890193326Sed  }
2891198092Srdivacky
2892263508Sdim  Expr *E = Attr.getArgAsExpr(0);
2893263508Sdim  SourceLocation Loc = E->getExprLoc();
2894263508Sdim  FunctionDecl *FD = 0;
2895263508Sdim  DeclarationNameInfo NI;
2896198092Srdivacky
2897263508Sdim  // gcc only allows for simple identifiers. Since we support more than gcc, we
2898263508Sdim  // will warn the user.
2899263508Sdim  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
2900263508Sdim    if (DRE->hasQualifier())
2901263508Sdim      S.Diag(Loc, diag::warn_cleanup_ext);
2902263508Sdim    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2903263508Sdim    NI = DRE->getNameInfo();
2904263508Sdim    if (!FD) {
2905263508Sdim      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
2906263508Sdim        << NI.getName();
2907263508Sdim      return;
2908263508Sdim    }
2909263508Sdim  } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
2910263508Sdim    if (ULE->hasExplicitTemplateArgs())
2911263508Sdim      S.Diag(Loc, diag::warn_cleanup_ext);
2912263508Sdim    FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
2913263508Sdim    NI = ULE->getNameInfo();
2914263508Sdim    if (!FD) {
2915263508Sdim      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
2916263508Sdim        << NI.getName();
2917263508Sdim      if (ULE->getType() == S.Context.OverloadTy)
2918263508Sdim        S.NoteAllOverloadCandidates(ULE);
2919263508Sdim      return;
2920263508Sdim    }
2921263508Sdim  } else {
2922263508Sdim    S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
2923193326Sed    return;
2924193326Sed  }
2925193326Sed
2926193326Sed  if (FD->getNumParams() != 1) {
2927263508Sdim    S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
2928263508Sdim      << 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) {
2938263508Sdim    S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
2939263508Sdim      << NI.getName() << ParamTy << Ty;
2940193326Sed    return;
2941193326Sed  }
2942198092Srdivacky
2943249423Sdim  D->addAttr(::new (S.Context)
2944249423Sdim             CleanupAttr(Attr.getRange(), S.Context, FD,
2945249423Sdim                         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
2957263508Sdim  Expr *IdxExpr = Attr.getArgAsExpr(0);
2958263508Sdim  uint64_t ArgIdx;
2959263508Sdim  if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
2960263508Sdim                                          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
2989263508Sdim  // We cannot use the ArgIdx returned from checkFunctionOrMethodArgumentIndex
2990263508Sdim  // because that has corrected for the implicit this parameter, and is zero-
2991263508Sdim  // based.  The attribute expects what the user wrote explicitly.
2992263508Sdim  llvm::APSInt Val;
2993263508Sdim  IdxExpr->EvaluateAsInt(Val, S.Context);
2994263508Sdim
2995249423Sdim  D->addAttr(::new (S.Context)
2996263508Sdim             FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(),
2997249423Sdim                           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.
3011226633Sdimstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
3012239462Sdim  return llvm::StringSwitch<FormatAttrKind>(Format)
3013239462Sdim    // Check for formats that get handled specially.
3014239462Sdim    .Case("NSString", NSStringFormat)
3015239462Sdim    .Case("CFString", CFStringFormat)
3016239462Sdim    .Case("strftime", StrftimeFormat)
3017198398Srdivacky
3018239462Sdim    // Otherwise, check for supported formats.
3019239462Sdim    .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
3020239462Sdim    .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
3021239462Sdim    .Case("kprintf", SupportedFormat) // OpenBSD.
3022198398Srdivacky
3023239462Sdim    .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
3024239462Sdim    .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) {
3031234353Sdim  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
3050263508Sdim  Expr *priorityExpr = Attr.getArgAsExpr(0);
3051210299Sed
3052210299Sed  llvm::APSInt priority(32);
3053210299Sed  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
3054210299Sed      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
3055263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3056263508Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
3057263508Sdim      << 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  }
3068249423Sdim  D->addAttr(::new (S.Context)
3069249423Sdim             InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
3070249423Sdim                              Attr.getAttributeSpellingListIndex()));
3071210299Sed}
3072210299Sed
3073263508SdimFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
3074263508Sdim                                  IdentifierInfo *Format, int FormatIdx,
3075263508Sdim                                  int FirstArg,
3076249423Sdim                                  unsigned AttrSpellingListIndex) {
3077239462Sdim  // Check whether we already have an equivalent format attribute.
3078239462Sdim  for (specific_attr_iterator<FormatAttr>
3079239462Sdim         i = D->specific_attr_begin<FormatAttr>(),
3080239462Sdim         e = D->specific_attr_end<FormatAttr>();
3081239462Sdim       i != e ; ++i) {
3082239462Sdim    FormatAttr *f = *i;
3083239462Sdim    if (f->getType() == Format &&
3084239462Sdim        f->getFormatIdx() == FormatIdx &&
3085239462Sdim        f->getFirstArg() == FirstArg) {
3086239462Sdim      // If we don't have a valid location for this attribute, adopt the
3087239462Sdim      // location.
3088239462Sdim      if (f->getLocation().isInvalid())
3089239462Sdim        f->setRange(Range);
3090239462Sdim      return NULL;
3091239462Sdim    }
3092239462Sdim  }
3093239462Sdim
3094263508Sdim  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
3095263508Sdim                                    FirstArg, AttrSpellingListIndex);
3096239462Sdim}
3097239462Sdim
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) {
3101263508Sdim  if (!Attr.isArgIdent(0)) {
3102263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3103263508Sdim      << 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
3119263508Sdim  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
3120263508Sdim  StringRef Format = II->getName();
3121193326Sed
3122193326Sed  // Normalize the argument, __foo__ becomes foo.
3123263508Sdim  if (Format.startswith("__") && Format.endswith("__")) {
3124198398Srdivacky    Format = Format.substr(2, Format.size() - 4);
3125263508Sdim    // If we've modified the string name, we need a new identifier for it.
3126263508Sdim    II = &S.Context.Idents.get(Format);
3127263508Sdim  }
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)
3137263508Sdim      << "format" << II->getName();
3138193326Sed    return;
3139193326Sed  }
3140193326Sed
3141193326Sed  // checks for the 2nd argument
3142263508Sdim  Expr *IdxExpr = Attr.getArgAsExpr(1);
3143193326Sed  llvm::APSInt Idx(32);
3144208600Srdivacky  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
3145208600Srdivacky      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
3146263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3147263508Sdim      << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
3148263508Sdim      << 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
3198263508Sdim  Expr *FirstArgExpr = Attr.getArgAsExpr(2);
3199193326Sed  llvm::APSInt FirstArg(32);
3200208600Srdivacky  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
3201208600Srdivacky      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
3202263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3203263508Sdim      << Attr.getName() << 3 << AANT_ArgumentIntegerConstant
3204263508Sdim      << 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
3233263508Sdim  FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II,
3234212904Sdim                                          Idx.getZExtValue(),
3235249423Sdim                                          FirstArg.getZExtValue(),
3236249423Sdim                                          Attr.getAttributeSpellingListIndex());
3237239462Sdim  if (NewAttr)
3238239462Sdim    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
3257226633Sdim  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
3300249423Sdim  RD->addAttr(::new (S.Context)
3301249423Sdim              TransparentUnionAttr(Attr.getRange(), S.Context,
3302249423Sdim                                   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.
3308263508Sdim  StringRef Str;
3309263508Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
3310193326Sed    return;
3311226633Sdim
3312226633Sdim  // Don't duplicate annotations that are already set.
3313226633Sdim  for (specific_attr_iterator<AnnotateAttr>
3314226633Sdim       i = D->specific_attr_begin<AnnotateAttr>(),
3315226633Sdim       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
3316263508Sdim    if ((*i)->getAnnotation() == Str)
3317263508Sdim      return;
3318226633Sdim  }
3319249423Sdim
3320249423Sdim  D->addAttr(::new (S.Context)
3321263508Sdim             AnnotateAttr(Attr.getRange(), S.Context, Str,
3322249423Sdim                          Attr.getAttributeSpellingListIndex()));
3323193326Sed}
3324193326Sed
3325224145Sdimstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3326193326Sed  // check the attribute arguments.
3327193326Sed  if (Attr.getNumArgs() > 1) {
3328263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
3329263508Sdim      << Attr.getName() << 1;
3330193326Sed    return;
3331193326Sed  }
3332239462Sdim
3333193326Sed  if (Attr.getNumArgs() == 0) {
3334249423Sdim    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
3335249423Sdim               true, 0, Attr.getAttributeSpellingListIndex()));
3336193326Sed    return;
3337193326Sed  }
3338198092Srdivacky
3339263508Sdim  Expr *E = Attr.getArgAsExpr(0);
3340249423Sdim  if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
3341249423Sdim    S.Diag(Attr.getEllipsisLoc(),
3342249423Sdim           diag::err_pack_expansion_without_parameter_packs);
3343249423Sdim    return;
3344249423Sdim  }
3345210299Sed
3346249423Sdim  if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
3347234353Sdim    return;
3348234353Sdim
3349249423Sdim  S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(),
3350249423Sdim                   Attr.isPackExpansion());
3351249423Sdim}
3352249423Sdim
3353249423Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
3354249423Sdim                          unsigned SpellingListIndex, bool IsPackExpansion) {
3355249423Sdim  AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex);
3356249423Sdim  SourceLocation AttrLoc = AttrRange.getBegin();
3357249423Sdim
3358249423Sdim  // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
3359249423Sdim  if (TmpAttr.isAlignas()) {
3360249423Sdim    // C++11 [dcl.align]p1:
3361249423Sdim    //   An alignment-specifier may be applied to a variable or to a class
3362249423Sdim    //   data member, but it shall not be applied to a bit-field, a function
3363249423Sdim    //   parameter, the formal parameter of a catch clause, or a variable
3364249423Sdim    //   declared with the register storage class specifier. An
3365249423Sdim    //   alignment-specifier may also be applied to the declaration of a class
3366249423Sdim    //   or enumeration type.
3367249423Sdim    // C11 6.7.5/2:
3368249423Sdim    //   An alignment attribute shall not be specified in a declaration of
3369249423Sdim    //   a typedef, or a bit-field, or a function, or a parameter, or an
3370249423Sdim    //   object declared with the register storage-class specifier.
3371249423Sdim    int DiagKind = -1;
3372249423Sdim    if (isa<ParmVarDecl>(D)) {
3373249423Sdim      DiagKind = 0;
3374249423Sdim    } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3375249423Sdim      if (VD->getStorageClass() == SC_Register)
3376249423Sdim        DiagKind = 1;
3377249423Sdim      if (VD->isExceptionVariable())
3378249423Sdim        DiagKind = 2;
3379249423Sdim    } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
3380249423Sdim      if (FD->isBitField())
3381249423Sdim        DiagKind = 3;
3382249423Sdim    } else if (!isa<TagDecl>(D)) {
3383249423Sdim      Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
3384249423Sdim        << (TmpAttr.isC11() ? "'_Alignas'" : "'alignas'")
3385249423Sdim        << (TmpAttr.isC11() ? ExpectedVariableOrField
3386249423Sdim                            : ExpectedVariableFieldOrTag);
3387249423Sdim      return;
3388249423Sdim    }
3389249423Sdim    if (DiagKind != -1) {
3390249423Sdim      Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
3391249423Sdim        << TmpAttr.isC11() << DiagKind;
3392249423Sdim      return;
3393249423Sdim    }
3394249423Sdim  }
3395249423Sdim
3396210299Sed  if (E->isTypeDependent() || E->isValueDependent()) {
3397210299Sed    // Save dependent expressions in the AST to be instantiated.
3398249423Sdim    AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
3399249423Sdim    AA->setPackExpansion(IsPackExpansion);
3400249423Sdim    D->addAttr(AA);
3401210299Sed    return;
3402210299Sed  }
3403249423Sdim
3404212904Sdim  // FIXME: Cache the number on the Attr object?
3405193326Sed  llvm::APSInt Alignment(32);
3406239462Sdim  ExprResult ICE
3407239462Sdim    = VerifyIntegerConstantExpression(E, &Alignment,
3408239462Sdim        diag::err_aligned_attribute_argument_not_int,
3409239462Sdim        /*AllowFold*/ false);
3410234353Sdim  if (ICE.isInvalid())
3411193326Sed    return;
3412249423Sdim
3413249423Sdim  // C++11 [dcl.align]p2:
3414249423Sdim  //   -- if the constant expression evaluates to zero, the alignment
3415249423Sdim  //      specifier shall have no effect
3416249423Sdim  // C11 6.7.5p6:
3417249423Sdim  //   An alignment specification of zero has no effect.
3418249423Sdim  if (!(TmpAttr.isAlignas() && !Alignment) &&
3419249423Sdim      !llvm::isPowerOf2_64(Alignment.getZExtValue())) {
3420210299Sed    Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
3421210299Sed      << E->getSourceRange();
3422193326Sed    return;
3423193326Sed  }
3424249423Sdim
3425249423Sdim  if (TmpAttr.isDeclspec()) {
3426239462Sdim    // We've already verified it's a power of 2, now let's make sure it's
3427239462Sdim    // 8192 or less.
3428239462Sdim    if (Alignment.getZExtValue() > 8192) {
3429249423Sdim      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
3430239462Sdim        << E->getSourceRange();
3431239462Sdim      return;
3432239462Sdim    }
3433239462Sdim  }
3434193326Sed
3435249423Sdim  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
3436249423Sdim                                                ICE.take(), SpellingListIndex);
3437249423Sdim  AA->setPackExpansion(IsPackExpansion);
3438249423Sdim  D->addAttr(AA);
3439193326Sed}
3440193326Sed
3441249423Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
3442249423Sdim                          unsigned SpellingListIndex, bool IsPackExpansion) {
3443212904Sdim  // FIXME: Cache the number on the Attr object if non-dependent?
3444212904Sdim  // FIXME: Perform checking of type validity
3445249423Sdim  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS,
3446249423Sdim                                                SpellingListIndex);
3447249423Sdim  AA->setPackExpansion(IsPackExpansion);
3448249423Sdim  D->addAttr(AA);
3449212904Sdim}
3450212904Sdim
3451249423Sdimvoid Sema::CheckAlignasUnderalignment(Decl *D) {
3452249423Sdim  assert(D->hasAttrs() && "no attributes on decl");
3453249423Sdim
3454249423Sdim  QualType Ty;
3455249423Sdim  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3456249423Sdim    Ty = VD->getType();
3457249423Sdim  else
3458249423Sdim    Ty = Context.getTagDeclType(cast<TagDecl>(D));
3459249423Sdim  if (Ty->isDependentType() || Ty->isIncompleteType())
3460249423Sdim    return;
3461249423Sdim
3462249423Sdim  // C++11 [dcl.align]p5, C11 6.7.5/4:
3463249423Sdim  //   The combined effect of all alignment attributes in a declaration shall
3464249423Sdim  //   not specify an alignment that is less strict than the alignment that
3465249423Sdim  //   would otherwise be required for the entity being declared.
3466249423Sdim  AlignedAttr *AlignasAttr = 0;
3467249423Sdim  unsigned Align = 0;
3468249423Sdim  for (specific_attr_iterator<AlignedAttr>
3469249423Sdim         I = D->specific_attr_begin<AlignedAttr>(),
3470249423Sdim         E = D->specific_attr_end<AlignedAttr>(); I != E; ++I) {
3471249423Sdim    if (I->isAlignmentDependent())
3472249423Sdim      return;
3473249423Sdim    if (I->isAlignas())
3474249423Sdim      AlignasAttr = *I;
3475249423Sdim    Align = std::max(Align, I->getAlignment(Context));
3476249423Sdim  }
3477249423Sdim
3478249423Sdim  if (AlignasAttr && Align) {
3479249423Sdim    CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
3480249423Sdim    CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty);
3481249423Sdim    if (NaturalAlign > RequestedAlign)
3482249423Sdim      Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
3483249423Sdim        << Ty << (unsigned)NaturalAlign.getQuantity();
3484249423Sdim  }
3485249423Sdim}
3486249423Sdim
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.
3496263508Sdim  if (!Attr.isArgIdent(0)) {
3497263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
3498263508Sdim      << AANT_ArgumentIdentifier;
3499193326Sed    return;
3500193326Sed  }
3501263508Sdim
3502263508Sdim  IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident;
3503263508Sdim  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")
3535226633Sdim      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3536198398Srdivacky    else if (Str == "byte")
3537226633Sdim      DestWidth = S.Context.getTargetInfo().getCharWidth();
3538193326Sed    break;
3539193326Sed  case 7:
3540198398Srdivacky    if (Str == "pointer")
3541226633Sdim      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3542193326Sed    break;
3543249423Sdim  case 11:
3544249423Sdim    if (Str == "unwind_word")
3545249423Sdim      DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
3546249423Sdim    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)
3556226633Sdim      << "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
3577263508Sdim  if (!DestWidth) {
3578193326Sed    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
3579193326Sed    return;
3580263508Sdim  }
3581263508Sdim
3582263508Sdim  QualType NewTy;
3583263508Sdim
3584263508Sdim  if (IntegerMode)
3585263508Sdim    NewTy = S.Context.getIntTypeForBitwidth(DestWidth,
3586263508Sdim                                            OldTy->isSignedIntegerType());
3587263508Sdim  else
3588263508Sdim    NewTy = S.Context.getRealTypeForBitwidth(DestWidth);
3589263508Sdim
3590263508Sdim  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.
3600263508Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3601263508Sdim    TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
3602263508Sdim  else
3603193326Sed    cast<ValueDecl>(D)->setType(NewTy);
3604263508Sdim
3605263508Sdim  D->addAttr(::new (S.Context)
3606263508Sdim             ModeAttr(Attr.getRange(), S.Context, Name,
3607263508Sdim                      Attr.getAttributeSpellingListIndex()));
3608193326Sed}
3609193326Sed
3610224145Sdimstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3611239462Sdim  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3612239462Sdim    if (!VD->hasGlobalStorage())
3613239462Sdim      S.Diag(Attr.getLoc(),
3614239462Sdim             diag::warn_attribute_requires_functions_or_static_globals)
3615239462Sdim        << Attr.getName();
3616239462Sdim  } else if (!isFunctionOrMethod(D)) {
3617239462Sdim    S.Diag(Attr.getLoc(),
3618239462Sdim           diag::warn_attribute_requires_functions_or_static_globals)
3619239462Sdim      << Attr.getName();
3620193326Sed    return;
3621193326Sed  }
3622198092Srdivacky
3623249423Sdim  D->addAttr(::new (S.Context)
3624249423Sdim             NoDebugAttr(Attr.getRange(), S.Context,
3625249423Sdim                         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
3635249423Sdim  D->addAttr(::new (S.Context)
3636249423Sdim             NoInlineAttr(Attr.getRange(), S.Context,
3637249423Sdim             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
3648249423Sdim  D->addAttr(::new (S.Context)
3649249423Sdim             NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
3650249423Sdim                                      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
3661249423Sdim    D->addAttr(::new (S.Context)
3662249423Sdim               CUDAConstantAttr(Attr.getRange(), S.Context,
3663249423Sdim                                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) {
3673263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
3674263508Sdim        << 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
3684249423Sdim    D->addAttr(::new (S.Context)
3685249423Sdim               CUDADeviceAttr(Attr.getRange(), S.Context,
3686249423Sdim                              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();
3703249423Sdim      if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
3704218893Sdim        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3705218893Sdim          << FD->getType()
3706249423Sdim          << 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
3715249423Sdim    D->addAttr(::new (S.Context)
3716249423Sdim               CUDAGlobalAttr(Attr.getRange(), S.Context,
3717249423Sdim                              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
3731249423Sdim    D->addAttr(::new (S.Context)
3732249423Sdim               CUDAHostAttr(Attr.getRange(), S.Context,
3733249423Sdim                            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
3747249423Sdim    D->addAttr(::new (S.Context)
3748249423Sdim               CUDASharedAttr(Attr.getRange(), S.Context,
3749249423Sdim                              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
3768249423Sdim  D->addAttr(::new (S.Context)
3769249423Sdim             GNUInlineAttr(Attr.getRange(), S.Context,
3770249423Sdim                           Attr.getAttributeSpellingListIndex()));
3771193326Sed}
3772193326Sed
3773224145Sdimstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3774224145Sdim  if (hasDeclarator(D)) return;
3775218893Sdim
3776249423Sdim  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;
3780249423Sdim  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()) {
3790239462Sdim  case AttributeList::AT_FastCall:
3791249423Sdim    D->addAttr(::new (S.Context)
3792249423Sdim               FastCallAttr(Attr.getRange(), S.Context,
3793249423Sdim                            Attr.getAttributeSpellingListIndex()));
3794207619Srdivacky    return;
3795239462Sdim  case AttributeList::AT_StdCall:
3796249423Sdim    D->addAttr(::new (S.Context)
3797249423Sdim               StdCallAttr(Attr.getRange(), S.Context,
3798249423Sdim                           Attr.getAttributeSpellingListIndex()));
3799207619Srdivacky    return;
3800239462Sdim  case AttributeList::AT_ThisCall:
3801249423Sdim    D->addAttr(::new (S.Context)
3802249423Sdim               ThisCallAttr(Attr.getRange(), S.Context,
3803249423Sdim                            Attr.getAttributeSpellingListIndex()));
3804212904Sdim    return;
3805239462Sdim  case AttributeList::AT_CDecl:
3806249423Sdim    D->addAttr(::new (S.Context)
3807249423Sdim               CDeclAttr(Attr.getRange(), S.Context,
3808249423Sdim                         Attr.getAttributeSpellingListIndex()));
3809207619Srdivacky    return;
3810239462Sdim  case AttributeList::AT_Pascal:
3811249423Sdim    D->addAttr(::new (S.Context)
3812249423Sdim               PascalAttr(Attr.getRange(), S.Context,
3813249423Sdim                          Attr.getAttributeSpellingListIndex()));
3814212904Sdim    return;
3815256030Sdim  case AttributeList::AT_MSABI:
3816256030Sdim    D->addAttr(::new (S.Context)
3817256030Sdim               MSABIAttr(Attr.getRange(), S.Context,
3818256030Sdim                         Attr.getAttributeSpellingListIndex()));
3819256030Sdim    return;
3820256030Sdim  case AttributeList::AT_SysVABI:
3821256030Sdim    D->addAttr(::new (S.Context)
3822256030Sdim               SysVABIAttr(Attr.getRange(), S.Context,
3823256030Sdim                           Attr.getAttributeSpellingListIndex()));
3824256030Sdim    return;
3825239462Sdim  case AttributeList::AT_Pcs: {
3826221345Sdim    PcsAttr::PCSType PCS;
3827239462Sdim    switch (CC) {
3828239462Sdim    case CC_AAPCS:
3829221345Sdim      PCS = PcsAttr::AAPCS;
3830239462Sdim      break;
3831239462Sdim    case CC_AAPCS_VFP:
3832221345Sdim      PCS = PcsAttr::AAPCS_VFP;
3833239462Sdim      break;
3834239462Sdim    default:
3835239462Sdim      llvm_unreachable("unexpected calling convention in pcs attribute");
3836221345Sdim    }
3837221345Sdim
3838249423Sdim    D->addAttr(::new (S.Context)
3839249423Sdim               PcsAttr(Attr.getRange(), S.Context, PCS,
3840249423Sdim                       Attr.getAttributeSpellingListIndex()));
3841243830Sdim    return;
3842221345Sdim  }
3843243830Sdim  case AttributeList::AT_PnaclCall:
3844249423Sdim    D->addAttr(::new (S.Context)
3845249423Sdim               PnaclCallAttr(Attr.getRange(), S.Context,
3846249423Sdim                             Attr.getAttributeSpellingListIndex()));
3847243830Sdim    return;
3848249423Sdim  case AttributeList::AT_IntelOclBicc:
3849249423Sdim    D->addAttr(::new (S.Context)
3850249423Sdim               IntelOclBiccAttr(Attr.getRange(), S.Context,
3851249423Sdim                                Attr.getAttributeSpellingListIndex()));
3852249423Sdim    return;
3853243830Sdim
3854207619Srdivacky  default:
3855207619Srdivacky    llvm_unreachable("unexpected attribute kind");
3856207619Srdivacky  }
3857207619Srdivacky}
3858207619Srdivacky
3859224145Sdimstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
3860226633Sdim  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
3861218893Sdim}
3862218893Sdim
3863249423Sdimstatic void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){
3864263508Sdim  Expr *E = Attr.getArgAsExpr(0);
3865249423Sdim  llvm::APSInt ArgNum(32);
3866249423Sdim  if (E->isTypeDependent() || E->isValueDependent() ||
3867249423Sdim      !E->isIntegerConstantExpr(ArgNum, S.Context)) {
3868263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3869263508Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
3870263508Sdim      << E->getSourceRange();
3871249423Sdim    return;
3872249423Sdim  }
3873249423Sdim
3874249423Sdim  D->addAttr(::new (S.Context) OpenCLImageAccessAttr(
3875249423Sdim    Attr.getRange(), S.Context, ArgNum.getZExtValue()));
3876249423Sdim}
3877249423Sdim
3878249423Sdimbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
3879249423Sdim                                const FunctionDecl *FD) {
3880218893Sdim  if (attr.isInvalid())
3881218893Sdim    return true;
3882218893Sdim
3883239462Sdim  unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
3884263508Sdim  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()) {
3892239462Sdim  case AttributeList::AT_CDecl: CC = CC_C; break;
3893239462Sdim  case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
3894239462Sdim  case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
3895239462Sdim  case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
3896239462Sdim  case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
3897256030Sdim  case AttributeList::AT_MSABI:
3898256030Sdim    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
3899256030Sdim                                                             CC_X86_64Win64;
3900256030Sdim    break;
3901256030Sdim  case AttributeList::AT_SysVABI:
3902256030Sdim    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
3903256030Sdim                                                             CC_C;
3904256030Sdim    break;
3905239462Sdim  case AttributeList::AT_Pcs: {
3906263508Sdim    StringRef StrRef;
3907263508Sdim    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    }
3918239462Sdim
3919239462Sdim    attr.setInvalid();
3920239462Sdim    Diag(attr.getLoc(), diag::err_invalid_pcs);
3921239462Sdim    return true;
3922221345Sdim  }
3923243830Sdim  case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break;
3924249423Sdim  case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
3925234353Sdim  default: llvm_unreachable("unexpected attribute kind");
3926218893Sdim  }
3927218893Sdim
3928243830Sdim  const TargetInfo &TI = Context.getTargetInfo();
3929243830Sdim  TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
3930243830Sdim  if (A == TargetInfo::CCCR_Warning) {
3931243830Sdim    Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
3932249423Sdim
3933249423Sdim    TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
3934249423Sdim    if (FD)
3935249423Sdim      MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
3936249423Sdim                                    TargetInfo::CCMT_NonMember;
3937249423Sdim    CC = TI.getDefaultCallingConv(MT);
3938243830Sdim  }
3939243830Sdim
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
3956249423Sdim  D->addAttr(::new (S.Context)
3957249423Sdim             RegparmAttr(Attr.getRange(), S.Context, numParams,
3958249423Sdim                         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
3967263508Sdim  if (!checkAttributeNumArgs(*this, Attr, 1)) {
3968224145Sdim    Attr.setInvalid();
3969218893Sdim    return true;
3970218893Sdim  }
3971218893Sdim
3972263508Sdim  Expr *NumParamsExpr = Attr.getArgAsExpr(0);
3973193326Sed  llvm::APSInt NumParams(32);
3974208600Srdivacky  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
3975218893Sdim      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
3976263508Sdim    Diag(Attr.getLoc(), diag::err_attribute_argument_type)
3977263508Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
3978263508Sdim      << NumParamsExpr->getSourceRange();
3979224145Sdim    Attr.setInvalid();
3980218893Sdim    return true;
3981193326Sed  }
3982193326Sed
3983226633Sdim  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();
3991226633Sdim  if (numParams > Context.getTargetInfo().getRegParmMax()) {
3992224145Sdim    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3993226633Sdim      << 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
4016263508Sdim    Expr *MaxThreadsExpr = Attr.getArgAsExpr(0);
4017218893Sdim    llvm::APSInt MaxThreads(32);
4018218893Sdim    if (MaxThreadsExpr->isTypeDependent() ||
4019218893Sdim        MaxThreadsExpr->isValueDependent() ||
4020218893Sdim        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
4021263508Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4022263508Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
4023263508Sdim        << MaxThreadsExpr->getSourceRange();
4024218893Sdim      return;
4025218893Sdim    }
4026218893Sdim
4027218893Sdim    llvm::APSInt MinBlocks(32);
4028218893Sdim    if (Attr.getNumArgs() > 1) {
4029263508Sdim      Expr *MinBlocksExpr = Attr.getArgAsExpr(1);
4030218893Sdim      if (MinBlocksExpr->isTypeDependent() ||
4031218893Sdim          MinBlocksExpr->isValueDependent() ||
4032218893Sdim          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
4033263508Sdim        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4034263508Sdim          << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
4035263508Sdim          << MinBlocksExpr->getSourceRange();
4036218893Sdim        return;
4037218893Sdim      }
4038218893Sdim    }
4039218893Sdim
4040249423Sdim    D->addAttr(::new (S.Context)
4041249423Sdim               CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
4042249423Sdim                                    MaxThreads.getZExtValue(),
4043249423Sdim                                    MinBlocks.getZExtValue(),
4044249423Sdim                                    Attr.getAttributeSpellingListIndex()));
4045218893Sdim  } else {
4046218893Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
4047199990Srdivacky  }
4048199990Srdivacky}
4049199990Srdivacky
4050239462Sdimstatic void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
4051239462Sdim                                          const AttributeList &Attr) {
4052263508Sdim  if (!Attr.isArgIdent(0)) {
4053263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4054263508Sdim      << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier;
4055239462Sdim    return;
4056239462Sdim  }
4057263508Sdim
4058263508Sdim  if (!checkAttributeNumArgs(S, Attr, 3))
4059239462Sdim    return;
4060239462Sdim
4061263508Sdim  StringRef AttrName = Attr.getName()->getName();
4062263508Sdim  IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident;
4063239462Sdim
4064239462Sdim  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
4065239462Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
4066239462Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
4067239462Sdim    return;
4068239462Sdim  }
4069239462Sdim
4070239462Sdim  uint64_t ArgumentIdx;
4071239462Sdim  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
4072239462Sdim                                          Attr.getLoc(), 2,
4073263508Sdim                                          Attr.getArgAsExpr(1), ArgumentIdx))
4074239462Sdim    return;
4075239462Sdim
4076239462Sdim  uint64_t TypeTagIdx;
4077239462Sdim  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
4078239462Sdim                                          Attr.getLoc(), 3,
4079263508Sdim                                          Attr.getArgAsExpr(2), TypeTagIdx))
4080239462Sdim    return;
4081239462Sdim
4082239462Sdim  bool IsPointer = (AttrName == "pointer_with_type_tag");
4083239462Sdim  if (IsPointer) {
4084239462Sdim    // Ensure that buffer has a pointer type.
4085239462Sdim    QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
4086239462Sdim    if (!BufferTy->isPointerType()) {
4087239462Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
4088263508Sdim        << Attr.getName();
4089239462Sdim    }
4090239462Sdim  }
4091239462Sdim
4092249423Sdim  D->addAttr(::new (S.Context)
4093249423Sdim             ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
4094249423Sdim                                     ArgumentIdx, TypeTagIdx, IsPointer,
4095249423Sdim                                     Attr.getAttributeSpellingListIndex()));
4096239462Sdim}
4097239462Sdim
4098239462Sdimstatic void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
4099239462Sdim                                         const AttributeList &Attr) {
4100263508Sdim  if (!Attr.isArgIdent(0)) {
4101263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
4102263508Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
4103239462Sdim    return;
4104239462Sdim  }
4105263508Sdim
4106263508Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
4107263508Sdim    return;
4108239462Sdim
4109263508Sdim  IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
4110263508Sdim  TypeSourceInfo *MatchingCTypeLoc = 0;
4111263508Sdim  S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc);
4112263508Sdim  assert(MatchingCTypeLoc && "no type source info for attribute argument");
4113239462Sdim
4114249423Sdim  D->addAttr(::new (S.Context)
4115249423Sdim             TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
4116263508Sdim                                    MatchingCTypeLoc,
4117249423Sdim                                    Attr.getLayoutCompatible(),
4118249423Sdim                                    Attr.getMustBeNull(),
4119249423Sdim                                    Attr.getAttributeSpellingListIndex()));
4120239462Sdim}
4121239462Sdim
4122193326Sed//===----------------------------------------------------------------------===//
4123218893Sdim// Checker-specific attribute handlers.
4124199990Srdivacky//===----------------------------------------------------------------------===//
4125199990Srdivacky
4126218893Sdimstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
4127226633Sdim  return type->isDependentType() ||
4128226633Sdim         type->isObjCObjectPointerType() ||
4129226633Sdim         S.Context.isObjCNSObjectType(type);
4130199990Srdivacky}
4131218893Sdimstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
4132226633Sdim  return type->isDependentType() ||
4133226633Sdim         type->isPointerType() ||
4134226633Sdim         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)
4141226633Sdim      << Attr.getRange() << Attr.getName() << ExpectedParameter;
4142199990Srdivacky    return;
4143199990Srdivacky  }
4144199990Srdivacky
4145218893Sdim  bool typeOK, cf;
4146239462Sdim  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)
4156226633Sdim      << Attr.getRange() << Attr.getName() << cf;
4157199990Srdivacky    return;
4158199990Srdivacky  }
4159199990Srdivacky
4160218893Sdim  if (cf)
4161249423Sdim    param->addAttr(::new (S.Context)
4162249423Sdim                   CFConsumedAttr(Attr.getRange(), S.Context,
4163249423Sdim                                  Attr.getAttributeSpellingListIndex()));
4164218893Sdim  else
4165249423Sdim    param->addAttr(::new (S.Context)
4166249423Sdim                   NSConsumedAttr(Attr.getRange(), S.Context,
4167249423Sdim                                  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)
4174226633Sdim      << Attr.getRange() << Attr.getName() << ExpectedMethod;
4175199990Srdivacky    return;
4176199990Srdivacky  }
4177199990Srdivacky
4178249423Sdim  D->addAttr(::new (S.Context)
4179249423Sdim             NSConsumesSelfAttr(Attr.getRange(), S.Context,
4180249423Sdim                                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();
4190234353Sdim  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
4191239462Sdim           (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
4192224145Sdim    return; // ignore: was handled as a type attribute
4193243830Sdim  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
4194243830Sdim    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)
4199226633Sdim        << Attr.getRange() << Attr.getName()
4200221345Sdim        << ExpectedFunctionOrMethod;
4201193326Sed    return;
4202193326Sed  }
4203198092Srdivacky
4204218893Sdim  bool typeOK;
4205218893Sdim  bool cf;
4206224145Sdim  switch (Attr.getKind()) {
4207234353Sdim  default: llvm_unreachable("invalid ownership attribute");
4208239462Sdim  case AttributeList::AT_NSReturnsAutoreleased:
4209239462Sdim  case AttributeList::AT_NSReturnsRetained:
4210239462Sdim  case AttributeList::AT_NSReturnsNotRetained:
4211218893Sdim    typeOK = isValidSubjectOfNSAttribute(S, returnType);
4212218893Sdim    cf = false;
4213218893Sdim    break;
4214218893Sdim
4215239462Sdim  case AttributeList::AT_CFReturnsRetained:
4216239462Sdim  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)
4224226633Sdim      << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf;
4225198092Srdivacky    return;
4226193326Sed  }
4227198092Srdivacky
4228224145Sdim  switch (Attr.getKind()) {
4229193326Sed    default:
4230226633Sdim      llvm_unreachable("invalid ownership attribute");
4231239462Sdim    case AttributeList::AT_NSReturnsAutoreleased:
4232249423Sdim      D->addAttr(::new (S.Context)
4233249423Sdim                 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
4234249423Sdim                                           Attr.getAttributeSpellingListIndex()));
4235218893Sdim      return;
4236239462Sdim    case AttributeList::AT_CFReturnsNotRetained:
4237249423Sdim      D->addAttr(::new (S.Context)
4238249423Sdim                 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4239249423Sdim                                          Attr.getAttributeSpellingListIndex()));
4240204643Srdivacky      return;
4241239462Sdim    case AttributeList::AT_NSReturnsNotRetained:
4242249423Sdim      D->addAttr(::new (S.Context)
4243249423Sdim                 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
4244249423Sdim                                          Attr.getAttributeSpellingListIndex()));
4245204643Srdivacky      return;
4246239462Sdim    case AttributeList::AT_CFReturnsRetained:
4247249423Sdim      D->addAttr(::new (S.Context)
4248249423Sdim                 CFReturnsRetainedAttr(Attr.getRange(), S.Context,
4249249423Sdim                                       Attr.getAttributeSpellingListIndex()));
4250193326Sed      return;
4251239462Sdim    case AttributeList::AT_NSReturnsRetained:
4252249423Sdim      D->addAttr(::new (S.Context)
4253249423Sdim                 NSReturnsRetainedAttr(Attr.getRange(), S.Context,
4254249423Sdim                                       Attr.getAttributeSpellingListIndex()));
4255193326Sed      return;
4256193326Sed  };
4257193326Sed}
4258193326Sed
4259226633Sdimstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
4260226633Sdim                                              const AttributeList &attr) {
4261263508Sdim  const int EP_ObjCMethod = 1;
4262263508Sdim  const int EP_ObjCProperty = 2;
4263263508Sdim
4264226633Sdim  SourceLocation loc = attr.getLoc();
4265263508Sdim  QualType resultType;
4266263508Sdim
4267226633Sdim  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4268226633Sdim
4269239462Sdim  if (!method) {
4270263508Sdim    ObjCPropertyDecl *property = dyn_cast<ObjCPropertyDecl>(D);
4271263508Sdim    if (!property) {
4272263508Sdim      S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4273263508Sdim        << SourceRange(loc, loc) << attr.getName() << ExpectedMethodOrProperty;
4274263508Sdim      return;
4275263508Sdim    }
4276263508Sdim    resultType = property->getType();
4277226633Sdim  }
4278263508Sdim  else
4279263508Sdim    // Check that the method returns a normal pointer.
4280263508Sdim    resultType = method->getResultType();
4281226633Sdim
4282226633Sdim  if (!resultType->isReferenceType() &&
4283226633Sdim      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
4284263508Sdim    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4285226633Sdim      << SourceRange(loc)
4286263508Sdim    << attr.getName() << (method ? EP_ObjCMethod : EP_ObjCProperty)
4287263508Sdim    << /*non-retainable pointer*/ 2;
4288226633Sdim
4289226633Sdim    // Drop the attribute.
4290226633Sdim    return;
4291226633Sdim  }
4292226633Sdim
4293263508Sdim  D->addAttr(::new (S.Context)
4294249423Sdim                  ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
4295249423Sdim                                              attr.getAttributeSpellingListIndex()));
4296226633Sdim}
4297226633Sdim
4298243830Sdimstatic void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
4299243830Sdim                                        const AttributeList &attr) {
4300243830Sdim  SourceLocation loc = attr.getLoc();
4301243830Sdim  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
4302243830Sdim
4303243830Sdim  if (!method) {
4304243830Sdim   S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4305243830Sdim   << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
4306243830Sdim    return;
4307243830Sdim  }
4308243830Sdim  DeclContext *DC = method->getDeclContext();
4309243830Sdim  if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
4310243830Sdim    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4311243830Sdim    << attr.getName() << 0;
4312243830Sdim    S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
4313243830Sdim    return;
4314243830Sdim  }
4315243830Sdim  if (method->getMethodFamily() == OMF_dealloc) {
4316243830Sdim    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4317243830Sdim    << attr.getName() << 1;
4318243830Sdim    return;
4319243830Sdim  }
4320243830Sdim
4321249423Sdim  method->addAttr(::new (S.Context)
4322249423Sdim                  ObjCRequiresSuperAttr(attr.getRange(), S.Context,
4323249423Sdim                                        attr.getAttributeSpellingListIndex()));
4324243830Sdim}
4325243830Sdim
4326226633Sdim/// Handle cf_audited_transfer and cf_unknown_transfer.
4327226633Sdimstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
4328226633Sdim  if (!isa<FunctionDecl>(D)) {
4329226633Sdim    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4330234353Sdim      << A.getRange() << A.getName() << ExpectedFunction;
4331226633Sdim    return;
4332226633Sdim  }
4333226633Sdim
4334239462Sdim  bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
4335226633Sdim
4336226633Sdim  // Check whether there's a conflicting attribute already present.
4337226633Sdim  Attr *Existing;
4338226633Sdim  if (IsAudited) {
4339226633Sdim    Existing = D->getAttr<CFUnknownTransferAttr>();
4340226633Sdim  } else {
4341226633Sdim    Existing = D->getAttr<CFAuditedTransferAttr>();
4342226633Sdim  }
4343226633Sdim  if (Existing) {
4344226633Sdim    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
4345226633Sdim      << A.getName()
4346226633Sdim      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
4347226633Sdim      << A.getRange() << Existing->getRange();
4348226633Sdim    return;
4349226633Sdim  }
4350226633Sdim
4351226633Sdim  // All clear;  add the attribute.
4352226633Sdim  if (IsAudited) {
4353249423Sdim    D->addAttr(::new (S.Context)
4354249423Sdim               CFAuditedTransferAttr(A.getRange(), S.Context,
4355249423Sdim                                     A.getAttributeSpellingListIndex()));
4356226633Sdim  } else {
4357249423Sdim    D->addAttr(::new (S.Context)
4358249423Sdim               CFUnknownTransferAttr(A.getRange(), S.Context,
4359249423Sdim                                     A.getAttributeSpellingListIndex()));
4360226633Sdim  }
4361226633Sdim}
4362226633Sdim
4363226633Sdimstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
4364226633Sdim                                const AttributeList &Attr) {
4365226633Sdim  RecordDecl *RD = dyn_cast<RecordDecl>(D);
4366226633Sdim  if (!RD || RD->isUnion()) {
4367226633Sdim    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4368234353Sdim      << Attr.getRange() << Attr.getName() << ExpectedStruct;
4369226633Sdim  }
4370226633Sdim
4371263508Sdim  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
4372226633Sdim
4373226633Sdim  // In Objective-C, verify that the type names an Objective-C type.
4374226633Sdim  // We don't want to check this outside of ObjC because people sometimes
4375226633Sdim  // do crazy C declarations of Objective-C types.
4376263508Sdim  if (Parm && S.getLangOpts().ObjC1) {
4377226633Sdim    // Check for an existing type with this name.
4378263508Sdim    LookupResult R(S, DeclarationName(Parm->Ident), Parm->Loc,
4379226633Sdim                   Sema::LookupOrdinaryName);
4380226633Sdim    if (S.LookupName(R, Sc)) {
4381226633Sdim      NamedDecl *Target = R.getFoundDecl();
4382226633Sdim      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
4383226633Sdim        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
4384226633Sdim        S.Diag(Target->getLocStart(), diag::note_declared_at);
4385226633Sdim      }
4386226633Sdim    }
4387226633Sdim  }
4388226633Sdim
4389249423Sdim  D->addAttr(::new (S.Context)
4390263508Sdim             NSBridgedAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
4391249423Sdim                           Attr.getAttributeSpellingListIndex()));
4392226633Sdim}
4393226633Sdim
4394263508Sdimstatic void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
4395263508Sdim                                const AttributeList &Attr) {
4396263508Sdim  if (!isa<RecordDecl>(D)) {
4397263508Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
4398263508Sdim    << Attr.getName()
4399263508Sdim    << (S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass
4400263508Sdim                                  : ExpectedStructOrUnion);
4401263508Sdim    return;
4402263508Sdim  }
4403263508Sdim
4404263508Sdim  if (Attr.getNumArgs() != 1) {
4405263508Sdim    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
4406263508Sdim    return;
4407263508Sdim  }
4408263508Sdim  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
4409263508Sdim  if (!Parm) {
4410263508Sdim    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
4411263508Sdim    return;
4412263508Sdim  }
4413263508Sdim
4414263508Sdim  D->addAttr(::new (S.Context)
4415263508Sdim             ObjCBridgeAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
4416263508Sdim                           Attr.getAttributeSpellingListIndex()));
4417263508Sdim}
4418263508Sdim
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)
4424234353Sdim    << 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)
4431234353Sdim      << 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)
4470249423Sdim             ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
4471249423Sdim                                     Attr.getAttributeSpellingListIndex()));
4472224145Sdim}
4473224145Sdim
4474193326Sed//===----------------------------------------------------------------------===//
4475218893Sdim// Microsoft specific attribute handlers.
4476218893Sdim//===----------------------------------------------------------------------===//
4477218893Sdim
4478263508Sdim// Check if MS extensions or some other language extensions are enabled.  If
4479263508Sdim// not, issue a diagnostic that the given attribute is unused.
4480263508Sdimstatic bool checkMicrosoftExt(Sema &S, const AttributeList &Attr,
4481263508Sdim                              bool OtherExtension = false) {
4482263508Sdim  if (S.LangOpts.MicrosoftExt || OtherExtension)
4483263508Sdim    return true;
4484263508Sdim  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
4485263508Sdim  return false;
4486263508Sdim}
4487263508Sdim
4488224145Sdimstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4489263508Sdim  if (!checkMicrosoftExt(S, Attr, S.LangOpts.Borland))
4490263508Sdim    return;
4491224145Sdim
4492263508Sdim  StringRef StrRef;
4493263508Sdim  SourceLocation LiteralLoc;
4494263508Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc))
4495263508Sdim    return;
4496218893Sdim
4497263508Sdim  // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
4498263508Sdim  // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
4499263508Sdim  if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
4500263508Sdim    StrRef = StrRef.drop_front().drop_back();
4501218893Sdim
4502263508Sdim  // Validate GUID length.
4503263508Sdim  if (StrRef.size() != 36) {
4504263508Sdim    S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4505263508Sdim    return;
4506263508Sdim  }
4507234353Sdim
4508263508Sdim  for (unsigned i = 0; i < 36; ++i) {
4509263508Sdim    if (i == 8 || i == 13 || i == 18 || i == 23) {
4510263508Sdim      if (StrRef[i] != '-') {
4511263508Sdim        S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4512218893Sdim        return;
4513218893Sdim      }
4514263508Sdim    } else if (!isHexDigit(StrRef[i])) {
4515263508Sdim      S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4516263508Sdim      return;
4517218893Sdim    }
4518263508Sdim  }
4519218893Sdim
4520263508Sdim  D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef,
4521263508Sdim                                        Attr.getAttributeSpellingListIndex()));
4522218893Sdim}
4523218893Sdim
4524239462Sdimstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4525263508Sdim  if (!checkMicrosoftExt(S, Attr))
4526243830Sdim    return;
4527243830Sdim
4528243830Sdim  AttributeList::Kind Kind = Attr.getKind();
4529243830Sdim  if (Kind == AttributeList::AT_SingleInheritance)
4530243830Sdim    D->addAttr(
4531249423Sdim        ::new (S.Context)
4532249423Sdim               SingleInheritanceAttr(Attr.getRange(), S.Context,
4533249423Sdim                                     Attr.getAttributeSpellingListIndex()));
4534243830Sdim  else if (Kind == AttributeList::AT_MultipleInheritance)
4535243830Sdim    D->addAttr(
4536249423Sdim        ::new (S.Context)
4537249423Sdim               MultipleInheritanceAttr(Attr.getRange(), S.Context,
4538249423Sdim                                       Attr.getAttributeSpellingListIndex()));
4539243830Sdim  else if (Kind == AttributeList::AT_VirtualInheritance)
4540243830Sdim    D->addAttr(
4541249423Sdim        ::new (S.Context)
4542249423Sdim               VirtualInheritanceAttr(Attr.getRange(), S.Context,
4543249423Sdim                                      Attr.getAttributeSpellingListIndex()));
4544239462Sdim}
4545239462Sdim
4546239462Sdimstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4547263508Sdim  if (!checkMicrosoftExt(S, Attr))
4548263508Sdim    return;
4549263508Sdim
4550263508Sdim  AttributeList::Kind Kind = Attr.getKind();
4551263508Sdim    if (Kind == AttributeList::AT_Win64)
4552263508Sdim    D->addAttr(
4553263508Sdim        ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
4554263508Sdim                                    Attr.getAttributeSpellingListIndex()));
4555239462Sdim}
4556239462Sdim
4557239462Sdimstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4558263508Sdim  if (!checkMicrosoftExt(S, Attr))
4559263508Sdim    return;
4560263508Sdim  D->addAttr(::new (S.Context)
4561263508Sdim             ForceInlineAttr(Attr.getRange(), S.Context,
4562263508Sdim                             Attr.getAttributeSpellingListIndex()));
4563239462Sdim}
4564239462Sdim
4565263508Sdimstatic void handleSelectAnyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4566263508Sdim  if (!checkMicrosoftExt(S, Attr))
4567263508Sdim    return;
4568263508Sdim  // Check linkage after possibly merging declaratinos.  See
4569263508Sdim  // checkAttributesAfterMerging().
4570263508Sdim  D->addAttr(::new (S.Context)
4571263508Sdim             SelectAnyAttr(Attr.getRange(), S.Context,
4572263508Sdim                           Attr.getAttributeSpellingListIndex()));
4573263508Sdim}
4574263508Sdim
4575263508Sdim/// Handles semantic checking for features that are common to all attributes,
4576263508Sdim/// such as checking whether a parameter was properly specified, or the correct
4577263508Sdim/// number of arguments were passed, etc.
4578263508Sdimstatic bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
4579263508Sdim                                          const AttributeList &Attr) {
4580263508Sdim  // Several attributes carry different semantics than the parsing requires, so
4581263508Sdim  // those are opted out of the common handling.
4582263508Sdim  //
4583263508Sdim  // We also bail on unknown and ignored attributes because those are handled
4584263508Sdim  // as part of the target-specific handling logic.
4585263508Sdim  if (Attr.hasCustomParsing() ||
4586263508Sdim      Attr.getKind() == AttributeList::UnknownAttribute ||
4587263508Sdim      Attr.getKind() == AttributeList::IgnoredAttribute)
4588263508Sdim    return false;
4589263508Sdim
4590263508Sdim  // If there are no optional arguments, then checking for the argument count
4591263508Sdim  // is trivial.
4592263508Sdim  if (Attr.getMinArgs() == Attr.getMaxArgs() &&
4593263508Sdim      !checkAttributeNumArgs(S, Attr, Attr.getMinArgs()))
4594263508Sdim    return true;
4595263508Sdim  return false;
4596263508Sdim}
4597263508Sdim
4598218893Sdim//===----------------------------------------------------------------------===//
4599193326Sed// Top Level Sema Entry Points
4600193326Sed//===----------------------------------------------------------------------===//
4601193326Sed
4602263508Sdim/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
4603263508Sdim/// the attribute applies to decls.  If the attribute is a type attribute, just
4604263508Sdim/// silently ignore it if a GNU attribute.
4605263508Sdimstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
4606263508Sdim                                 const AttributeList &Attr,
4607263508Sdim                                 bool IncludeCXX11Attributes) {
4608263508Sdim  if (Attr.isInvalid())
4609263508Sdim    return;
4610207619Srdivacky
4611263508Sdim  // Ignore C++11 attributes on declarator chunks: they appertain to the type
4612263508Sdim  // instead.
4613263508Sdim  if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
4614263508Sdim    return;
4615263508Sdim
4616263508Sdim  if (handleCommonAttributeFeatures(S, scope, D, Attr))
4617263508Sdim    return;
4618263508Sdim
4619193326Sed  switch (Attr.getKind()) {
4620249423Sdim  case AttributeList::AT_IBAction:    handleIBAction(S, D, Attr); break;
4621249423Sdim  case AttributeList::AT_IBOutlet:    handleIBOutlet(S, D, Attr); break;
4622249423Sdim  case AttributeList::AT_IBOutletCollection:
4623249423Sdim    handleIBOutletCollection(S, D, Attr); break;
4624239462Sdim  case AttributeList::AT_AddressSpace:
4625239462Sdim  case AttributeList::AT_ObjCGC:
4626239462Sdim  case AttributeList::AT_VectorSize:
4627239462Sdim  case AttributeList::AT_NeonVectorType:
4628239462Sdim  case AttributeList::AT_NeonPolyVectorType:
4629263508Sdim  case AttributeList::AT_Ptr32:
4630263508Sdim  case AttributeList::AT_Ptr64:
4631263508Sdim  case AttributeList::AT_SPtr:
4632263508Sdim  case AttributeList::AT_UPtr:
4633198092Srdivacky    // Ignore these, these are type attributes, handled by
4634198092Srdivacky    // ProcessTypeAttributes.
4635193326Sed    break;
4636239462Sdim  case AttributeList::AT_Alias:       handleAliasAttr       (S, D, Attr); break;
4637239462Sdim  case AttributeList::AT_Aligned:     handleAlignedAttr     (S, D, Attr); break;
4638239462Sdim  case AttributeList::AT_AllocSize:   handleAllocSizeAttr   (S, D, Attr); break;
4639239462Sdim  case AttributeList::AT_AlwaysInline:
4640224145Sdim    handleAlwaysInlineAttr  (S, D, Attr); break;
4641239462Sdim  case AttributeList::AT_AnalyzerNoReturn:
4642224145Sdim    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
4643239462Sdim  case AttributeList::AT_TLSModel:    handleTLSModelAttr    (S, D, Attr); break;
4644239462Sdim  case AttributeList::AT_Annotate:    handleAnnotateAttr    (S, D, Attr); break;
4645239462Sdim  case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
4646239462Sdim  case AttributeList::AT_CarriesDependency:
4647249423Sdim    handleDependencyAttr(S, scope, D, Attr);
4648249423Sdim    break;
4649239462Sdim  case AttributeList::AT_Common:      handleCommonAttr      (S, D, Attr); break;
4650239462Sdim  case AttributeList::AT_CUDAConstant:handleConstantAttr    (S, D, Attr); break;
4651239462Sdim  case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
4652249423Sdim  case AttributeList::AT_CXX11NoReturn:
4653249423Sdim    handleCXX11NoReturnAttr(S, D, Attr);
4654249423Sdim    break;
4655239462Sdim  case AttributeList::AT_Deprecated:
4656263508Sdim    handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
4657239462Sdim    break;
4658239462Sdim  case AttributeList::AT_Destructor:  handleDestructorAttr  (S, D, Attr); break;
4659239462Sdim  case AttributeList::AT_ExtVectorType:
4660224145Sdim    handleExtVectorTypeAttr(S, scope, D, Attr);
4661193326Sed    break;
4662243830Sdim  case AttributeList::AT_MinSize:
4663243830Sdim    handleMinSizeAttr(S, D, Attr);
4664243830Sdim    break;
4665239462Sdim  case AttributeList::AT_Format:      handleFormatAttr      (S, D, Attr); break;
4666239462Sdim  case AttributeList::AT_FormatArg:   handleFormatArgAttr   (S, D, Attr); break;
4667239462Sdim  case AttributeList::AT_CUDAGlobal:  handleGlobalAttr      (S, D, Attr); break;
4668263508Sdim  case AttributeList::AT_CUDADevice:  handleDeviceAttr      (S, D, Attr); break;
4669263508Sdim  case AttributeList::AT_CUDAHost:    handleHostAttr        (S, D, Attr); break;
4670239462Sdim  case AttributeList::AT_GNUInline:   handleGNUInlineAttr   (S, D, Attr); break;
4671239462Sdim  case AttributeList::AT_CUDALaunchBounds:
4672224145Sdim    handleLaunchBoundsAttr(S, D, Attr);
4673218893Sdim    break;
4674239462Sdim  case AttributeList::AT_Malloc:      handleMallocAttr      (S, D, Attr); break;
4675239462Sdim  case AttributeList::AT_MayAlias:    handleMayAliasAttr    (S, D, Attr); break;
4676263508Sdim  case AttributeList::AT_Mode:        handleModeAttr        (S, D, Attr); break;
4677239462Sdim  case AttributeList::AT_NoCommon:    handleNoCommonAttr    (S, D, Attr); break;
4678239462Sdim  case AttributeList::AT_NonNull:     handleNonNullAttr     (S, D, Attr); break;
4679263508Sdim  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;
4684239462Sdim  case AttributeList::AT_Cold:        handleColdAttr        (S, D, Attr); break;
4685239462Sdim  case AttributeList::AT_Hot:         handleHotAttr         (S, D, Attr); break;
4686239462Sdim  case AttributeList::AT_Naked:       handleNakedAttr       (S, D, Attr); break;
4687239462Sdim  case AttributeList::AT_NoReturn:    handleNoReturnAttr    (S, D, Attr); break;
4688239462Sdim  case AttributeList::AT_NoThrow:     handleNothrowAttr     (S, D, Attr); break;
4689239462Sdim  case AttributeList::AT_CUDAShared:  handleSharedAttr      (S, D, Attr); break;
4690239462Sdim  case AttributeList::AT_VecReturn:   handleVecReturnAttr   (S, D, Attr); break;
4691193326Sed
4692239462Sdim  case AttributeList::AT_ObjCOwnership:
4693224145Sdim    handleObjCOwnershipAttr(S, D, Attr); break;
4694239462Sdim  case AttributeList::AT_ObjCPreciseLifetime:
4695224145Sdim    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
4696224145Sdim
4697239462Sdim  case AttributeList::AT_ObjCReturnsInnerPointer:
4698226633Sdim    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
4699226633Sdim
4700243830Sdim  case AttributeList::AT_ObjCRequiresSuper:
4701243830Sdim      handleObjCRequiresSuperAttr(S, D, Attr); break;
4702243830Sdim
4703239462Sdim  case AttributeList::AT_NSBridged:
4704226633Sdim    handleNSBridgedAttr(S, scope, D, Attr); break;
4705263508Sdim
4706263508Sdim  case AttributeList::AT_ObjCBridge:
4707263508Sdim    handleObjCBridgeAttr(S, scope, D, Attr); break;
4708226633Sdim
4709239462Sdim  case AttributeList::AT_CFAuditedTransfer:
4710239462Sdim  case AttributeList::AT_CFUnknownTransfer:
4711226633Sdim    handleCFTransferAttr(S, D, Attr); break;
4712226633Sdim
4713193326Sed  // Checker-specific.
4714239462Sdim  case AttributeList::AT_CFConsumed:
4715239462Sdim  case AttributeList::AT_NSConsumed:  handleNSConsumedAttr  (S, D, Attr); break;
4716239462Sdim  case AttributeList::AT_NSConsumesSelf:
4717224145Sdim    handleNSConsumesSelfAttr(S, D, Attr); break;
4718218893Sdim
4719239462Sdim  case AttributeList::AT_NSReturnsAutoreleased:
4720239462Sdim  case AttributeList::AT_NSReturnsNotRetained:
4721239462Sdim  case AttributeList::AT_CFReturnsNotRetained:
4722239462Sdim  case AttributeList::AT_NSReturnsRetained:
4723239462Sdim  case AttributeList::AT_CFReturnsRetained:
4724224145Sdim    handleNSReturnsRetainedAttr(S, D, Attr); break;
4725193326Sed
4726239462Sdim  case AttributeList::AT_WorkGroupSizeHint:
4727239462Sdim  case AttributeList::AT_ReqdWorkGroupSize:
4728239462Sdim    handleWorkGroupSize(S, D, Attr); break;
4729195099Sed
4730249423Sdim  case AttributeList::AT_VecTypeHint:
4731249423Sdim    handleVecTypeHint(S, D, Attr); break;
4732249423Sdim
4733239462Sdim  case AttributeList::AT_InitPriority:
4734224145Sdim      handleInitPriorityAttr(S, D, Attr); break;
4735210299Sed
4736239462Sdim  case AttributeList::AT_Packed:      handlePackedAttr      (S, D, Attr); break;
4737239462Sdim  case AttributeList::AT_Section:     handleSectionAttr     (S, D, Attr); break;
4738239462Sdim  case AttributeList::AT_Unavailable:
4739263508Sdim    handleAttrWithMessage<UnavailableAttr>(S, D, Attr);
4740239462Sdim    break;
4741239462Sdim  case AttributeList::AT_ArcWeakrefUnavailable:
4742224145Sdim    handleArcWeakrefUnavailableAttr (S, D, Attr);
4743193326Sed    break;
4744239462Sdim  case AttributeList::AT_ObjCRootClass:
4745234353Sdim    handleObjCRootClassAttr(S, D, Attr);
4746234353Sdim    break;
4747239462Sdim  case AttributeList::AT_ObjCRequiresPropertyDefs:
4748234353Sdim    handleObjCRequiresPropertyDefsAttr (S, D, Attr);
4749234353Sdim    break;
4750239462Sdim  case AttributeList::AT_Unused:      handleUnusedAttr      (S, D, Attr); break;
4751239462Sdim  case AttributeList::AT_ReturnsTwice:
4752226633Sdim    handleReturnsTwiceAttr(S, D, Attr);
4753226633Sdim    break;
4754239462Sdim  case AttributeList::AT_Used:        handleUsedAttr        (S, D, Attr); break;
4755249423Sdim  case AttributeList::AT_Visibility:
4756249423Sdim    handleVisibilityAttr(S, D, Attr, false);
4757249423Sdim    break;
4758249423Sdim  case AttributeList::AT_TypeVisibility:
4759249423Sdim    handleVisibilityAttr(S, D, Attr, true);
4760249423Sdim    break;
4761263508Sdim  case AttributeList::AT_WarnUnused:
4762263508Sdim    handleWarnUnusedAttr(S, D, Attr);
4763263508Sdim    break;
4764239462Sdim  case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
4765224145Sdim    break;
4766239462Sdim  case AttributeList::AT_Weak:        handleWeakAttr        (S, D, Attr); break;
4767239462Sdim  case AttributeList::AT_WeakRef:     handleWeakRefAttr     (S, D, Attr); break;
4768239462Sdim  case AttributeList::AT_WeakImport:  handleWeakImportAttr  (S, D, Attr); break;
4769239462Sdim  case AttributeList::AT_TransparentUnion:
4770224145Sdim    handleTransparentUnionAttr(S, D, Attr);
4771193326Sed    break;
4772239462Sdim  case AttributeList::AT_ObjCException:
4773224145Sdim    handleObjCExceptionAttr(S, D, Attr);
4774193326Sed    break;
4775239462Sdim  case AttributeList::AT_ObjCMethodFamily:
4776224145Sdim    handleObjCMethodFamilyAttr(S, D, Attr);
4777221345Sdim    break;
4778239462Sdim  case AttributeList::AT_ObjCNSObject:handleObjCNSObject    (S, D, Attr); break;
4779239462Sdim  case AttributeList::AT_Blocks:      handleBlocksAttr      (S, D, Attr); break;
4780239462Sdim  case AttributeList::AT_Sentinel:    handleSentinelAttr    (S, D, Attr); break;
4781239462Sdim  case AttributeList::AT_Const:       handleConstAttr       (S, D, Attr); break;
4782239462Sdim  case AttributeList::AT_Pure:        handlePureAttr        (S, D, Attr); break;
4783239462Sdim  case AttributeList::AT_Cleanup:     handleCleanupAttr     (S, D, Attr); break;
4784239462Sdim  case AttributeList::AT_NoDebug:     handleNoDebugAttr     (S, D, Attr); break;
4785239462Sdim  case AttributeList::AT_NoInline:    handleNoInlineAttr    (S, D, Attr); break;
4786239462Sdim  case AttributeList::AT_Regparm:     handleRegparmAttr     (S, D, Attr); break;
4787198092Srdivacky  case AttributeList::IgnoredAttribute:
4788193326Sed    // Just ignore
4789193326Sed    break;
4790239462Sdim  case AttributeList::AT_NoInstrumentFunction:  // Interacts with -pg.
4791224145Sdim    handleNoInstrumentFunctionAttr(S, D, Attr);
4792210299Sed    break;
4793239462Sdim  case AttributeList::AT_StdCall:
4794239462Sdim  case AttributeList::AT_CDecl:
4795239462Sdim  case AttributeList::AT_FastCall:
4796239462Sdim  case AttributeList::AT_ThisCall:
4797239462Sdim  case AttributeList::AT_Pascal:
4798256030Sdim  case AttributeList::AT_MSABI:
4799256030Sdim  case AttributeList::AT_SysVABI:
4800239462Sdim  case AttributeList::AT_Pcs:
4801243830Sdim  case AttributeList::AT_PnaclCall:
4802249423Sdim  case AttributeList::AT_IntelOclBicc:
4803224145Sdim    handleCallConvAttr(S, D, Attr);
4804203955Srdivacky    break;
4805239462Sdim  case AttributeList::AT_OpenCLKernel:
4806224145Sdim    handleOpenCLKernelAttr(S, D, Attr);
4807218893Sdim    break;
4808249423Sdim  case AttributeList::AT_OpenCLImageAccess:
4809249423Sdim    handleOpenCLImageAccessAttr(S, D, Attr);
4810249423Sdim    break;
4811239462Sdim
4812239462Sdim  // Microsoft attributes:
4813239462Sdim  case AttributeList::AT_MsStruct:
4814239462Sdim    handleMsStructAttr(S, D, Attr);
4815239462Sdim    break;
4816239462Sdim  case AttributeList::AT_Uuid:
4817224145Sdim    handleUuidAttr(S, D, Attr);
4818218893Sdim    break;
4819239462Sdim  case AttributeList::AT_SingleInheritance:
4820239462Sdim  case AttributeList::AT_MultipleInheritance:
4821239462Sdim  case AttributeList::AT_VirtualInheritance:
4822239462Sdim    handleInheritanceAttr(S, D, Attr);
4823239462Sdim    break;
4824239462Sdim  case AttributeList::AT_Win64:
4825239462Sdim    handlePortabilityAttr(S, D, Attr);
4826239462Sdim    break;
4827239462Sdim  case AttributeList::AT_ForceInline:
4828239462Sdim    handleForceInlineAttr(S, D, Attr);
4829239462Sdim    break;
4830263508Sdim  case AttributeList::AT_SelectAny:
4831263508Sdim    handleSelectAnyAttr(S, D, Attr);
4832263508Sdim    break;
4833226633Sdim
4834226633Sdim  // Thread safety attributes:
4835263508Sdim  case AttributeList::AT_AssertExclusiveLock:
4836263508Sdim    handleAssertExclusiveLockAttr(S, D, Attr);
4837263508Sdim    break;
4838263508Sdim  case AttributeList::AT_AssertSharedLock:
4839263508Sdim    handleAssertSharedLockAttr(S, D, Attr);
4840263508Sdim    break;
4841239462Sdim  case AttributeList::AT_GuardedVar:
4842226633Sdim    handleGuardedVarAttr(S, D, Attr);
4843226633Sdim    break;
4844239462Sdim  case AttributeList::AT_PtGuardedVar:
4845239462Sdim    handlePtGuardedVarAttr(S, D, Attr);
4846226633Sdim    break;
4847239462Sdim  case AttributeList::AT_ScopedLockable:
4848239462Sdim    handleScopedLockableAttr(S, D, Attr);
4849226633Sdim    break;
4850249423Sdim  case AttributeList::AT_NoSanitizeAddress:
4851249423Sdim    handleNoSanitizeAddressAttr(S, D, Attr);
4852234353Sdim    break;
4853239462Sdim  case AttributeList::AT_NoThreadSafetyAnalysis:
4854249423Sdim    handleNoThreadSafetyAnalysis(S, D, Attr);
4855226633Sdim    break;
4856249423Sdim  case AttributeList::AT_NoSanitizeThread:
4857249423Sdim    handleNoSanitizeThread(S, D, Attr);
4858249423Sdim    break;
4859249423Sdim  case AttributeList::AT_NoSanitizeMemory:
4860249423Sdim    handleNoSanitizeMemory(S, D, Attr);
4861249423Sdim    break;
4862239462Sdim  case AttributeList::AT_Lockable:
4863226633Sdim    handleLockableAttr(S, D, Attr);
4864226633Sdim    break;
4865239462Sdim  case AttributeList::AT_GuardedBy:
4866226633Sdim    handleGuardedByAttr(S, D, Attr);
4867226633Sdim    break;
4868239462Sdim  case AttributeList::AT_PtGuardedBy:
4869239462Sdim    handlePtGuardedByAttr(S, D, Attr);
4870226633Sdim    break;
4871239462Sdim  case AttributeList::AT_ExclusiveLockFunction:
4872239462Sdim    handleExclusiveLockFunctionAttr(S, D, Attr);
4873226633Sdim    break;
4874239462Sdim  case AttributeList::AT_ExclusiveLocksRequired:
4875239462Sdim    handleExclusiveLocksRequiredAttr(S, D, Attr);
4876226633Sdim    break;
4877239462Sdim  case AttributeList::AT_ExclusiveTrylockFunction:
4878239462Sdim    handleExclusiveTrylockFunctionAttr(S, D, Attr);
4879226633Sdim    break;
4880239462Sdim  case AttributeList::AT_LockReturned:
4881226633Sdim    handleLockReturnedAttr(S, D, Attr);
4882226633Sdim    break;
4883239462Sdim  case AttributeList::AT_LocksExcluded:
4884226633Sdim    handleLocksExcludedAttr(S, D, Attr);
4885226633Sdim    break;
4886239462Sdim  case AttributeList::AT_SharedLockFunction:
4887239462Sdim    handleSharedLockFunctionAttr(S, D, Attr);
4888226633Sdim    break;
4889239462Sdim  case AttributeList::AT_SharedLocksRequired:
4890239462Sdim    handleSharedLocksRequiredAttr(S, D, Attr);
4891226633Sdim    break;
4892239462Sdim  case AttributeList::AT_SharedTrylockFunction:
4893239462Sdim    handleSharedTrylockFunctionAttr(S, D, Attr);
4894226633Sdim    break;
4895239462Sdim  case AttributeList::AT_UnlockFunction:
4896226633Sdim    handleUnlockFunAttr(S, D, Attr);
4897226633Sdim    break;
4898239462Sdim  case AttributeList::AT_AcquiredBefore:
4899239462Sdim    handleAcquiredBeforeAttr(S, D, Attr);
4900226633Sdim    break;
4901239462Sdim  case AttributeList::AT_AcquiredAfter:
4902239462Sdim    handleAcquiredAfterAttr(S, D, Attr);
4903226633Sdim    break;
4904226633Sdim
4905263508Sdim  // Consumed analysis attributes.
4906263508Sdim  case AttributeList::AT_Consumable:
4907263508Sdim    handleConsumableAttr(S, D, Attr);
4908263508Sdim    break;
4909263508Sdim  case AttributeList::AT_CallableWhen:
4910263508Sdim    handleCallableWhenAttr(S, D, Attr);
4911263508Sdim    break;
4912263508Sdim  case AttributeList::AT_ParamTypestate:
4913263508Sdim    handleParamTypestateAttr(S, D, Attr);
4914263508Sdim    break;
4915263508Sdim  case AttributeList::AT_ReturnTypestate:
4916263508Sdim    handleReturnTypestateAttr(S, D, Attr);
4917263508Sdim    break;
4918263508Sdim  case AttributeList::AT_SetTypestate:
4919263508Sdim    handleSetTypestateAttr(S, D, Attr);
4920263508Sdim    break;
4921263508Sdim  case AttributeList::AT_TestTypestate:
4922263508Sdim    handleTestTypestateAttr(S, D, Attr);
4923263508Sdim    break;
4924263508Sdim
4925239462Sdim  // Type safety attributes.
4926239462Sdim  case AttributeList::AT_ArgumentWithTypeTag:
4927239462Sdim    handleArgumentWithTypeTagAttr(S, D, Attr);
4928239462Sdim    break;
4929239462Sdim  case AttributeList::AT_TypeTagForDatatype:
4930239462Sdim    handleTypeTagForDatatypeAttr(S, D, Attr);
4931239462Sdim    break;
4932239462Sdim
4933193326Sed  default:
4934202379Srdivacky    // Ask target about the attribute.
4935202379Srdivacky    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
4936202379Srdivacky    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
4937239462Sdim      S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
4938239462Sdim             diag::warn_unhandled_ms_attribute_ignored :
4939239462Sdim             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,
4948249423Sdim                                    bool IncludeCXX11Attributes) {
4949249423Sdim  for (const AttributeList* l = AttrList; l; l = l->getNext())
4950263508Sdim    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.
4955263508Sdim  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
4956204643Srdivacky    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
4957249423Sdim    cast<NamedDecl>(D)->getNameAsString();
4958249423Sdim    D->dropAttr<WeakRefAttr>();
4959204643Srdivacky    return;
4960204643Srdivacky  }
4961193326Sed}
4962193326Sed
4963226633Sdim// Annotation attributes are the only attributes allowed after an access
4964226633Sdim// specifier.
4965226633Sdimbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
4966226633Sdim                                          const AttributeList *AttrList) {
4967226633Sdim  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
4968239462Sdim    if (l->getKind() == AttributeList::AT_Annotate) {
4969226633Sdim      handleAnnotateAttr(*this, ASDecl, *l);
4970226633Sdim    } else {
4971226633Sdim      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
4972226633Sdim      return true;
4973226633Sdim    }
4974226633Sdim  }
4975226633Sdim
4976226633Sdim  return false;
4977226633Sdim}
4978226633Sdim
4979226633Sdim/// checkUnusedDeclAttributes - Check a list of attributes to see if it
4980226633Sdim/// contains any decl attributes that we should warn about.
4981226633Sdimstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
4982226633Sdim  for ( ; A; A = A->getNext()) {
4983226633Sdim    // Only warn if the attribute is an unignored, non-type attribute.
4984249423Sdim    if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
4985226633Sdim    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
4986226633Sdim
4987226633Sdim    if (A->getKind() == AttributeList::UnknownAttribute) {
4988226633Sdim      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
4989226633Sdim        << A->getName() << A->getRange();
4990226633Sdim    } else {
4991226633Sdim      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
4992226633Sdim        << A->getName() << A->getRange();
4993226633Sdim    }
4994226633Sdim  }
4995226633Sdim}
4996226633Sdim
4997226633Sdim/// checkUnusedDeclAttributes - Given a declarator which is not being
4998226633Sdim/// used to build a declaration, complain about any decl attributes
4999226633Sdim/// which might be lying around on it.
5000226633Sdimvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
5001226633Sdim  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
5002226633Sdim  ::checkUnusedDeclAttributes(*this, D.getAttributes());
5003226633Sdim  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
5004226633Sdim    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
5005226633Sdim}
5006226633Sdim
5007198092Srdivacky/// DeclClonePragmaWeak - clone existing decl (maybe definition),
5008239462Sdim/// \#pragma weak needs a non-definition decl and source may not have one.
5009226633SdimNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
5010226633Sdim                                      SourceLocation Loc) {
5011198092Srdivacky  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
5012198092Srdivacky  NamedDecl *NewD = 0;
5013198092Srdivacky  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
5014226633Sdim    FunctionDecl *NewFD;
5015226633Sdim    // FIXME: Missing call to CheckFunctionDeclaration().
5016226633Sdim    // FIXME: Mangling?
5017226633Sdim    // FIXME: Is the qualifier info correct?
5018226633Sdim    // FIXME: Is the DeclContext correct?
5019226633Sdim    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
5020226633Sdim                                 Loc, Loc, DeclarationName(II),
5021226633Sdim                                 FD->getType(), FD->getTypeSourceInfo(),
5022249423Sdim                                 SC_None, false/*isInlineSpecified*/,
5023226633Sdim                                 FD->hasPrototype(),
5024226633Sdim                                 false/*isConstexprSpecified*/);
5025226633Sdim    NewD = NewFD;
5026226633Sdim
5027226633Sdim    if (FD->getQualifier())
5028219077Sdim      NewFD->setQualifierInfo(FD->getQualifierLoc());
5029226633Sdim
5030226633Sdim    // Fake up parameter variables; they are declared as if this were
5031226633Sdim    // a typedef.
5032226633Sdim    QualType FDTy = FD->getType();
5033226633Sdim    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
5034226633Sdim      SmallVector<ParmVarDecl*, 16> Params;
5035226633Sdim      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
5036226633Sdim           AE = FT->arg_type_end(); AI != AE; ++AI) {
5037226633Sdim        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
5038226633Sdim        Param->setScopeInfo(0, Params.size());
5039226633Sdim        Params.push_back(Param);
5040226633Sdim      }
5041226633Sdim      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(),
5047249423Sdim                           VD->getStorageClass());
5048205219Srdivacky    if (VD->getQualifier()) {
5049205219Srdivacky      VarDecl *NewVD = cast<VarDecl>(NewD);
5050219077Sdim      NewVD->setQualifierInfo(VD->getQualifierLoc());
5051205219Srdivacky    }
5052198092Srdivacky  }
5053198092Srdivacky  return NewD;
5054198092Srdivacky}
5055198092Srdivacky
5056239462Sdim/// 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();
5063226633Sdim    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
5079249423Sdimvoid Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
5080218893Sdim  // It's valid to "forward-declare" #pragma weak, in which case we
5081218893Sdim  // have to do this.
5082249423Sdim  LoadExternalWeakUndeclaredIdentifiers();
5083249423Sdim  if (!WeakUndeclaredIdentifiers.empty()) {
5084249423Sdim    NamedDecl *ND = NULL;
5085249423Sdim    if (VarDecl *VD = dyn_cast<VarDecl>(D))
5086249423Sdim      if (VD->isExternC())
5087249423Sdim        ND = VD;
5088249423Sdim    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5089249423Sdim      if (FD->isExternC())
5090249423Sdim        ND = FD;
5091249423Sdim    if (ND) {
5092249423Sdim      if (IdentifierInfo *Id = ND->getIdentifier()) {
5093249423Sdim        llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I
5094249423Sdim          = WeakUndeclaredIdentifiers.find(Id);
5095249423Sdim        if (I != WeakUndeclaredIdentifiers.end()) {
5096249423Sdim          WeakInfo W = I->second;
5097249423Sdim          DeclApplyPragmaWeak(S, ND, W);
5098249423Sdim          WeakUndeclaredIdentifiers[Id] = W;
5099218893Sdim        }
5100198092Srdivacky      }
5101198092Srdivacky    }
5102198092Srdivacky  }
5103249423Sdim}
5104198092Srdivacky
5105249423Sdim/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
5106249423Sdim/// it, apply them to D.  This is a bit tricky because PD can have attributes
5107249423Sdim/// specified in many different places, and we need to find and apply them all.
5108263508Sdimvoid 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())
5111263508Sdim    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())
5119263508Sdim      ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false);
5120198092Srdivacky
5121193326Sed  // Finally, apply any attributes on the decl itself.
5122193326Sed  if (const AttributeList *Attrs = PD.getAttributes())
5123263508Sdim    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.
5131226633Sdim  // Function declarations in sys headers will be marked unavailable.
5132226633Sdim  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
5133226633Sdim      !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  }
5148234353Sdim  if (S.getLangOpts().ObjCAutoRefCount)
5149226633Sdim    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
5150239462Sdim      // FIXME: we may want to suppress diagnostics for all
5151226633Sdim      // kind of forbidden type messages on unavailable functions.
5152226633Sdim      if (FD->hasAttr<UnavailableAttr>() &&
5153226633Sdim          diag.getForbiddenTypeDiagnostic() ==
5154226633Sdim          diag::err_arc_array_param_no_ownership) {
5155226633Sdim        diag.Triggered = true;
5156226633Sdim        return;
5157226633Sdim      }
5158226633Sdim    }
5159224145Sdim
5160224145Sdim  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
5161224145Sdim    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
5162224145Sdim  diag.Triggered = true;
5163224145Sdim}
5164224145Sdim
5165239462Sdimvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
5166239462Sdim  assert(DelayedDiagnostics.getCurrentPool());
5167239462Sdim  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
5168239462Sdim  DelayedDiagnostics.popWithoutEmitting(state);
5169218893Sdim
5170239462Sdim  // When delaying diagnostics to run in the context of a parsed
5171239462Sdim  // declaration, we only want to actually emit anything if parsing
5172239462Sdim  // succeeds.
5173239462Sdim  if (!decl) return;
5174218893Sdim
5175239462Sdim  // We emit all the active diagnostics in this pool or any of its
5176239462Sdim  // parents.  In general, we'll get one pool for the decl spec
5177239462Sdim  // and a child pool for each declarator; in a decl group like:
5178239462Sdim  //   deprecated_typedef foo, *bar, baz();
5179239462Sdim  // only the declarator pops will be passed decls.  This is correct;
5180239462Sdim  // we really do need to consider delayed diagnostics from the decl spec
5181239462Sdim  // for each of the different declarations.
5182239462Sdim  const DelayedDiagnosticPool *pool = &poppedPool;
5183239462Sdim  do {
5184239462Sdim    for (DelayedDiagnosticPool::pool_iterator
5185239462Sdim           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
5186239462Sdim      // This const_cast is a bit lame.  Really, Triggered should be mutable.
5187239462Sdim      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
5188218893Sdim      if (diag.Triggered)
5189203955Srdivacky        continue;
5190198893Srdivacky
5191218893Sdim      switch (diag.Kind) {
5192203955Srdivacky      case DelayedDiagnostic::Deprecation:
5193234353Sdim        // Don't bother giving deprecation diagnostics if the decl is invalid.
5194234353Sdim        if (!decl->isInvalidDecl())
5195239462Sdim          HandleDelayedDeprecationCheck(diag, decl);
5196203955Srdivacky        break;
5197203955Srdivacky
5198203955Srdivacky      case DelayedDiagnostic::Access:
5199239462Sdim        HandleDelayedAccessCheck(diag, decl);
5200203955Srdivacky        break;
5201224145Sdim
5202224145Sdim      case DelayedDiagnostic::ForbiddenType:
5203239462Sdim        handleDelayedForbiddenType(*this, diag, decl);
5204224145Sdim        break;
5205198893Srdivacky      }
5206198893Srdivacky    }
5207239462Sdim  } while ((pool = pool->getParent()));
5208239462Sdim}
5209198893Srdivacky
5210239462Sdim/// Given a set of delayed diagnostics, re-emit them as if they had
5211239462Sdim/// been delayed in the current context instead of in the given pool.
5212239462Sdim/// Essentially, this just moves them to the current pool.
5213239462Sdimvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
5214239462Sdim  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
5215239462Sdim  assert(curPool && "re-emitting in undelayed context not supported");
5216239462Sdim  curPool->steal(pool);
5217198893Srdivacky}
5218198893Srdivacky
5219203955Srdivackystatic bool isDeclDeprecated(Decl *D) {
5220203955Srdivacky  do {
5221221345Sdim    if (D->isDeprecated())
5222203955Srdivacky      return true;
5223226633Sdim    // A category implicitly has the availability of the interface.
5224226633Sdim    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
5225226633Sdim      return CatD->getClassInterface()->isDeprecated();
5226203955Srdivacky  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
5227203955Srdivacky  return false;
5228203955Srdivacky}
5229203955Srdivacky
5230239462Sdimstatic void
5231239462SdimDoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
5232239462Sdim                         SourceLocation Loc,
5233243830Sdim                         const ObjCInterfaceDecl *UnknownObjCClass,
5234243830Sdim                         const ObjCPropertyDecl *ObjCPropery) {
5235239462Sdim  DeclarationName Name = D->getDeclName();
5236239462Sdim  if (!Message.empty()) {
5237239462Sdim    S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
5238239462Sdim    S.Diag(D->getLocation(),
5239239462Sdim           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5240239462Sdim                                  : diag::note_previous_decl) << Name;
5241243830Sdim    if (ObjCPropery)
5242243830Sdim      S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5243243830Sdim        << ObjCPropery->getDeclName() << 0;
5244239462Sdim  } else if (!UnknownObjCClass) {
5245239462Sdim    S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
5246239462Sdim    S.Diag(D->getLocation(),
5247239462Sdim           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
5248239462Sdim                                  : diag::note_previous_decl) << Name;
5249243830Sdim    if (ObjCPropery)
5250243830Sdim      S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
5251243830Sdim        << ObjCPropery->getDeclName() << 0;
5252239462Sdim  } else {
5253239462Sdim    S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
5254239462Sdim    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
5255239462Sdim  }
5256239462Sdim}
5257239462Sdim
5258212904Sdimvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
5259203955Srdivacky                                         Decl *Ctx) {
5260203955Srdivacky  if (isDeclDeprecated(Ctx))
5261203955Srdivacky    return;
5262203955Srdivacky
5263203955Srdivacky  DD.Triggered = true;
5264239462Sdim  DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
5265239462Sdim                           DD.getDeprecationMessage(), DD.Loc,
5266243830Sdim                           DD.getUnknownObjCClass(),
5267243830Sdim                           DD.getObjCProperty());
5268203955Srdivacky}
5269203955Srdivacky
5270226633Sdimvoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
5271218893Sdim                                  SourceLocation Loc,
5272243830Sdim                                  const ObjCInterfaceDecl *UnknownObjCClass,
5273243830Sdim                                  const ObjCPropertyDecl  *ObjCProperty) {
5274198893Srdivacky  // Delay if we're currently parsing a declaration.
5275218893Sdim  if (DelayedDiagnostics.shouldDelayDiagnostics()) {
5276234353Sdim    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
5277234353Sdim                                                              UnknownObjCClass,
5278243830Sdim                                                              ObjCProperty,
5279234353Sdim                                                              Message));
5280198893Srdivacky    return;
5281198893Srdivacky  }
5282198893Srdivacky
5283198893Srdivacky  // Otherwise, don't warn if our current context is deprecated.
5284226633Sdim  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
5285198893Srdivacky    return;
5286243830Sdim  DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty);
5287198893Srdivacky}
5288