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"
15193326Sed#include "clang/AST/ASTContext.h"
16239462Sdim#include "clang/AST/CXXInheritance.h"
17212904Sdim#include "clang/AST/DeclCXX.h"
18249423Sdim#include "clang/AST/DeclObjC.h"
19226633Sdim#include "clang/AST/DeclTemplate.h"
20193326Sed#include "clang/AST/Expr.h"
21276479Sdim#include "clang/AST/ExprCXX.h"
22249423Sdim#include "clang/AST/Mangle.h"
23288943Sdim#include "clang/AST/ASTMutationListener.h"
24249423Sdim#include "clang/Basic/CharInfo.h"
25224145Sdim#include "clang/Basic/SourceManager.h"
26193326Sed#include "clang/Basic/TargetInfo.h"
27261991Sdim#include "clang/Lex/Preprocessor.h"
28212904Sdim#include "clang/Sema/DeclSpec.h"
29212904Sdim#include "clang/Sema/DelayedDiagnostic.h"
30226633Sdim#include "clang/Sema/Lookup.h"
31249423Sdim#include "clang/Sema/Scope.h"
32198092Srdivacky#include "llvm/ADT/StringExtras.h"
33280031Sdim#include "llvm/Support/MathExtras.h"
34193326Sedusing namespace clang;
35212904Sdimusing namespace sema;
36193326Sed
37276479Sdimnamespace AttributeLangSupport {
38276479Sdim  enum LANG {
39276479Sdim    C,
40276479Sdim    Cpp,
41276479Sdim    ObjC
42276479Sdim  };
43276479Sdim}
44221345Sdim
45193326Sed//===----------------------------------------------------------------------===//
46193326Sed//  Helper functions
47193326Sed//===----------------------------------------------------------------------===//
48193326Sed
49198092Srdivacky/// isFunctionOrMethod - Return true if the given decl has function
50193326Sed/// type (function or function-typed variable) or an Objective-C
51193326Sed/// method.
52224145Sdimstatic bool isFunctionOrMethod(const Decl *D) {
53276479Sdim  return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D);
54193326Sed}
55288943Sdim/// \brief Return true if the given decl has function type (function or
56288943Sdim/// function-typed variable) or an Objective-C method or a block.
57288943Sdimstatic bool isFunctionOrMethodOrBlock(const Decl *D) {
58288943Sdim  return isFunctionOrMethod(D) || isa<BlockDecl>(D);
59288943Sdim}
60193326Sed
61218893Sdim/// Return true if the given decl has a declarator that should have
62218893Sdim/// been processed by Sema::GetTypeForDeclarator.
63224145Sdimstatic bool hasDeclarator(const Decl *D) {
64224145Sdim  // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
65224145Sdim  return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
66224145Sdim         isa<ObjCPropertyDecl>(D);
67218893Sdim}
68218893Sdim
69193326Sed/// hasFunctionProto - Return true if the given decl has a argument
70193326Sed/// information. This decl should have already passed
71193326Sed/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
72224145Sdimstatic bool hasFunctionProto(const Decl *D) {
73276479Sdim  if (const FunctionType *FnTy = D->getFunctionType())
74193326Sed    return isa<FunctionProtoType>(FnTy);
75276479Sdim  return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
76193326Sed}
77193326Sed
78276479Sdim/// getFunctionOrMethodNumParams - Return number of function or method
79276479Sdim/// parameters. It is an error to call this on a K&R function (use
80193326Sed/// hasFunctionProto first).
81276479Sdimstatic unsigned getFunctionOrMethodNumParams(const Decl *D) {
82276479Sdim  if (const FunctionType *FnTy = D->getFunctionType())
83276479Sdim    return cast<FunctionProtoType>(FnTy)->getNumParams();
84224145Sdim  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
85193326Sed    return BD->getNumParams();
86224145Sdim  return cast<ObjCMethodDecl>(D)->param_size();
87193326Sed}
88193326Sed
89276479Sdimstatic QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
90276479Sdim  if (const FunctionType *FnTy = D->getFunctionType())
91276479Sdim    return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
92224145Sdim  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
93193326Sed    return BD->getParamDecl(Idx)->getType();
94198092Srdivacky
95276479Sdim  return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
96193326Sed}
97193326Sed
98280031Sdimstatic SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
99280031Sdim  if (const auto *FD = dyn_cast<FunctionDecl>(D))
100280031Sdim    return FD->getParamDecl(Idx)->getSourceRange();
101280031Sdim  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
102280031Sdim    return MD->parameters()[Idx]->getSourceRange();
103280031Sdim  if (const auto *BD = dyn_cast<BlockDecl>(D))
104280031Sdim    return BD->getParamDecl(Idx)->getSourceRange();
105280031Sdim  return SourceRange();
106280031Sdim}
107280031Sdim
108224145Sdimstatic QualType getFunctionOrMethodResultType(const Decl *D) {
109276479Sdim  if (const FunctionType *FnTy = D->getFunctionType())
110276479Sdim    return cast<FunctionType>(FnTy)->getReturnType();
111276479Sdim  return cast<ObjCMethodDecl>(D)->getReturnType();
112193326Sed}
113193326Sed
114280031Sdimstatic SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
115280031Sdim  if (const auto *FD = dyn_cast<FunctionDecl>(D))
116280031Sdim    return FD->getReturnTypeSourceRange();
117280031Sdim  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
118280031Sdim    return MD->getReturnTypeSourceRange();
119280031Sdim  return SourceRange();
120280031Sdim}
121280031Sdim
122224145Sdimstatic bool isFunctionOrMethodVariadic(const Decl *D) {
123276479Sdim  if (const FunctionType *FnTy = D->getFunctionType()) {
124193326Sed    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
125193326Sed    return proto->isVariadic();
126280031Sdim  }
127280031Sdim  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
128207619Srdivacky    return BD->isVariadic();
129280031Sdim
130280031Sdim  return cast<ObjCMethodDecl>(D)->isVariadic();
131193326Sed}
132193326Sed
133224145Sdimstatic bool isInstanceMethod(const Decl *D) {
134224145Sdim  if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D))
135218893Sdim    return MethodDecl->isInstance();
136218893Sdim  return false;
137218893Sdim}
138218893Sdim
139193326Sedstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
140198092Srdivacky  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
141193326Sed  if (!PT)
142193326Sed    return false;
143198092Srdivacky
144208600Srdivacky  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
145208600Srdivacky  if (!Cls)
146193326Sed    return false;
147198092Srdivacky
148208600Srdivacky  IdentifierInfo* ClsName = Cls->getIdentifier();
149198092Srdivacky
150193326Sed  // FIXME: Should we walk the chain of classes?
151193326Sed  return ClsName == &Ctx.Idents.get("NSString") ||
152193326Sed         ClsName == &Ctx.Idents.get("NSMutableString");
153193326Sed}
154193326Sed
155193326Sedstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
156198092Srdivacky  const PointerType *PT = T->getAs<PointerType>();
157193326Sed  if (!PT)
158193326Sed    return false;
159193326Sed
160198092Srdivacky  const RecordType *RT = PT->getPointeeType()->getAs<RecordType>();
161193326Sed  if (!RT)
162193326Sed    return false;
163198092Srdivacky
164193326Sed  const RecordDecl *RD = RT->getDecl();
165208600Srdivacky  if (RD->getTagKind() != TTK_Struct)
166193326Sed    return false;
167193326Sed
168193326Sed  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
169193326Sed}
170193326Sed
171261991Sdimstatic unsigned getNumAttributeArgs(const AttributeList &Attr) {
172261991Sdim  // FIXME: Include the type in the argument list.
173261991Sdim  return Attr.getNumArgs() + Attr.hasParsedType();
174261991Sdim}
175261991Sdim
176280031Sdimtemplate <typename Compare>
177280031Sdimstatic bool checkAttributeNumArgsImpl(Sema &S, const AttributeList &Attr,
178280031Sdim                                      unsigned Num, unsigned Diag,
179280031Sdim                                      Compare Comp) {
180280031Sdim  if (Comp(getNumAttributeArgs(Attr), Num)) {
181280031Sdim    S.Diag(Attr.getLoc(), Diag) << Attr.getName() << Num;
182224145Sdim    return false;
183224145Sdim  }
184224145Sdim
185224145Sdim  return true;
186224145Sdim}
187224145Sdim
188280031Sdim/// \brief Check if the attribute has exactly as many args as Num. May
189280031Sdim/// output an error.
190280031Sdimstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
191280031Sdim                                  unsigned Num) {
192280031Sdim  return checkAttributeNumArgsImpl(S, Attr, Num,
193280031Sdim                                   diag::err_attribute_wrong_number_arguments,
194280031Sdim                                   std::not_equal_to<unsigned>());
195280031Sdim}
196280031Sdim
197226633Sdim/// \brief Check if the attribute has at least as many args as Num. May
198226633Sdim/// output an error.
199226633Sdimstatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
200261991Sdim                                         unsigned Num) {
201280031Sdim  return checkAttributeNumArgsImpl(S, Attr, Num,
202280031Sdim                                   diag::err_attribute_too_few_arguments,
203280031Sdim                                   std::less<unsigned>());
204280031Sdim}
205226633Sdim
206280031Sdim/// \brief Check if the attribute has at most as many args as Num. May
207280031Sdim/// output an error.
208280031Sdimstatic bool checkAttributeAtMostNumArgs(Sema &S, const AttributeList &Attr,
209280031Sdim                                         unsigned Num) {
210280031Sdim  return checkAttributeNumArgsImpl(S, Attr, Num,
211280031Sdim                                   diag::err_attribute_too_many_arguments,
212280031Sdim                                   std::greater<unsigned>());
213226633Sdim}
214226633Sdim
215276479Sdim/// \brief If Expr is a valid integer constant, get the value of the integer
216276479Sdim/// expression and return success or failure. May output an error.
217276479Sdimstatic bool checkUInt32Argument(Sema &S, const AttributeList &Attr,
218276479Sdim                                const Expr *Expr, uint32_t &Val,
219276479Sdim                                unsigned Idx = UINT_MAX) {
220276479Sdim  llvm::APSInt I(32);
221276479Sdim  if (Expr->isTypeDependent() || Expr->isValueDependent() ||
222276479Sdim      !Expr->isIntegerConstantExpr(I, S.Context)) {
223276479Sdim    if (Idx != UINT_MAX)
224276479Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
225276479Sdim        << Attr.getName() << Idx << AANT_ArgumentIntegerConstant
226276479Sdim        << Expr->getSourceRange();
227276479Sdim    else
228276479Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
229276479Sdim        << Attr.getName() << AANT_ArgumentIntegerConstant
230276479Sdim        << Expr->getSourceRange();
231276479Sdim    return false;
232276479Sdim  }
233280031Sdim
234280031Sdim  if (!I.isIntN(32)) {
235280031Sdim    S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
236280031Sdim        << I.toString(10, false) << 32 << /* Unsigned */ 1;
237280031Sdim    return false;
238280031Sdim  }
239280031Sdim
240276479Sdim  Val = (uint32_t)I.getZExtValue();
241276479Sdim  return true;
242276479Sdim}
243276479Sdim
244276479Sdim/// \brief Diagnose mutually exclusive attributes when present on a given
245276479Sdim/// declaration. Returns true if diagnosed.
246276479Sdimtemplate <typename AttrTy>
247296417Sdimstatic bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range,
248296417Sdim                                     IdentifierInfo *Ident) {
249276479Sdim  if (AttrTy *A = D->getAttr<AttrTy>()) {
250296417Sdim    S.Diag(Range.getBegin(), diag::err_attributes_are_not_compatible) << Ident
251296417Sdim                                                                      << A;
252296417Sdim    S.Diag(A->getLocation(), diag::note_conflicting_attribute);
253276479Sdim    return true;
254276479Sdim  }
255276479Sdim  return false;
256276479Sdim}
257276479Sdim
258276479Sdim/// \brief Check if IdxExpr is a valid parameter index for a function or
259239462Sdim/// instance method D.  May output an error.
260226633Sdim///
261239462Sdim/// \returns true if IdxExpr is a valid index.
262276479Sdimstatic bool checkFunctionOrMethodParameterIndex(Sema &S, const Decl *D,
263276479Sdim                                                const AttributeList &Attr,
264276479Sdim                                                unsigned AttrArgNum,
265276479Sdim                                                const Expr *IdxExpr,
266276479Sdim                                                uint64_t &Idx) {
267288943Sdim  assert(isFunctionOrMethodOrBlock(D));
268239462Sdim
269239462Sdim  // In C++ the implicit 'this' function parameter also counts.
270239462Sdim  // Parameters are counted from one.
271261991Sdim  bool HP = hasFunctionProto(D);
272261991Sdim  bool HasImplicitThisParam = isInstanceMethod(D);
273261991Sdim  bool IV = HP && isFunctionOrMethodVariadic(D);
274276479Sdim  unsigned NumParams =
275276479Sdim      (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
276239462Sdim
277239462Sdim  llvm::APSInt IdxInt;
278239462Sdim  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
279239462Sdim      !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
280276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
281276479Sdim      << Attr.getName() << AttrArgNum << AANT_ArgumentIntegerConstant
282276479Sdim      << IdxExpr->getSourceRange();
283239462Sdim    return false;
284239462Sdim  }
285239462Sdim
286239462Sdim  Idx = IdxInt.getLimitedValue();
287276479Sdim  if (Idx < 1 || (!IV && Idx > NumParams)) {
288276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
289276479Sdim      << Attr.getName() << AttrArgNum << IdxExpr->getSourceRange();
290239462Sdim    return false;
291239462Sdim  }
292239462Sdim  Idx--; // Convert to zero-based.
293239462Sdim  if (HasImplicitThisParam) {
294239462Sdim    if (Idx == 0) {
295276479Sdim      S.Diag(Attr.getLoc(),
296239462Sdim             diag::err_attribute_invalid_implicit_this_argument)
297276479Sdim        << Attr.getName() << IdxExpr->getSourceRange();
298239462Sdim      return false;
299239462Sdim    }
300239462Sdim    --Idx;
301239462Sdim  }
302239462Sdim
303239462Sdim  return true;
304239462Sdim}
305239462Sdim
306261991Sdim/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
307261991Sdim/// If not emit an error and return false. If the argument is an identifier it
308261991Sdim/// will emit an error with a fixit hint and treat it as if it was a string
309261991Sdim/// literal.
310261991Sdimbool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr,
311261991Sdim                                          unsigned ArgNum, StringRef &Str,
312261991Sdim                                          SourceLocation *ArgLocation) {
313261991Sdim  // Look for identifiers. If we have one emit a hint to fix it to a literal.
314261991Sdim  if (Attr.isArgIdent(ArgNum)) {
315261991Sdim    IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum);
316261991Sdim    Diag(Loc->Loc, diag::err_attribute_argument_type)
317261991Sdim        << Attr.getName() << AANT_ArgumentString
318261991Sdim        << FixItHint::CreateInsertion(Loc->Loc, "\"")
319296417Sdim        << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");
320261991Sdim    Str = Loc->Ident->getName();
321261991Sdim    if (ArgLocation)
322261991Sdim      *ArgLocation = Loc->Loc;
323261991Sdim    return true;
324261991Sdim  }
325261991Sdim
326261991Sdim  // Now check for an actual string literal.
327261991Sdim  Expr *ArgExpr = Attr.getArgAsExpr(ArgNum);
328261991Sdim  StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
329261991Sdim  if (ArgLocation)
330261991Sdim    *ArgLocation = ArgExpr->getLocStart();
331261991Sdim
332261991Sdim  if (!Literal || !Literal->isAscii()) {
333261991Sdim    Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type)
334261991Sdim        << Attr.getName() << AANT_ArgumentString;
335261991Sdim    return false;
336261991Sdim  }
337261991Sdim
338261991Sdim  Str = Literal->getString();
339261991Sdim  return true;
340261991Sdim}
341261991Sdim
342276479Sdim/// \brief Applies the given attribute to the Decl without performing any
343276479Sdim/// additional semantic checking.
344276479Sdimtemplate <typename AttrType>
345276479Sdimstatic void handleSimpleAttribute(Sema &S, Decl *D,
346276479Sdim                                  const AttributeList &Attr) {
347276479Sdim  D->addAttr(::new (S.Context) AttrType(Attr.getRange(), S.Context,
348276479Sdim                                        Attr.getAttributeSpellingListIndex()));
349226633Sdim}
350226633Sdim
351296417Sdimtemplate <typename AttrType>
352296417Sdimstatic void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
353296417Sdim                                                const AttributeList &Attr) {
354296417Sdim  handleSimpleAttribute<AttrType>(S, D, Attr);
355296417Sdim}
356296417Sdim
357296417Sdim/// \brief Applies the given attribute to the Decl so long as the Decl doesn't
358296417Sdim/// already have one of the given incompatible attributes.
359296417Sdimtemplate <typename AttrType, typename IncompatibleAttrType,
360296417Sdim          typename... IncompatibleAttrTypes>
361296417Sdimstatic void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
362296417Sdim                                                const AttributeList &Attr) {
363296417Sdim  if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, Attr.getRange(),
364296417Sdim                                                     Attr.getName()))
365296417Sdim    return;
366296417Sdim  handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
367296417Sdim                                                                          Attr);
368296417Sdim}
369296417Sdim
370226633Sdim/// \brief Check if the passed-in expression is of type int or bool.
371226633Sdimstatic bool isIntOrBool(Expr *Exp) {
372226633Sdim  QualType QT = Exp->getType();
373226633Sdim  return QT->isBooleanType() || QT->isIntegerType();
374226633Sdim}
375226633Sdim
376239462Sdim
377239462Sdim// Check to see if the type is a smart pointer of some kind.  We assume
378239462Sdim// it's a smart pointer if it defines both operator-> and operator*.
379239462Sdimstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
380288943Sdim  DeclContextLookupResult Res1 = RT->getDecl()->lookup(
381288943Sdim      S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
382249423Sdim  if (Res1.empty())
383239462Sdim    return false;
384239462Sdim
385288943Sdim  DeclContextLookupResult Res2 = RT->getDecl()->lookup(
386288943Sdim      S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
387249423Sdim  if (Res2.empty())
388239462Sdim    return false;
389239462Sdim
390239462Sdim  return true;
391239462Sdim}
392239462Sdim
393226633Sdim/// \brief Check if passed in Decl is a pointer type.
394226633Sdim/// Note that this function may produce an error message.
395226633Sdim/// \return true if the Decl is a pointer type; false otherwise
396239462Sdimstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
397239462Sdim                                       const AttributeList &Attr) {
398276479Sdim  const ValueDecl *vd = cast<ValueDecl>(D);
399276479Sdim  QualType QT = vd->getType();
400276479Sdim  if (QT->isAnyPointerType())
401276479Sdim    return true;
402276479Sdim
403276479Sdim  if (const RecordType *RT = QT->getAs<RecordType>()) {
404276479Sdim    // If it's an incomplete type, it could be a smart pointer; skip it.
405276479Sdim    // (We don't want to force template instantiation if we can avoid it,
406276479Sdim    // since that would alter the order in which templates are instantiated.)
407276479Sdim    if (RT->isIncompleteType())
408226633Sdim      return true;
409239462Sdim
410276479Sdim    if (threadSafetyCheckIsSmartPointer(S, RT))
411276479Sdim      return true;
412276479Sdim  }
413239462Sdim
414276479Sdim  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
415276479Sdim    << Attr.getName() << QT;
416226633Sdim  return false;
417226633Sdim}
418226633Sdim
419226633Sdim/// \brief Checks that the passed in QualType either is of RecordType or points
420226633Sdim/// to RecordType. Returns the relevant RecordType, null if it does not exit.
421226633Sdimstatic const RecordType *getRecordType(QualType QT) {
422226633Sdim  if (const RecordType *RT = QT->getAs<RecordType>())
423226633Sdim    return RT;
424226633Sdim
425226633Sdim  // Now check if we point to record type.
426226633Sdim  if (const PointerType *PT = QT->getAs<PointerType>())
427226633Sdim    return PT->getPointeeType()->getAs<RecordType>();
428226633Sdim
429276479Sdim  return nullptr;
430226633Sdim}
431226633Sdim
432276479Sdimstatic bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
433234353Sdim  const RecordType *RT = getRecordType(Ty);
434239462Sdim
435276479Sdim  if (!RT)
436276479Sdim    return false;
437239462Sdim
438276479Sdim  // Don't check for the capability if the class hasn't been defined yet.
439234353Sdim  if (RT->isIncompleteType())
440276479Sdim    return true;
441239462Sdim
442276479Sdim  // Allow smart pointers to be used as capability objects.
443239462Sdim  // FIXME -- Check the type that the smart pointer points to.
444239462Sdim  if (threadSafetyCheckIsSmartPointer(S, RT))
445276479Sdim    return true;
446239462Sdim
447276479Sdim  // Check if the record itself has a capability.
448239462Sdim  RecordDecl *RD = RT->getDecl();
449276479Sdim  if (RD->hasAttr<CapabilityAttr>())
450276479Sdim    return true;
451239462Sdim
452276479Sdim  // Else check if any base classes have a capability.
453239462Sdim  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
454239462Sdim    CXXBasePaths BPaths(false, false);
455296417Sdim    if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath &) {
456296417Sdim          const auto *Type = BS->getType()->getAs<RecordType>();
457296417Sdim          return Type->getDecl()->hasAttr<CapabilityAttr>();
458296417Sdim        }, BPaths))
459276479Sdim      return true;
460226633Sdim  }
461276479Sdim  return false;
462276479Sdim}
463239462Sdim
464276479Sdimstatic bool checkTypedefTypeForCapability(QualType Ty) {
465276479Sdim  const auto *TD = Ty->getAs<TypedefType>();
466276479Sdim  if (!TD)
467276479Sdim    return false;
468276479Sdim
469276479Sdim  TypedefNameDecl *TN = TD->getDecl();
470276479Sdim  if (!TN)
471276479Sdim    return false;
472276479Sdim
473276479Sdim  return TN->hasAttr<CapabilityAttr>();
474226633Sdim}
475226633Sdim
476276479Sdimstatic bool typeHasCapability(Sema &S, QualType Ty) {
477276479Sdim  if (checkTypedefTypeForCapability(Ty))
478276479Sdim    return true;
479276479Sdim
480276479Sdim  if (checkRecordTypeForCapability(S, Ty))
481276479Sdim    return true;
482276479Sdim
483276479Sdim  return false;
484276479Sdim}
485276479Sdim
486276479Sdimstatic bool isCapabilityExpr(Sema &S, const Expr *Ex) {
487276479Sdim  // Capability expressions are simple expressions involving the boolean logic
488276479Sdim  // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
489276479Sdim  // a DeclRefExpr is found, its type should be checked to determine whether it
490276479Sdim  // is a capability or not.
491276479Sdim
492276479Sdim  if (const auto *E = dyn_cast<DeclRefExpr>(Ex))
493276479Sdim    return typeHasCapability(S, E->getType());
494276479Sdim  else if (const auto *E = dyn_cast<CastExpr>(Ex))
495276479Sdim    return isCapabilityExpr(S, E->getSubExpr());
496276479Sdim  else if (const auto *E = dyn_cast<ParenExpr>(Ex))
497276479Sdim    return isCapabilityExpr(S, E->getSubExpr());
498276479Sdim  else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
499276479Sdim    if (E->getOpcode() == UO_LNot)
500276479Sdim      return isCapabilityExpr(S, E->getSubExpr());
501276479Sdim    return false;
502276479Sdim  } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
503276479Sdim    if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
504276479Sdim      return isCapabilityExpr(S, E->getLHS()) &&
505276479Sdim             isCapabilityExpr(S, E->getRHS());
506276479Sdim    return false;
507276479Sdim  }
508276479Sdim
509276479Sdim  return false;
510276479Sdim}
511276479Sdim
512276479Sdim/// \brief Checks that all attribute arguments, starting from Sidx, resolve to
513276479Sdim/// a capability object.
514226633Sdim/// \param Sidx The attribute argument index to start checking with.
515226633Sdim/// \param ParamIdxOk Whether an argument can be indexing into a function
516226633Sdim/// parameter list.
517276479Sdimstatic void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
518276479Sdim                                           const AttributeList &Attr,
519276479Sdim                                           SmallVectorImpl<Expr *> &Args,
520276479Sdim                                           int Sidx = 0,
521276479Sdim                                           bool ParamIdxOk = false) {
522276479Sdim  for (unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
523261991Sdim    Expr *ArgExp = Attr.getArgAsExpr(Idx);
524226633Sdim
525226633Sdim    if (ArgExp->isTypeDependent()) {
526239462Sdim      // FIXME -- need to check this again on template instantiation
527226633Sdim      Args.push_back(ArgExp);
528226633Sdim      continue;
529226633Sdim    }
530226633Sdim
531239462Sdim    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
532243830Sdim      if (StrLit->getLength() == 0 ||
533261991Sdim          (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) {
534243830Sdim        // Pass empty strings to the analyzer without warnings.
535243830Sdim        // Treat "*" as the universal lock.
536243830Sdim        Args.push_back(ArgExp);
537239462Sdim        continue;
538243830Sdim      }
539239462Sdim
540239462Sdim      // We allow constant strings to be used as a placeholder for expressions
541239462Sdim      // that are not valid C++ syntax, but warn that they are ignored.
542239462Sdim      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
543239462Sdim        Attr.getName();
544243830Sdim      Args.push_back(ArgExp);
545239462Sdim      continue;
546239462Sdim    }
547239462Sdim
548226633Sdim    QualType ArgTy = ArgExp->getType();
549226633Sdim
550239462Sdim    // A pointer to member expression of the form  &MyClass::mu is treated
551239462Sdim    // specially -- we need to look at the type of the member.
552239462Sdim    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
553239462Sdim      if (UOp->getOpcode() == UO_AddrOf)
554239462Sdim        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
555239462Sdim          if (DRE->getDecl()->isCXXInstanceMember())
556239462Sdim            ArgTy = DRE->getDecl()->getType();
557239462Sdim
558276479Sdim    // First see if we can just cast to record type, or pointer to record type.
559226633Sdim    const RecordType *RT = getRecordType(ArgTy);
560226633Sdim
561226633Sdim    // Now check if we index into a record type function param.
562226633Sdim    if(!RT && ParamIdxOk) {
563226633Sdim      FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
564226633Sdim      IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp);
565226633Sdim      if(FD && IL) {
566226633Sdim        unsigned int NumParams = FD->getNumParams();
567226633Sdim        llvm::APInt ArgValue = IL->getValue();
568226633Sdim        uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
569226633Sdim        uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
570226633Sdim        if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
571226633Sdim          S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
572226633Sdim            << Attr.getName() << Idx + 1 << NumParams;
573239462Sdim          continue;
574226633Sdim        }
575226633Sdim        ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
576226633Sdim      }
577226633Sdim    }
578226633Sdim
579276479Sdim    // If the type does not have a capability, see if the components of the
580276479Sdim    // expression have capabilities. This allows for writing C code where the
581276479Sdim    // capability may be on the type, and the expression is a capability
582276479Sdim    // boolean logic expression. Eg) requires_capability(A || B && !C)
583276479Sdim    if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
584276479Sdim      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
585276479Sdim          << Attr.getName() << ArgTy;
586226633Sdim
587226633Sdim    Args.push_back(ArgExp);
588226633Sdim  }
589226633Sdim}
590226633Sdim
591193326Sed//===----------------------------------------------------------------------===//
592193326Sed// Attribute Implementations
593193326Sed//===----------------------------------------------------------------------===//
594193326Sed
595239462Sdimstatic void handlePtGuardedVarAttr(Sema &S, Decl *D,
596249423Sdim                                   const AttributeList &Attr) {
597239462Sdim  if (!threadSafetyCheckIsPointer(S, D, Attr))
598239462Sdim    return;
599239462Sdim
600249423Sdim  D->addAttr(::new (S.Context)
601249423Sdim             PtGuardedVarAttr(Attr.getRange(), S.Context,
602249423Sdim                              Attr.getAttributeSpellingListIndex()));
603239462Sdim}
604239462Sdim
605239462Sdimstatic bool checkGuardedByAttrCommon(Sema &S, Decl *D,
606239462Sdim                                     const AttributeList &Attr,
607239462Sdim                                     Expr* &Arg) {
608239462Sdim  SmallVector<Expr*, 1> Args;
609239462Sdim  // check that all arguments are lockable objects
610276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
611239462Sdim  unsigned Size = Args.size();
612239462Sdim  if (Size != 1)
613239462Sdim    return false;
614239462Sdim
615239462Sdim  Arg = Args[0];
616239462Sdim
617239462Sdim  return true;
618239462Sdim}
619239462Sdim
620239462Sdimstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
621276479Sdim  Expr *Arg = nullptr;
622239462Sdim  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
623226633Sdim    return;
624226633Sdim
625276479Sdim  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg,
626276479Sdim                                        Attr.getAttributeSpellingListIndex()));
627239462Sdim}
628226633Sdim
629239462Sdimstatic void handlePtGuardedByAttr(Sema &S, Decl *D,
630239462Sdim                                  const AttributeList &Attr) {
631276479Sdim  Expr *Arg = nullptr;
632239462Sdim  if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
633239462Sdim    return;
634239462Sdim
635239462Sdim  if (!threadSafetyCheckIsPointer(S, D, Attr))
636239462Sdim    return;
637239462Sdim
638239462Sdim  D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
639276479Sdim                                               S.Context, Arg,
640276479Sdim                                        Attr.getAttributeSpellingListIndex()));
641226633Sdim}
642226633Sdim
643239462Sdimstatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
644239462Sdim                                        const AttributeList &Attr,
645261991Sdim                                        SmallVectorImpl<Expr *> &Args) {
646226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
647239462Sdim    return false;
648226633Sdim
649239462Sdim  // Check that this attribute only applies to lockable types.
650276479Sdim  QualType QT = cast<ValueDecl>(D)->getType();
651296417Sdim  if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
652296417Sdim    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
653296417Sdim      << Attr.getName();
654296417Sdim    return false;
655226633Sdim  }
656226633Sdim
657239462Sdim  // Check that all arguments are lockable objects.
658276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
659251662Sdim  if (Args.empty())
660239462Sdim    return false;
661239462Sdim
662239462Sdim  return true;
663239462Sdim}
664239462Sdim
665239462Sdimstatic void handleAcquiredAfterAttr(Sema &S, Decl *D,
666239462Sdim                                    const AttributeList &Attr) {
667226633Sdim  SmallVector<Expr*, 1> Args;
668239462Sdim  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
669226633Sdim    return;
670226633Sdim
671239462Sdim  Expr **StartArg = &Args[0];
672249423Sdim  D->addAttr(::new (S.Context)
673249423Sdim             AcquiredAfterAttr(Attr.getRange(), S.Context,
674249423Sdim                               StartArg, Args.size(),
675249423Sdim                               Attr.getAttributeSpellingListIndex()));
676239462Sdim}
677226633Sdim
678239462Sdimstatic void handleAcquiredBeforeAttr(Sema &S, Decl *D,
679239462Sdim                                     const AttributeList &Attr) {
680239462Sdim  SmallVector<Expr*, 1> Args;
681239462Sdim  if (!checkAcquireOrderAttrCommon(S, D, Attr, Args))
682239462Sdim    return;
683239462Sdim
684239462Sdim  Expr **StartArg = &Args[0];
685249423Sdim  D->addAttr(::new (S.Context)
686249423Sdim             AcquiredBeforeAttr(Attr.getRange(), S.Context,
687249423Sdim                                StartArg, Args.size(),
688249423Sdim                                Attr.getAttributeSpellingListIndex()));
689226633Sdim}
690226633Sdim
691239462Sdimstatic bool checkLockFunAttrCommon(Sema &S, Decl *D,
692239462Sdim                                   const AttributeList &Attr,
693261991Sdim                                   SmallVectorImpl<Expr *> &Args) {
694226633Sdim  // zero or more arguments ok
695226633Sdim  // check that all arguments are lockable objects
696276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
697239462Sdim
698239462Sdim  return true;
699239462Sdim}
700239462Sdim
701261991Sdimstatic void handleAssertSharedLockAttr(Sema &S, Decl *D,
702261991Sdim                                       const AttributeList &Attr) {
703261991Sdim  SmallVector<Expr*, 1> Args;
704261991Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
705261991Sdim    return;
706261991Sdim
707261991Sdim  unsigned Size = Args.size();
708276479Sdim  Expr **StartArg = Size == 0 ? nullptr : &Args[0];
709261991Sdim  D->addAttr(::new (S.Context)
710261991Sdim             AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size,
711261991Sdim                                  Attr.getAttributeSpellingListIndex()));
712261991Sdim}
713261991Sdim
714261991Sdimstatic void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
715261991Sdim                                          const AttributeList &Attr) {
716261991Sdim  SmallVector<Expr*, 1> Args;
717261991Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
718261991Sdim    return;
719261991Sdim
720261991Sdim  unsigned Size = Args.size();
721276479Sdim  Expr **StartArg = Size == 0 ? nullptr : &Args[0];
722261991Sdim  D->addAttr(::new (S.Context)
723261991Sdim             AssertExclusiveLockAttr(Attr.getRange(), S.Context,
724261991Sdim                                     StartArg, Size,
725261991Sdim                                     Attr.getAttributeSpellingListIndex()));
726261991Sdim}
727261991Sdim
728261991Sdim
729239462Sdimstatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
730239462Sdim                                      const AttributeList &Attr,
731261991Sdim                                      SmallVectorImpl<Expr *> &Args) {
732226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
733239462Sdim    return false;
734226633Sdim
735261991Sdim  if (!isIntOrBool(Attr.getArgAsExpr(0))) {
736261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
737261991Sdim      << Attr.getName() << 1 << AANT_ArgumentIntOrBool;
738239462Sdim    return false;
739226633Sdim  }
740226633Sdim
741239462Sdim  // check that all arguments are lockable objects
742276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 1);
743239462Sdim
744239462Sdim  return true;
745239462Sdim}
746239462Sdim
747239462Sdimstatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
748239462Sdim                                            const AttributeList &Attr) {
749226633Sdim  SmallVector<Expr*, 2> Args;
750239462Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
751226633Sdim    return;
752226633Sdim
753249423Sdim  D->addAttr(::new (S.Context)
754249423Sdim             SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
755261991Sdim                                       Attr.getArgAsExpr(0),
756261991Sdim                                       Args.data(), Args.size(),
757249423Sdim                                       Attr.getAttributeSpellingListIndex()));
758239462Sdim}
759226633Sdim
760239462Sdimstatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
761239462Sdim                                               const AttributeList &Attr) {
762239462Sdim  SmallVector<Expr*, 2> Args;
763239462Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
764239462Sdim    return;
765239462Sdim
766280031Sdim  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
767280031Sdim      Attr.getRange(), S.Context, Attr.getArgAsExpr(0), Args.data(),
768280031Sdim      Args.size(), Attr.getAttributeSpellingListIndex()));
769226633Sdim}
770226633Sdim
771226633Sdimstatic void handleLockReturnedAttr(Sema &S, Decl *D,
772226633Sdim                                   const AttributeList &Attr) {
773226633Sdim  // check that the argument is lockable object
774239462Sdim  SmallVector<Expr*, 1> Args;
775276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
776239462Sdim  unsigned Size = Args.size();
777239462Sdim  if (Size == 0)
778239462Sdim    return;
779226633Sdim
780249423Sdim  D->addAttr(::new (S.Context)
781249423Sdim             LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
782249423Sdim                              Attr.getAttributeSpellingListIndex()));
783226633Sdim}
784226633Sdim
785226633Sdimstatic void handleLocksExcludedAttr(Sema &S, Decl *D,
786226633Sdim                                    const AttributeList &Attr) {
787226633Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
788226633Sdim    return;
789226633Sdim
790226633Sdim  // check that all arguments are lockable objects
791226633Sdim  SmallVector<Expr*, 1> Args;
792276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
793239462Sdim  unsigned Size = Args.size();
794239462Sdim  if (Size == 0)
795226633Sdim    return;
796239462Sdim  Expr **StartArg = &Args[0];
797226633Sdim
798249423Sdim  D->addAttr(::new (S.Context)
799249423Sdim             LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
800249423Sdim                               Attr.getAttributeSpellingListIndex()));
801226633Sdim}
802226633Sdim
803276479Sdimstatic void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) {
804276479Sdim  Expr *Cond = Attr.getArgAsExpr(0);
805276479Sdim  if (!Cond->isTypeDependent()) {
806276479Sdim    ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
807276479Sdim    if (Converted.isInvalid())
808276479Sdim      return;
809276479Sdim    Cond = Converted.get();
810276479Sdim  }
811276479Sdim
812276479Sdim  StringRef Msg;
813276479Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 1, Msg))
814276479Sdim    return;
815276479Sdim
816276479Sdim  SmallVector<PartialDiagnosticAt, 8> Diags;
817276479Sdim  if (!Cond->isValueDependent() &&
818276479Sdim      !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
819276479Sdim                                                Diags)) {
820276479Sdim    S.Diag(Attr.getLoc(), diag::err_enable_if_never_constant_expr);
821276479Sdim    for (int I = 0, N = Diags.size(); I != N; ++I)
822276479Sdim      S.Diag(Diags[I].first, Diags[I].second);
823276479Sdim    return;
824276479Sdim  }
825276479Sdim
826276479Sdim  D->addAttr(::new (S.Context)
827276479Sdim             EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg,
828276479Sdim                          Attr.getAttributeSpellingListIndex()));
829276479Sdim}
830276479Sdim
831296417Sdimstatic void handlePassObjectSizeAttr(Sema &S, Decl *D,
832296417Sdim                                     const AttributeList &Attr) {
833296417Sdim  if (D->hasAttr<PassObjectSizeAttr>()) {
834296417Sdim    S.Diag(D->getLocStart(), diag::err_attribute_only_once_per_parameter)
835296417Sdim        << Attr.getName();
836296417Sdim    return;
837296417Sdim  }
838296417Sdim
839296417Sdim  Expr *E = Attr.getArgAsExpr(0);
840296417Sdim  uint32_t Type;
841296417Sdim  if (!checkUInt32Argument(S, Attr, E, Type, /*Idx=*/1))
842296417Sdim    return;
843296417Sdim
844296417Sdim  // pass_object_size's argument is passed in as the second argument of
845296417Sdim  // __builtin_object_size. So, it has the same constraints as that second
846296417Sdim  // argument; namely, it must be in the range [0, 3].
847296417Sdim  if (Type > 3) {
848296417Sdim    S.Diag(E->getLocStart(), diag::err_attribute_argument_outof_range)
849296417Sdim        << Attr.getName() << 0 << 3 << E->getSourceRange();
850296417Sdim    return;
851296417Sdim  }
852296417Sdim
853296417Sdim  // pass_object_size is only supported on constant pointer parameters; as a
854296417Sdim  // kindness to users, we allow the parameter to be non-const for declarations.
855296417Sdim  // At this point, we have no clue if `D` belongs to a function declaration or
856296417Sdim  // definition, so we defer the constness check until later.
857296417Sdim  if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
858296417Sdim    S.Diag(D->getLocStart(), diag::err_attribute_pointers_only)
859296417Sdim        << Attr.getName() << 1;
860296417Sdim    return;
861296417Sdim  }
862296417Sdim
863296417Sdim  D->addAttr(::new (S.Context)
864296417Sdim                 PassObjectSizeAttr(Attr.getRange(), S.Context, (int)Type,
865296417Sdim                                    Attr.getAttributeSpellingListIndex()));
866296417Sdim}
867296417Sdim
868261991Sdimstatic void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
869261991Sdim  ConsumableAttr::ConsumedState DefaultState;
870226633Sdim
871261991Sdim  if (Attr.isArgIdent(0)) {
872261991Sdim    IdentifierLoc *IL = Attr.getArgAsIdent(0);
873261991Sdim    if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
874261991Sdim                                                   DefaultState)) {
875261991Sdim      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
876261991Sdim        << Attr.getName() << IL->Ident;
877261991Sdim      return;
878261991Sdim    }
879261991Sdim  } else {
880261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
881261991Sdim        << Attr.getName() << AANT_ArgumentIdentifier;
882261991Sdim    return;
883261991Sdim  }
884261991Sdim
885261991Sdim  D->addAttr(::new (S.Context)
886261991Sdim             ConsumableAttr(Attr.getRange(), S.Context, DefaultState,
887261991Sdim                            Attr.getAttributeSpellingListIndex()));
888261991Sdim}
889261991Sdim
890276479Sdim
891261991Sdimstatic bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
892261991Sdim                                        const AttributeList &Attr) {
893261991Sdim  ASTContext &CurrContext = S.getASTContext();
894261991Sdim  QualType ThisType = MD->getThisType(CurrContext)->getPointeeType();
895261991Sdim
896261991Sdim  if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
897261991Sdim    if (!RD->hasAttr<ConsumableAttr>()) {
898261991Sdim      S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) <<
899261991Sdim        RD->getNameAsString();
900261991Sdim
901261991Sdim      return false;
902261991Sdim    }
903261991Sdim  }
904261991Sdim
905261991Sdim  return true;
906261991Sdim}
907261991Sdim
908261991Sdim
909261991Sdimstatic void handleCallableWhenAttr(Sema &S, Decl *D,
910261991Sdim                                   const AttributeList &Attr) {
911261991Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
912261991Sdim    return;
913261991Sdim
914261991Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
915261991Sdim    return;
916261991Sdim
917261991Sdim  SmallVector<CallableWhenAttr::ConsumedState, 3> States;
918261991Sdim  for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) {
919261991Sdim    CallableWhenAttr::ConsumedState CallableState;
920261991Sdim
921261991Sdim    StringRef StateString;
922261991Sdim    SourceLocation Loc;
923280031Sdim    if (Attr.isArgIdent(ArgIndex)) {
924280031Sdim      IdentifierLoc *Ident = Attr.getArgAsIdent(ArgIndex);
925280031Sdim      StateString = Ident->Ident->getName();
926280031Sdim      Loc = Ident->Loc;
927280031Sdim    } else {
928280031Sdim      if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc))
929280031Sdim        return;
930280031Sdim    }
931261991Sdim
932261991Sdim    if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
933261991Sdim                                                     CallableState)) {
934261991Sdim      S.Diag(Loc, diag::warn_attribute_type_not_supported)
935261991Sdim        << Attr.getName() << StateString;
936261991Sdim      return;
937261991Sdim    }
938261991Sdim
939261991Sdim    States.push_back(CallableState);
940261991Sdim  }
941261991Sdim
942261991Sdim  D->addAttr(::new (S.Context)
943261991Sdim             CallableWhenAttr(Attr.getRange(), S.Context, States.data(),
944261991Sdim               States.size(), Attr.getAttributeSpellingListIndex()));
945261991Sdim}
946261991Sdim
947261991Sdim
948261991Sdimstatic void handleParamTypestateAttr(Sema &S, Decl *D,
949261991Sdim                                    const AttributeList &Attr) {
950261991Sdim  ParamTypestateAttr::ConsumedState ParamState;
951261991Sdim
952261991Sdim  if (Attr.isArgIdent(0)) {
953261991Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
954261991Sdim    StringRef StateString = Ident->Ident->getName();
955261991Sdim
956261991Sdim    if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
957261991Sdim                                                       ParamState)) {
958261991Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
959261991Sdim        << Attr.getName() << StateString;
960261991Sdim      return;
961261991Sdim    }
962261991Sdim  } else {
963261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
964261991Sdim      Attr.getName() << AANT_ArgumentIdentifier;
965261991Sdim    return;
966261991Sdim  }
967261991Sdim
968261991Sdim  // FIXME: This check is currently being done in the analysis.  It can be
969261991Sdim  //        enabled here only after the parser propagates attributes at
970261991Sdim  //        template specialization definition, not declaration.
971261991Sdim  //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
972261991Sdim  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
973261991Sdim  //
974261991Sdim  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
975261991Sdim  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
976261991Sdim  //      ReturnType.getAsString();
977261991Sdim  //    return;
978261991Sdim  //}
979261991Sdim
980261991Sdim  D->addAttr(::new (S.Context)
981261991Sdim             ParamTypestateAttr(Attr.getRange(), S.Context, ParamState,
982261991Sdim                                Attr.getAttributeSpellingListIndex()));
983261991Sdim}
984261991Sdim
985261991Sdim
986261991Sdimstatic void handleReturnTypestateAttr(Sema &S, Decl *D,
987261991Sdim                                      const AttributeList &Attr) {
988261991Sdim  ReturnTypestateAttr::ConsumedState ReturnState;
989261991Sdim
990261991Sdim  if (Attr.isArgIdent(0)) {
991261991Sdim    IdentifierLoc *IL = Attr.getArgAsIdent(0);
992261991Sdim    if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
993261991Sdim                                                        ReturnState)) {
994261991Sdim      S.Diag(IL->Loc, diag::warn_attribute_type_not_supported)
995261991Sdim        << Attr.getName() << IL->Ident;
996261991Sdim      return;
997261991Sdim    }
998261991Sdim  } else {
999261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1000261991Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1001261991Sdim    return;
1002261991Sdim  }
1003261991Sdim
1004261991Sdim  // FIXME: This check is currently being done in the analysis.  It can be
1005261991Sdim  //        enabled here only after the parser propagates attributes at
1006261991Sdim  //        template specialization definition, not declaration.
1007261991Sdim  //QualType ReturnType;
1008261991Sdim  //
1009261991Sdim  //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1010261991Sdim  //  ReturnType = Param->getType();
1011261991Sdim  //
1012261991Sdim  //} else if (const CXXConstructorDecl *Constructor =
1013261991Sdim  //             dyn_cast<CXXConstructorDecl>(D)) {
1014261991Sdim  //  ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType();
1015261991Sdim  //
1016261991Sdim  //} else {
1017261991Sdim  //
1018261991Sdim  //  ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1019261991Sdim  //}
1020261991Sdim  //
1021261991Sdim  //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1022261991Sdim  //
1023261991Sdim  //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1024261991Sdim  //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1025261991Sdim  //      ReturnType.getAsString();
1026261991Sdim  //    return;
1027261991Sdim  //}
1028261991Sdim
1029261991Sdim  D->addAttr(::new (S.Context)
1030261991Sdim             ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState,
1031261991Sdim                                 Attr.getAttributeSpellingListIndex()));
1032261991Sdim}
1033261991Sdim
1034261991Sdim
1035261991Sdimstatic void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1036261991Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1037261991Sdim    return;
1038261991Sdim
1039261991Sdim  SetTypestateAttr::ConsumedState NewState;
1040261991Sdim  if (Attr.isArgIdent(0)) {
1041261991Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1042261991Sdim    StringRef Param = Ident->Ident->getName();
1043261991Sdim    if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1044261991Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1045261991Sdim        << Attr.getName() << Param;
1046261991Sdim      return;
1047261991Sdim    }
1048261991Sdim  } else {
1049261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1050261991Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1051261991Sdim    return;
1052261991Sdim  }
1053261991Sdim
1054261991Sdim  D->addAttr(::new (S.Context)
1055261991Sdim             SetTypestateAttr(Attr.getRange(), S.Context, NewState,
1056261991Sdim                              Attr.getAttributeSpellingListIndex()));
1057261991Sdim}
1058261991Sdim
1059261991Sdimstatic void handleTestTypestateAttr(Sema &S, Decl *D,
1060261991Sdim                                    const AttributeList &Attr) {
1061261991Sdim  if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
1062261991Sdim    return;
1063261991Sdim
1064261991Sdim  TestTypestateAttr::ConsumedState TestState;
1065261991Sdim  if (Attr.isArgIdent(0)) {
1066261991Sdim    IdentifierLoc *Ident = Attr.getArgAsIdent(0);
1067261991Sdim    StringRef Param = Ident->Ident->getName();
1068261991Sdim    if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1069261991Sdim      S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1070261991Sdim        << Attr.getName() << Param;
1071261991Sdim      return;
1072261991Sdim    }
1073261991Sdim  } else {
1074261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) <<
1075261991Sdim      Attr.getName() << AANT_ArgumentIdentifier;
1076261991Sdim    return;
1077261991Sdim  }
1078261991Sdim
1079261991Sdim  D->addAttr(::new (S.Context)
1080261991Sdim             TestTypestateAttr(Attr.getRange(), S.Context, TestState,
1081261991Sdim                                Attr.getAttributeSpellingListIndex()));
1082261991Sdim}
1083261991Sdim
1084224145Sdimstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
1085224145Sdim                                    const AttributeList &Attr) {
1086249423Sdim  // Remember this typedef decl, we will need it later for diagnostics.
1087276479Sdim  S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
1088193326Sed}
1089193326Sed
1090224145Sdimstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1091224145Sdim  if (TagDecl *TD = dyn_cast<TagDecl>(D))
1092276479Sdim    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context,
1093276479Sdim                                        Attr.getAttributeSpellingListIndex()));
1094224145Sdim  else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
1095296417Sdim    // Report warning about changed offset in the newer compiler versions.
1096243830Sdim    if (!FD->getType()->isDependentType() &&
1097296417Sdim        !FD->getType()->isIncompleteType() && FD->isBitField() &&
1098193326Sed        S.Context.getTypeAlign(FD->getType()) <= 8)
1099296417Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield);
1100296417Sdim
1101296417Sdim    FD->addAttr(::new (S.Context) PackedAttr(
1102296417Sdim        Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
1103193326Sed  } else
1104193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1105193326Sed}
1106193326Sed
1107226633Sdimstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
1108226633Sdim  // The IBOutlet/IBOutletCollection attributes only apply to instance
1109226633Sdim  // variables or properties of Objective-C classes.  The outlet must also
1110226633Sdim  // have an object reference type.
1111226633Sdim  if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) {
1112226633Sdim    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1113234353Sdim      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
1114226633Sdim        << Attr.getName() << VD->getType() << 0;
1115226633Sdim      return false;
1116226633Sdim    }
1117226633Sdim  }
1118226633Sdim  else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1119226633Sdim    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1120234353Sdim      S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type)
1121226633Sdim        << Attr.getName() << PD->getType() << 1;
1122226633Sdim      return false;
1123226633Sdim    }
1124226633Sdim  }
1125226633Sdim  else {
1126226633Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName();
1127226633Sdim    return false;
1128226633Sdim  }
1129234353Sdim
1130226633Sdim  return true;
1131226633Sdim}
1132226633Sdim
1133224145Sdimstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) {
1134226633Sdim  if (!checkIBOutletCommon(S, D, Attr))
1135204643Srdivacky    return;
1136204643Srdivacky
1137249423Sdim  D->addAttr(::new (S.Context)
1138249423Sdim             IBOutletAttr(Attr.getRange(), S.Context,
1139249423Sdim                          Attr.getAttributeSpellingListIndex()));
1140193326Sed}
1141193326Sed
1142224145Sdimstatic void handleIBOutletCollection(Sema &S, Decl *D,
1143224145Sdim                                     const AttributeList &Attr) {
1144208600Srdivacky
1145208600Srdivacky  // The iboutletcollection attribute can have zero or one arguments.
1146261991Sdim  if (Attr.getNumArgs() > 1) {
1147261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1148261991Sdim      << Attr.getName() << 1;
1149208600Srdivacky    return;
1150208600Srdivacky  }
1151208600Srdivacky
1152226633Sdim  if (!checkIBOutletCommon(S, D, Attr))
1153208600Srdivacky    return;
1154226633Sdim
1155261991Sdim  ParsedType PT;
1156261991Sdim
1157261991Sdim  if (Attr.hasParsedType())
1158261991Sdim    PT = Attr.getTypeArg();
1159261991Sdim  else {
1160261991Sdim    PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(),
1161261991Sdim                       S.getScopeForContext(D->getDeclContext()->getParent()));
1162261991Sdim    if (!PT) {
1163261991Sdim      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1164261991Sdim      return;
1165261991Sdim    }
1166212904Sdim  }
1167261991Sdim
1168276479Sdim  TypeSourceInfo *QTLoc = nullptr;
1169261991Sdim  QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1170261991Sdim  if (!QTLoc)
1171261991Sdim    QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
1172261991Sdim
1173212904Sdim  // Diagnose use of non-object type in iboutletcollection attribute.
1174212904Sdim  // FIXME. Gnu attribute extension ignores use of builtin types in
1175212904Sdim  // attributes. So, __attribute__((iboutletcollection(char))) will be
1176212904Sdim  // treated as __attribute__((iboutletcollection())).
1177234353Sdim  if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1178261991Sdim    S.Diag(Attr.getLoc(),
1179261991Sdim           QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1180261991Sdim                               : diag::err_iboutletcollection_type) << QT;
1181212904Sdim    return;
1182212904Sdim  }
1183261991Sdim
1184249423Sdim  D->addAttr(::new (S.Context)
1185261991Sdim             IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc,
1186249423Sdim                                    Attr.getAttributeSpellingListIndex()));
1187208600Srdivacky}
1188208600Srdivacky
1189280031Sdimbool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
1190280031Sdim  if (RefOkay) {
1191280031Sdim    if (T->isReferenceType())
1192280031Sdim      return true;
1193280031Sdim  } else {
1194280031Sdim    T = T.getNonReferenceType();
1195280031Sdim  }
1196280031Sdim
1197280031Sdim  // The nonnull attribute, and other similar attributes, can be applied to a
1198280031Sdim  // transparent union that contains a pointer type.
1199280031Sdim  if (const RecordType *UT = T->getAsUnionType()) {
1200224145Sdim    if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1201224145Sdim      RecordDecl *UD = UT->getDecl();
1202276479Sdim      for (const auto *I : UD->fields()) {
1203276479Sdim        QualType QT = I->getType();
1204280031Sdim        if (QT->isAnyPointerType() || QT->isBlockPointerType())
1205280031Sdim          return true;
1206224145Sdim      }
1207224145Sdim    }
1208280031Sdim  }
1209280031Sdim
1210280031Sdim  return T->isAnyPointerType() || T->isBlockPointerType();
1211224145Sdim}
1212224145Sdim
1213276479Sdimstatic bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr,
1214280031Sdim                                SourceRange AttrParmRange,
1215280031Sdim                                SourceRange TypeRange,
1216280031Sdim                                bool isReturnValue = false) {
1217280031Sdim  if (!S.isValidPointerAttrType(T)) {
1218296417Sdim    if (isReturnValue)
1219296417Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only)
1220296417Sdim          << Attr.getName() << AttrParmRange << TypeRange;
1221296417Sdim    else
1222296417Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_pointers_only)
1223296417Sdim          << Attr.getName() << AttrParmRange << TypeRange << 0;
1224276479Sdim    return false;
1225239462Sdim  }
1226276479Sdim  return true;
1227239462Sdim}
1228239462Sdim
1229224145Sdimstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1230261991Sdim  SmallVector<unsigned, 8> NonNullArgs;
1231280031Sdim  for (unsigned I = 0; I < Attr.getNumArgs(); ++I) {
1232280031Sdim    Expr *Ex = Attr.getArgAsExpr(I);
1233261991Sdim    uint64_t Idx;
1234280031Sdim    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, I + 1, Ex, Idx))
1235193326Sed      return;
1236198092Srdivacky
1237193326Sed    // Is the function argument a pointer type?
1238280031Sdim    if (Idx < getFunctionOrMethodNumParams(D) &&
1239280031Sdim        !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr,
1240280031Sdim                             Ex->getSourceRange(),
1241280031Sdim                             getFunctionOrMethodParamRange(D, Idx)))
1242193326Sed      continue;
1243198092Srdivacky
1244261991Sdim    NonNullArgs.push_back(Idx);
1245193326Sed  }
1246198092Srdivacky
1247198092Srdivacky  // If no arguments were specified to __attribute__((nonnull)) then all pointer
1248280031Sdim  // arguments have a nonnull attribute; warn if there aren't any. Skip this
1249280031Sdim  // check if the attribute came from a macro expansion or a template
1250280031Sdim  // instantiation.
1251280031Sdim  if (NonNullArgs.empty() && Attr.getLoc().isFileID() &&
1252280031Sdim      S.ActiveTemplateInstantiations.empty()) {
1253280031Sdim    bool AnyPointers = isFunctionOrMethodVariadic(D);
1254280031Sdim    for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1255280031Sdim         I != E && !AnyPointers; ++I) {
1256280031Sdim      QualType T = getFunctionOrMethodParamType(D, I);
1257280031Sdim      if (T->isDependentType() || S.isValidPointerAttrType(T))
1258280031Sdim        AnyPointers = true;
1259193326Sed    }
1260198092Srdivacky
1261280031Sdim    if (!AnyPointers)
1262280031Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1263193326Sed  }
1264193326Sed
1265280031Sdim  unsigned *Start = NonNullArgs.data();
1266280031Sdim  unsigned Size = NonNullArgs.size();
1267280031Sdim  llvm::array_pod_sort(Start, Start + Size);
1268249423Sdim  D->addAttr(::new (S.Context)
1269280031Sdim             NonNullAttr(Attr.getRange(), S.Context, Start, Size,
1270249423Sdim                         Attr.getAttributeSpellingListIndex()));
1271193326Sed}
1272193326Sed
1273276479Sdimstatic void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1274276479Sdim                                       const AttributeList &Attr) {
1275276479Sdim  if (Attr.getNumArgs() > 0) {
1276276479Sdim    if (D->getFunctionType()) {
1277276479Sdim      handleNonNullAttr(S, D, Attr);
1278276479Sdim    } else {
1279276479Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1280276479Sdim        << D->getSourceRange();
1281276479Sdim    }
1282276479Sdim    return;
1283261991Sdim  }
1284276479Sdim
1285276479Sdim  // Is the argument a pointer type?
1286280031Sdim  if (!attrNonNullArgCheck(S, D->getType(), Attr, SourceRange(),
1287280031Sdim                           D->getSourceRange()))
1288276479Sdim    return;
1289276479Sdim
1290276479Sdim  D->addAttr(::new (S.Context)
1291276479Sdim             NonNullAttr(Attr.getRange(), S.Context, nullptr, 0,
1292276479Sdim                         Attr.getAttributeSpellingListIndex()));
1293261991Sdim}
1294261991Sdim
1295276479Sdimstatic void handleReturnsNonNullAttr(Sema &S, Decl *D,
1296276479Sdim                                     const AttributeList &Attr) {
1297276479Sdim  QualType ResultType = getFunctionOrMethodResultType(D);
1298280031Sdim  SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1299280031Sdim  if (!attrNonNullArgCheck(S, ResultType, Attr, SourceRange(), SR,
1300276479Sdim                           /* isReturnValue */ true))
1301276479Sdim    return;
1302276479Sdim
1303276479Sdim  D->addAttr(::new (S.Context)
1304276479Sdim            ReturnsNonNullAttr(Attr.getRange(), S.Context,
1305276479Sdim                               Attr.getAttributeSpellingListIndex()));
1306276479Sdim}
1307276479Sdim
1308280031Sdimstatic void handleAssumeAlignedAttr(Sema &S, Decl *D,
1309280031Sdim                                    const AttributeList &Attr) {
1310280031Sdim  Expr *E = Attr.getArgAsExpr(0),
1311280031Sdim       *OE = Attr.getNumArgs() > 1 ? Attr.getArgAsExpr(1) : nullptr;
1312280031Sdim  S.AddAssumeAlignedAttr(Attr.getRange(), D, E, OE,
1313280031Sdim                         Attr.getAttributeSpellingListIndex());
1314280031Sdim}
1315280031Sdim
1316280031Sdimvoid Sema::AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
1317280031Sdim                                Expr *OE, unsigned SpellingListIndex) {
1318280031Sdim  QualType ResultType = getFunctionOrMethodResultType(D);
1319280031Sdim  SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1320280031Sdim
1321280031Sdim  AssumeAlignedAttr TmpAttr(AttrRange, Context, E, OE, SpellingListIndex);
1322280031Sdim  SourceLocation AttrLoc = AttrRange.getBegin();
1323280031Sdim
1324280031Sdim  if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1325280031Sdim    Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1326280031Sdim      << &TmpAttr << AttrRange << SR;
1327280031Sdim    return;
1328280031Sdim  }
1329280031Sdim
1330280031Sdim  if (!E->isValueDependent()) {
1331280031Sdim    llvm::APSInt I(64);
1332280031Sdim    if (!E->isIntegerConstantExpr(I, Context)) {
1333280031Sdim      if (OE)
1334280031Sdim        Diag(AttrLoc, diag::err_attribute_argument_n_type)
1335280031Sdim          << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1336280031Sdim          << E->getSourceRange();
1337280031Sdim      else
1338280031Sdim        Diag(AttrLoc, diag::err_attribute_argument_type)
1339280031Sdim          << &TmpAttr << AANT_ArgumentIntegerConstant
1340280031Sdim          << E->getSourceRange();
1341280031Sdim      return;
1342280031Sdim    }
1343280031Sdim
1344280031Sdim    if (!I.isPowerOf2()) {
1345280031Sdim      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1346280031Sdim        << E->getSourceRange();
1347280031Sdim      return;
1348280031Sdim    }
1349280031Sdim  }
1350280031Sdim
1351280031Sdim  if (OE) {
1352280031Sdim    if (!OE->isValueDependent()) {
1353280031Sdim      llvm::APSInt I(64);
1354280031Sdim      if (!OE->isIntegerConstantExpr(I, Context)) {
1355280031Sdim        Diag(AttrLoc, diag::err_attribute_argument_n_type)
1356280031Sdim          << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1357280031Sdim          << OE->getSourceRange();
1358280031Sdim        return;
1359280031Sdim      }
1360280031Sdim    }
1361280031Sdim  }
1362280031Sdim
1363280031Sdim  D->addAttr(::new (Context)
1364280031Sdim            AssumeAlignedAttr(AttrRange, Context, E, OE, SpellingListIndex));
1365280031Sdim}
1366280031Sdim
1367296417Sdim/// Normalize the attribute, __foo__ becomes foo.
1368296417Sdim/// Returns true if normalization was applied.
1369296417Sdimstatic bool normalizeName(StringRef &AttrName) {
1370296417Sdim  if (AttrName.size() > 4 && AttrName.startswith("__") &&
1371296417Sdim      AttrName.endswith("__")) {
1372296417Sdim    AttrName = AttrName.drop_front(2).drop_back(2);
1373296417Sdim    return true;
1374296417Sdim  }
1375296417Sdim  return false;
1376296417Sdim}
1377296417Sdim
1378224145Sdimstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
1379261991Sdim  // This attribute must be applied to a function declaration. The first
1380261991Sdim  // argument to the attribute must be an identifier, the name of the resource,
1381261991Sdim  // for example: malloc. The following arguments must be argument indexes, the
1382261991Sdim  // arguments must be of integer type for Returns, otherwise of pointer type.
1383212904Sdim  // The difference between Holds and Takes is that a pointer may still be used
1384261991Sdim  // after being held. free() should be __attribute((ownership_takes)), whereas
1385212904Sdim  // a list append function may well be __attribute((ownership_holds)).
1386212904Sdim
1387261991Sdim  if (!AL.isArgIdent(0)) {
1388261991Sdim    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1389261991Sdim      << AL.getName() << 1 << AANT_ArgumentIdentifier;
1390212904Sdim    return;
1391212904Sdim  }
1392261991Sdim
1393276479Sdim  // Figure out our Kind.
1394276479Sdim  OwnershipAttr::OwnershipKind K =
1395276479Sdim      OwnershipAttr(AL.getLoc(), S.Context, nullptr, nullptr, 0,
1396276479Sdim                    AL.getAttributeSpellingListIndex()).getOwnKind();
1397276479Sdim
1398276479Sdim  // Check arguments.
1399276479Sdim  switch (K) {
1400276479Sdim  case OwnershipAttr::Takes:
1401276479Sdim  case OwnershipAttr::Holds:
1402261991Sdim    if (AL.getNumArgs() < 2) {
1403276479Sdim      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments)
1404276479Sdim        << AL.getName() << 2;
1405212904Sdim      return;
1406212904Sdim    }
1407212904Sdim    break;
1408276479Sdim  case OwnershipAttr::Returns:
1409261991Sdim    if (AL.getNumArgs() > 2) {
1410276479Sdim      S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments)
1411276479Sdim        << AL.getName() << 1;
1412212904Sdim      return;
1413212904Sdim    }
1414212904Sdim    break;
1415212904Sdim  }
1416212904Sdim
1417276479Sdim  IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
1418212904Sdim
1419276479Sdim  StringRef ModuleName = Module->getName();
1420296417Sdim  if (normalizeName(ModuleName)) {
1421276479Sdim    Module = &S.PP.getIdentifierTable().get(ModuleName);
1422276479Sdim  }
1423212904Sdim
1424261991Sdim  SmallVector<unsigned, 8> OwnershipArgs;
1425261991Sdim  for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1426261991Sdim    Expr *Ex = AL.getArgAsExpr(i);
1427261991Sdim    uint64_t Idx;
1428276479Sdim    if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
1429261991Sdim      return;
1430212904Sdim
1431261991Sdim    // Is the function argument a pointer type?
1432276479Sdim    QualType T = getFunctionOrMethodParamType(D, Idx);
1433261991Sdim    int Err = -1;  // No error
1434212904Sdim    switch (K) {
1435261991Sdim      case OwnershipAttr::Takes:
1436261991Sdim      case OwnershipAttr::Holds:
1437261991Sdim        if (!T->isAnyPointerType() && !T->isBlockPointerType())
1438261991Sdim          Err = 0;
1439261991Sdim        break;
1440261991Sdim      case OwnershipAttr::Returns:
1441261991Sdim        if (!T->isIntegerType())
1442261991Sdim          Err = 1;
1443261991Sdim        break;
1444212904Sdim    }
1445261991Sdim    if (-1 != Err) {
1446261991Sdim      S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err
1447261991Sdim        << Ex->getSourceRange();
1448261991Sdim      return;
1449212904Sdim    }
1450212904Sdim
1451212904Sdim    // Check we don't have a conflict with another ownership attribute.
1452276479Sdim    for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1453280031Sdim      // Cannot have two ownership attributes of different kinds for the same
1454280031Sdim      // index.
1455276479Sdim      if (I->getOwnKind() != K && I->args_end() !=
1456276479Sdim          std::find(I->args_begin(), I->args_end(), Idx)) {
1457261991Sdim        S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
1458276479Sdim          << AL.getName() << I;
1459261991Sdim        return;
1460280031Sdim      } else if (K == OwnershipAttr::Returns &&
1461280031Sdim                 I->getOwnKind() == OwnershipAttr::Returns) {
1462280031Sdim        // A returns attribute conflicts with any other returns attribute using
1463280031Sdim        // a different index. Note, diagnostic reporting is 1-based, but stored
1464280031Sdim        // argument indexes are 0-based.
1465280031Sdim        if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) {
1466280031Sdim          S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1467280031Sdim              << *(I->args_begin()) + 1;
1468280031Sdim          if (I->args_size())
1469280031Sdim            S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1470280031Sdim                << (unsigned)Idx + 1 << Ex->getSourceRange();
1471280031Sdim          return;
1472280031Sdim        }
1473212904Sdim      }
1474212904Sdim    }
1475261991Sdim    OwnershipArgs.push_back(Idx);
1476212904Sdim  }
1477212904Sdim
1478212904Sdim  unsigned* start = OwnershipArgs.data();
1479212904Sdim  unsigned size = OwnershipArgs.size();
1480212904Sdim  llvm::array_pod_sort(start, start + size);
1481212904Sdim
1482249423Sdim  D->addAttr(::new (S.Context)
1483276479Sdim             OwnershipAttr(AL.getLoc(), S.Context, Module, start, size,
1484249423Sdim                           AL.getAttributeSpellingListIndex()));
1485212904Sdim}
1486212904Sdim
1487224145Sdimstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1488204643Srdivacky  // Check the attribute arguments.
1489204643Srdivacky  if (Attr.getNumArgs() > 1) {
1490261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
1491261991Sdim      << Attr.getName() << 1;
1492204643Srdivacky    return;
1493204643Srdivacky  }
1494204643Srdivacky
1495224145Sdim  NamedDecl *nd = cast<NamedDecl>(D);
1496218893Sdim
1497204643Srdivacky  // gcc rejects
1498204643Srdivacky  // class c {
1499204643Srdivacky  //   static int a __attribute__((weakref ("v2")));
1500204643Srdivacky  //   static int b() __attribute__((weakref ("f3")));
1501204643Srdivacky  // };
1502204643Srdivacky  // and ignores the attributes of
1503204643Srdivacky  // void f(void) {
1504204643Srdivacky  //   static int a __attribute__((weakref ("v2")));
1505204643Srdivacky  // }
1506204643Srdivacky  // we reject them
1507224145Sdim  const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1508212904Sdim  if (!Ctx->isFileContext()) {
1509276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context)
1510276479Sdim      << nd;
1511212904Sdim    return;
1512204643Srdivacky  }
1513204643Srdivacky
1514204643Srdivacky  // The GCC manual says
1515204643Srdivacky  //
1516204643Srdivacky  // At present, a declaration to which `weakref' is attached can only
1517204643Srdivacky  // be `static'.
1518204643Srdivacky  //
1519204643Srdivacky  // It also says
1520204643Srdivacky  //
1521204643Srdivacky  // Without a TARGET,
1522204643Srdivacky  // given as an argument to `weakref' or to `alias', `weakref' is
1523204643Srdivacky  // equivalent to `weak'.
1524204643Srdivacky  //
1525204643Srdivacky  // gcc 4.4.1 will accept
1526204643Srdivacky  // int a7 __attribute__((weakref));
1527204643Srdivacky  // as
1528204643Srdivacky  // int a7 __attribute__((weak));
1529204643Srdivacky  // This looks like a bug in gcc. We reject that for now. We should revisit
1530204643Srdivacky  // it if this behaviour is actually used.
1531204643Srdivacky
1532204643Srdivacky  // GCC rejects
1533204643Srdivacky  // static ((alias ("y"), weakref)).
1534204643Srdivacky  // Should we? How to check that weakref is before or after alias?
1535204643Srdivacky
1536261991Sdim  // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1537261991Sdim  // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
1538261991Sdim  // StringRef parameter it was given anyway.
1539261991Sdim  StringRef Str;
1540261991Sdim  if (Attr.getNumArgs() && S.checkStringLiteralArgumentAttr(Attr, 0, Str))
1541204643Srdivacky    // GCC will accept anything as the argument of weakref. Should we
1542204643Srdivacky    // check for an existing decl?
1543261991Sdim    D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1544261991Sdim                                        Attr.getAttributeSpellingListIndex()));
1545204643Srdivacky
1546249423Sdim  D->addAttr(::new (S.Context)
1547249423Sdim             WeakRefAttr(Attr.getRange(), S.Context,
1548249423Sdim                         Attr.getAttributeSpellingListIndex()));
1549204643Srdivacky}
1550204643Srdivacky
1551224145Sdimstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1552261991Sdim  StringRef Str;
1553261991Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
1554193326Sed    return;
1555198092Srdivacky
1556226633Sdim  if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1557218893Sdim    S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin);
1558218893Sdim    return;
1559218893Sdim  }
1560218893Sdim
1561288943Sdim  // Aliases should be on declarations, not definitions.
1562288943Sdim  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1563288943Sdim    if (FD->isThisDeclarationADefinition()) {
1564288943Sdim      S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD;
1565288943Sdim      return;
1566288943Sdim    }
1567288943Sdim  } else {
1568288943Sdim    const auto *VD = cast<VarDecl>(D);
1569288943Sdim    if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
1570288943Sdim      S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << VD;
1571288943Sdim      return;
1572288943Sdim    }
1573288943Sdim  }
1574288943Sdim
1575193326Sed  // FIXME: check if target symbol exists in current file
1576198092Srdivacky
1577261991Sdim  D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str,
1578249423Sdim                                         Attr.getAttributeSpellingListIndex()));
1579193326Sed}
1580193326Sed
1581239462Sdimstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1582296417Sdim  if (checkAttrMutualExclusion<HotAttr>(S, D, Attr.getRange(), Attr.getName()))
1583239462Sdim    return;
1584239462Sdim
1585249423Sdim  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
1586249423Sdim                                        Attr.getAttributeSpellingListIndex()));
1587239462Sdim}
1588239462Sdim
1589239462Sdimstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1590296417Sdim  if (checkAttrMutualExclusion<ColdAttr>(S, D, Attr.getRange(), Attr.getName()))
1591239462Sdim    return;
1592239462Sdim
1593249423Sdim  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
1594249423Sdim                                       Attr.getAttributeSpellingListIndex()));
1595239462Sdim}
1596239462Sdim
1597239462Sdimstatic void handleTLSModelAttr(Sema &S, Decl *D,
1598239462Sdim                               const AttributeList &Attr) {
1599261991Sdim  StringRef Model;
1600261991Sdim  SourceLocation LiteralLoc;
1601239462Sdim  // Check that it is a string.
1602261991Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc))
1603239462Sdim    return;
1604239462Sdim
1605239462Sdim  // Check that the value.
1606239462Sdim  if (Model != "global-dynamic" && Model != "local-dynamic"
1607239462Sdim      && Model != "initial-exec" && Model != "local-exec") {
1608261991Sdim    S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
1609239462Sdim    return;
1610239462Sdim  }
1611239462Sdim
1612249423Sdim  D->addAttr(::new (S.Context)
1613249423Sdim             TLSModelAttr(Attr.getRange(), S.Context, Model,
1614249423Sdim                          Attr.getAttributeSpellingListIndex()));
1615239462Sdim}
1616239462Sdim
1617288943Sdimstatic void handleRestrictAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1618288943Sdim  QualType ResultType = getFunctionOrMethodResultType(D);
1619288943Sdim  if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
1620288943Sdim    D->addAttr(::new (S.Context) RestrictAttr(
1621288943Sdim        Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
1622288943Sdim    return;
1623198092Srdivacky  }
1624198092Srdivacky
1625288943Sdim  S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only)
1626288943Sdim      << Attr.getName() << getFunctionOrMethodResultSourceRange(D);
1627198092Srdivacky}
1628198092Srdivacky
1629224145Sdimstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1630261991Sdim  if (S.LangOpts.CPlusPlus) {
1631276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
1632296417Sdim        << Attr.getName() << AttributeLangSupport::Cpp;
1633261991Sdim    return;
1634261991Sdim  }
1635261991Sdim
1636296417Sdim  if (CommonAttr *CA = S.mergeCommonAttr(D, Attr.getRange(), Attr.getName(),
1637296417Sdim                                         Attr.getAttributeSpellingListIndex()))
1638296417Sdim    D->addAttr(CA);
1639218893Sdim}
1640218893Sdim
1641296417Sdimstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1642296417Sdim  if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, Attr.getRange(),
1643296417Sdim                                                     Attr.getName()))
1644296417Sdim    return;
1645296417Sdim
1646296417Sdim  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context,
1647296417Sdim                                         Attr.getAttributeSpellingListIndex()));
1648296417Sdim}
1649296417Sdim
1650224145Sdimstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
1651224145Sdim  if (hasDeclarator(D)) return;
1652218893Sdim
1653218893Sdim  if (S.CheckNoReturnAttr(attr)) return;
1654218893Sdim
1655224145Sdim  if (!isa<ObjCMethodDecl>(D)) {
1656218893Sdim    S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1657221345Sdim      << attr.getName() << ExpectedFunctionOrMethod;
1658218893Sdim    return;
1659218893Sdim  }
1660218893Sdim
1661249423Sdim  D->addAttr(::new (S.Context)
1662249423Sdim             NoReturnAttr(attr.getRange(), S.Context,
1663249423Sdim                          attr.getAttributeSpellingListIndex()));
1664218893Sdim}
1665218893Sdim
1666218893Sdimbool Sema::CheckNoReturnAttr(const AttributeList &attr) {
1667261991Sdim  if (!checkAttributeNumArgs(*this, attr, 0)) {
1668218893Sdim    attr.setInvalid();
1669218893Sdim    return true;
1670218893Sdim  }
1671218893Sdim
1672218893Sdim  return false;
1673218893Sdim}
1674218893Sdim
1675224145Sdimstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D,
1676224145Sdim                                       const AttributeList &Attr) {
1677212904Sdim
1678212904Sdim  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
1679212904Sdim  // because 'analyzer_noreturn' does not impact the type.
1680288943Sdim  if (!isFunctionOrMethodOrBlock(D)) {
1681224145Sdim    ValueDecl *VD = dyn_cast<ValueDecl>(D);
1682276479Sdim    if (!VD || (!VD->getType()->isBlockPointerType() &&
1683276479Sdim                !VD->getType()->isFunctionPointerType())) {
1684199990Srdivacky      S.Diag(Attr.getLoc(),
1685249423Sdim             Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
1686296417Sdim                                     : diag::warn_attribute_wrong_decl_type)
1687221345Sdim        << Attr.getName() << ExpectedFunctionMethodOrBlock;
1688212904Sdim      return;
1689193326Sed    }
1690193326Sed  }
1691212904Sdim
1692249423Sdim  D->addAttr(::new (S.Context)
1693249423Sdim             AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
1694249423Sdim                                  Attr.getAttributeSpellingListIndex()));
1695193326Sed}
1696193326Sed
1697212904Sdim// PS3 PPU-specific.
1698224145Sdimstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1699212904Sdim/*
1700212904Sdim  Returning a Vector Class in Registers
1701212904Sdim
1702218893Sdim  According to the PPU ABI specifications, a class with a single member of
1703218893Sdim  vector type is returned in memory when used as the return value of a function.
1704218893Sdim  This results in inefficient code when implementing vector classes. To return
1705218893Sdim  the value in a single vector register, add the vecreturn attribute to the
1706218893Sdim  class definition. This attribute is also applicable to struct types.
1707212904Sdim
1708212904Sdim  Example:
1709212904Sdim
1710212904Sdim  struct Vector
1711212904Sdim  {
1712212904Sdim    __vector float xyzw;
1713212904Sdim  } __attribute__((vecreturn));
1714212904Sdim
1715212904Sdim  Vector Add(Vector lhs, Vector rhs)
1716212904Sdim  {
1717212904Sdim    Vector result;
1718212904Sdim    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
1719212904Sdim    return result; // This will be returned in a register
1720212904Sdim  }
1721212904Sdim*/
1722276479Sdim  if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
1723276479Sdim    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << A;
1724212904Sdim    return;
1725212904Sdim  }
1726193326Sed
1727224145Sdim  RecordDecl *record = cast<RecordDecl>(D);
1728218893Sdim  int count = 0;
1729218893Sdim
1730218893Sdim  if (!isa<CXXRecordDecl>(record)) {
1731218893Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1732218893Sdim    return;
1733218893Sdim  }
1734218893Sdim
1735218893Sdim  if (!cast<CXXRecordDecl>(record)->isPOD()) {
1736218893Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
1737218893Sdim    return;
1738218893Sdim  }
1739218893Sdim
1740276479Sdim  for (const auto *I : record->fields()) {
1741276479Sdim    if ((count == 1) || !I->getType()->isVectorType()) {
1742218893Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
1743218893Sdim      return;
1744218893Sdim    }
1745218893Sdim    count++;
1746218893Sdim  }
1747218893Sdim
1748249423Sdim  D->addAttr(::new (S.Context)
1749249423Sdim             VecReturnAttr(Attr.getRange(), S.Context,
1750249423Sdim                           Attr.getAttributeSpellingListIndex()));
1751193326Sed}
1752193326Sed
1753249423Sdimstatic void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
1754249423Sdim                                 const AttributeList &Attr) {
1755249423Sdim  if (isa<ParmVarDecl>(D)) {
1756249423Sdim    // [[carries_dependency]] can only be applied to a parameter if it is a
1757249423Sdim    // parameter of a function declaration or lambda.
1758249423Sdim    if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
1759249423Sdim      S.Diag(Attr.getLoc(),
1760249423Sdim             diag::err_carries_dependency_param_not_function_decl);
1761249423Sdim      return;
1762249423Sdim    }
1763199990Srdivacky  }
1764249423Sdim
1765249423Sdim  D->addAttr(::new (S.Context) CarriesDependencyAttr(
1766249423Sdim                                   Attr.getRange(), S.Context,
1767249423Sdim                                   Attr.getAttributeSpellingListIndex()));
1768199990Srdivacky}
1769199990Srdivacky
1770296417Sdimstatic void handleNotTailCalledAttr(Sema &S, Decl *D,
1771296417Sdim                                    const AttributeList &Attr) {
1772296417Sdim  if (checkAttrMutualExclusion<AlwaysInlineAttr>(S, D, Attr.getRange(),
1773296417Sdim                                                 Attr.getName()))
1774296417Sdim    return;
1775296417Sdim
1776296417Sdim  D->addAttr(::new (S.Context) NotTailCalledAttr(
1777296417Sdim      Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
1778296417Sdim}
1779296417Sdim
1780296417Sdimstatic void handleDisableTailCallsAttr(Sema &S, Decl *D,
1781296417Sdim                                       const AttributeList &Attr) {
1782296417Sdim  if (checkAttrMutualExclusion<NakedAttr>(S, D, Attr.getRange(),
1783296417Sdim                                          Attr.getName()))
1784296417Sdim    return;
1785296417Sdim
1786296417Sdim  D->addAttr(::new (S.Context) DisableTailCallsAttr(
1787296417Sdim      Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
1788296417Sdim}
1789296417Sdim
1790224145Sdimstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1791224145Sdim  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1792261991Sdim    if (VD->hasLocalStorage()) {
1793276479Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1794193326Sed      return;
1795193326Sed    }
1796224145Sdim  } else if (!isFunctionOrMethod(D)) {
1797193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1798221345Sdim      << Attr.getName() << ExpectedVariableOrFunction;
1799193326Sed    return;
1800193326Sed  }
1801198092Srdivacky
1802249423Sdim  D->addAttr(::new (S.Context)
1803249423Sdim             UsedAttr(Attr.getRange(), S.Context,
1804249423Sdim                      Attr.getAttributeSpellingListIndex()));
1805193326Sed}
1806193326Sed
1807224145Sdimstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1808276479Sdim  uint32_t priority = ConstructorAttr::DefaultPriority;
1809280031Sdim  if (Attr.getNumArgs() &&
1810276479Sdim      !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))
1811193326Sed    return;
1812193326Sed
1813249423Sdim  D->addAttr(::new (S.Context)
1814249423Sdim             ConstructorAttr(Attr.getRange(), S.Context, priority,
1815249423Sdim                             Attr.getAttributeSpellingListIndex()));
1816193326Sed}
1817193326Sed
1818224145Sdimstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
1819276479Sdim  uint32_t priority = DestructorAttr::DefaultPriority;
1820280031Sdim  if (Attr.getNumArgs() &&
1821276479Sdim      !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))
1822193326Sed    return;
1823193326Sed
1824249423Sdim  D->addAttr(::new (S.Context)
1825249423Sdim             DestructorAttr(Attr.getRange(), S.Context, priority,
1826249423Sdim                            Attr.getAttributeSpellingListIndex()));
1827193326Sed}
1828193326Sed
1829239462Sdimtemplate <typename AttrTy>
1830261991Sdimstatic void handleAttrWithMessage(Sema &S, Decl *D,
1831261991Sdim                                  const AttributeList &Attr) {
1832239462Sdim  // Handle the case where the attribute has a text message.
1833226633Sdim  StringRef Str;
1834280031Sdim  if (Attr.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str))
1835261991Sdim    return;
1836198092Srdivacky
1837249423Sdim  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
1838249423Sdim                                      Attr.getAttributeSpellingListIndex()));
1839193326Sed}
1840193326Sed
1841276479Sdimstatic void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
1842276479Sdim                                          const AttributeList &Attr) {
1843276479Sdim  if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
1844276479Sdim    S.Diag(Attr.getLoc(), diag::err_objc_attr_protocol_requires_definition)
1845276479Sdim      << Attr.getName() << Attr.getRange();
1846234353Sdim    return;
1847234353Sdim  }
1848234353Sdim
1849249423Sdim  D->addAttr(::new (S.Context)
1850276479Sdim          ObjCExplicitProtocolImplAttr(Attr.getRange(), S.Context,
1851276479Sdim                                       Attr.getAttributeSpellingListIndex()));
1852234353Sdim}
1853234353Sdim
1854239462Sdimstatic bool checkAvailabilityAttr(Sema &S, SourceRange Range,
1855239462Sdim                                  IdentifierInfo *Platform,
1856239462Sdim                                  VersionTuple Introduced,
1857239462Sdim                                  VersionTuple Deprecated,
1858239462Sdim                                  VersionTuple Obsoleted) {
1859239462Sdim  StringRef PlatformName
1860239462Sdim    = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
1861239462Sdim  if (PlatformName.empty())
1862239462Sdim    PlatformName = Platform->getName();
1863239462Sdim
1864239462Sdim  // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
1865239462Sdim  // of these steps are needed).
1866239462Sdim  if (!Introduced.empty() && !Deprecated.empty() &&
1867239462Sdim      !(Introduced <= Deprecated)) {
1868239462Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
1869239462Sdim      << 1 << PlatformName << Deprecated.getAsString()
1870239462Sdim      << 0 << Introduced.getAsString();
1871239462Sdim    return true;
1872239462Sdim  }
1873239462Sdim
1874239462Sdim  if (!Introduced.empty() && !Obsoleted.empty() &&
1875239462Sdim      !(Introduced <= Obsoleted)) {
1876239462Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
1877239462Sdim      << 2 << PlatformName << Obsoleted.getAsString()
1878239462Sdim      << 0 << Introduced.getAsString();
1879239462Sdim    return true;
1880239462Sdim  }
1881239462Sdim
1882239462Sdim  if (!Deprecated.empty() && !Obsoleted.empty() &&
1883239462Sdim      !(Deprecated <= Obsoleted)) {
1884239462Sdim    S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
1885239462Sdim      << 2 << PlatformName << Obsoleted.getAsString()
1886239462Sdim      << 1 << Deprecated.getAsString();
1887239462Sdim    return true;
1888239462Sdim  }
1889239462Sdim
1890239462Sdim  return false;
1891239462Sdim}
1892239462Sdim
1893249423Sdim/// \brief Check whether the two versions match.
1894249423Sdim///
1895249423Sdim/// If either version tuple is empty, then they are assumed to match. If
1896249423Sdim/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
1897249423Sdimstatic bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
1898249423Sdim                          bool BeforeIsOkay) {
1899249423Sdim  if (X.empty() || Y.empty())
1900249423Sdim    return true;
1901249423Sdim
1902249423Sdim  if (X == Y)
1903249423Sdim    return true;
1904249423Sdim
1905249423Sdim  if (BeforeIsOkay && X < Y)
1906249423Sdim    return true;
1907249423Sdim
1908249423Sdim  return false;
1909249423Sdim}
1910249423Sdim
1911249423SdimAvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
1912239462Sdim                                              IdentifierInfo *Platform,
1913239462Sdim                                              VersionTuple Introduced,
1914239462Sdim                                              VersionTuple Deprecated,
1915239462Sdim                                              VersionTuple Obsoleted,
1916239462Sdim                                              bool IsUnavailable,
1917249423Sdim                                              StringRef Message,
1918296417Sdim                                              AvailabilityMergeKind AMK,
1919249423Sdim                                              unsigned AttrSpellingListIndex) {
1920239462Sdim  VersionTuple MergedIntroduced = Introduced;
1921239462Sdim  VersionTuple MergedDeprecated = Deprecated;
1922239462Sdim  VersionTuple MergedObsoleted = Obsoleted;
1923239462Sdim  bool FoundAny = false;
1924296417Sdim  bool OverrideOrImpl = false;
1925296417Sdim  switch (AMK) {
1926296417Sdim  case AMK_None:
1927296417Sdim  case AMK_Redeclaration:
1928296417Sdim    OverrideOrImpl = false;
1929296417Sdim    break;
1930239462Sdim
1931296417Sdim  case AMK_Override:
1932296417Sdim  case AMK_ProtocolImplementation:
1933296417Sdim    OverrideOrImpl = true;
1934296417Sdim    break;
1935296417Sdim  }
1936296417Sdim
1937239462Sdim  if (D->hasAttrs()) {
1938239462Sdim    AttrVec &Attrs = D->getAttrs();
1939239462Sdim    for (unsigned i = 0, e = Attrs.size(); i != e;) {
1940239462Sdim      const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
1941239462Sdim      if (!OldAA) {
1942239462Sdim        ++i;
1943239462Sdim        continue;
1944239462Sdim      }
1945239462Sdim
1946239462Sdim      IdentifierInfo *OldPlatform = OldAA->getPlatform();
1947239462Sdim      if (OldPlatform != Platform) {
1948239462Sdim        ++i;
1949239462Sdim        continue;
1950239462Sdim      }
1951239462Sdim
1952296417Sdim      // If there is an existing availability attribute for this platform that
1953296417Sdim      // is explicit and the new one is implicit use the explicit one and
1954296417Sdim      // discard the new implicit attribute.
1955296417Sdim      if (OldAA->getRange().isValid() && Range.isInvalid()) {
1956296417Sdim        return nullptr;
1957296417Sdim      }
1958296417Sdim
1959296417Sdim      // If there is an existing attribute for this platform that is implicit
1960296417Sdim      // and the new attribute is explicit then erase the old one and
1961296417Sdim      // continue processing the attributes.
1962296417Sdim      if (Range.isValid() && OldAA->getRange().isInvalid()) {
1963296417Sdim        Attrs.erase(Attrs.begin() + i);
1964296417Sdim        --e;
1965296417Sdim        continue;
1966296417Sdim      }
1967296417Sdim
1968239462Sdim      FoundAny = true;
1969239462Sdim      VersionTuple OldIntroduced = OldAA->getIntroduced();
1970239462Sdim      VersionTuple OldDeprecated = OldAA->getDeprecated();
1971239462Sdim      VersionTuple OldObsoleted = OldAA->getObsoleted();
1972239462Sdim      bool OldIsUnavailable = OldAA->getUnavailable();
1973239462Sdim
1974296417Sdim      if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
1975296417Sdim          !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||
1976296417Sdim          !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||
1977249423Sdim          !(OldIsUnavailable == IsUnavailable ||
1978296417Sdim            (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
1979296417Sdim        if (OverrideOrImpl) {
1980249423Sdim          int Which = -1;
1981249423Sdim          VersionTuple FirstVersion;
1982249423Sdim          VersionTuple SecondVersion;
1983296417Sdim          if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
1984249423Sdim            Which = 0;
1985249423Sdim            FirstVersion = OldIntroduced;
1986249423Sdim            SecondVersion = Introduced;
1987296417Sdim          } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {
1988249423Sdim            Which = 1;
1989249423Sdim            FirstVersion = Deprecated;
1990249423Sdim            SecondVersion = OldDeprecated;
1991296417Sdim          } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
1992249423Sdim            Which = 2;
1993249423Sdim            FirstVersion = Obsoleted;
1994249423Sdim            SecondVersion = OldObsoleted;
1995249423Sdim          }
1996249423Sdim
1997249423Sdim          if (Which == -1) {
1998249423Sdim            Diag(OldAA->getLocation(),
1999249423Sdim                 diag::warn_mismatched_availability_override_unavail)
2000296417Sdim              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2001296417Sdim              << (AMK == AMK_Override);
2002249423Sdim          } else {
2003249423Sdim            Diag(OldAA->getLocation(),
2004249423Sdim                 diag::warn_mismatched_availability_override)
2005249423Sdim              << Which
2006249423Sdim              << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2007296417Sdim              << FirstVersion.getAsString() << SecondVersion.getAsString()
2008296417Sdim              << (AMK == AMK_Override);
2009249423Sdim          }
2010296417Sdim          if (AMK == AMK_Override)
2011296417Sdim            Diag(Range.getBegin(), diag::note_overridden_method);
2012296417Sdim          else
2013296417Sdim            Diag(Range.getBegin(), diag::note_protocol_method);
2014249423Sdim        } else {
2015249423Sdim          Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2016249423Sdim          Diag(Range.getBegin(), diag::note_previous_attribute);
2017249423Sdim        }
2018249423Sdim
2019239462Sdim        Attrs.erase(Attrs.begin() + i);
2020239462Sdim        --e;
2021239462Sdim        continue;
2022239462Sdim      }
2023239462Sdim
2024239462Sdim      VersionTuple MergedIntroduced2 = MergedIntroduced;
2025239462Sdim      VersionTuple MergedDeprecated2 = MergedDeprecated;
2026239462Sdim      VersionTuple MergedObsoleted2 = MergedObsoleted;
2027239462Sdim
2028239462Sdim      if (MergedIntroduced2.empty())
2029239462Sdim        MergedIntroduced2 = OldIntroduced;
2030239462Sdim      if (MergedDeprecated2.empty())
2031239462Sdim        MergedDeprecated2 = OldDeprecated;
2032239462Sdim      if (MergedObsoleted2.empty())
2033239462Sdim        MergedObsoleted2 = OldObsoleted;
2034239462Sdim
2035239462Sdim      if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2036239462Sdim                                MergedIntroduced2, MergedDeprecated2,
2037239462Sdim                                MergedObsoleted2)) {
2038239462Sdim        Attrs.erase(Attrs.begin() + i);
2039239462Sdim        --e;
2040239462Sdim        continue;
2041239462Sdim      }
2042239462Sdim
2043239462Sdim      MergedIntroduced = MergedIntroduced2;
2044239462Sdim      MergedDeprecated = MergedDeprecated2;
2045239462Sdim      MergedObsoleted = MergedObsoleted2;
2046239462Sdim      ++i;
2047239462Sdim    }
2048239462Sdim  }
2049239462Sdim
2050239462Sdim  if (FoundAny &&
2051239462Sdim      MergedIntroduced == Introduced &&
2052239462Sdim      MergedDeprecated == Deprecated &&
2053239462Sdim      MergedObsoleted == Obsoleted)
2054276479Sdim    return nullptr;
2055239462Sdim
2056296417Sdim  // Only create a new attribute if !OverrideOrImpl, but we want to do
2057251662Sdim  // the checking.
2058239462Sdim  if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
2059251662Sdim                             MergedDeprecated, MergedObsoleted) &&
2060296417Sdim      !OverrideOrImpl) {
2061239462Sdim    return ::new (Context) AvailabilityAttr(Range, Context, Platform,
2062239462Sdim                                            Introduced, Deprecated,
2063249423Sdim                                            Obsoleted, IsUnavailable, Message,
2064249423Sdim                                            AttrSpellingListIndex);
2065239462Sdim  }
2066276479Sdim  return nullptr;
2067239462Sdim}
2068239462Sdim
2069224145Sdimstatic void handleAvailabilityAttr(Sema &S, Decl *D,
2070224145Sdim                                   const AttributeList &Attr) {
2071261991Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
2072261991Sdim    return;
2073261991Sdim  IdentifierLoc *Platform = Attr.getArgAsIdent(0);
2074249423Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2075249423Sdim
2076261991Sdim  IdentifierInfo *II = Platform->Ident;
2077261991Sdim  if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2078261991Sdim    S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2079261991Sdim      << Platform->Ident;
2080221345Sdim
2081249423Sdim  NamedDecl *ND = dyn_cast<NamedDecl>(D);
2082249423Sdim  if (!ND) {
2083249423Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2084249423Sdim    return;
2085249423Sdim  }
2086249423Sdim
2087221345Sdim  AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
2088221345Sdim  AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
2089221345Sdim  AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted();
2090221345Sdim  bool IsUnavailable = Attr.getUnavailableLoc().isValid();
2091234353Sdim  StringRef Str;
2092261991Sdim  if (const StringLiteral *SE =
2093261991Sdim          dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr()))
2094234353Sdim    Str = SE->getString();
2095239462Sdim
2096261991Sdim  AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
2097239462Sdim                                                      Introduced.Version,
2098239462Sdim                                                      Deprecated.Version,
2099239462Sdim                                                      Obsoleted.Version,
2100249423Sdim                                                      IsUnavailable, Str,
2101296417Sdim                                                      Sema::AMK_None,
2102249423Sdim                                                      Index);
2103239462Sdim  if (NewAttr)
2104239462Sdim    D->addAttr(NewAttr);
2105296417Sdim
2106296417Sdim  // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2107296417Sdim  // matches before the start of the watchOS platform.
2108296417Sdim  if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2109296417Sdim    IdentifierInfo *NewII = nullptr;
2110296417Sdim    if (II->getName() == "ios")
2111296417Sdim      NewII = &S.Context.Idents.get("watchos");
2112296417Sdim    else if (II->getName() == "ios_app_extension")
2113296417Sdim      NewII = &S.Context.Idents.get("watchos_app_extension");
2114296417Sdim
2115296417Sdim    if (NewII) {
2116296417Sdim        auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple {
2117296417Sdim          if (Version.empty())
2118296417Sdim            return Version;
2119296417Sdim          auto Major = Version.getMajor();
2120296417Sdim          auto NewMajor = Major >= 9 ? Major - 7 : 0;
2121296417Sdim          if (NewMajor >= 2) {
2122296417Sdim            if (Version.getMinor().hasValue()) {
2123296417Sdim              if (Version.getSubminor().hasValue())
2124296417Sdim                return VersionTuple(NewMajor, Version.getMinor().getValue(),
2125296417Sdim                                    Version.getSubminor().getValue());
2126296417Sdim              else
2127296417Sdim                return VersionTuple(NewMajor, Version.getMinor().getValue());
2128296417Sdim            }
2129296417Sdim          }
2130296417Sdim
2131296417Sdim          return VersionTuple(2, 0);
2132296417Sdim        };
2133296417Sdim
2134296417Sdim        auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2135296417Sdim        auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2136296417Sdim        auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2137296417Sdim
2138296417Sdim        AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
2139296417Sdim                                                            SourceRange(),
2140296417Sdim                                                            NewII,
2141296417Sdim                                                            NewIntroduced,
2142296417Sdim                                                            NewDeprecated,
2143296417Sdim                                                            NewObsoleted,
2144296417Sdim                                                            IsUnavailable, Str,
2145296417Sdim                                                            Sema::AMK_None,
2146296417Sdim                                                            Index);
2147296417Sdim        if (NewAttr)
2148296417Sdim          D->addAttr(NewAttr);
2149296417Sdim      }
2150296417Sdim  } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2151296417Sdim    // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2152296417Sdim    // matches before the start of the tvOS platform.
2153296417Sdim    IdentifierInfo *NewII = nullptr;
2154296417Sdim    if (II->getName() == "ios")
2155296417Sdim      NewII = &S.Context.Idents.get("tvos");
2156296417Sdim    else if (II->getName() == "ios_app_extension")
2157296417Sdim      NewII = &S.Context.Idents.get("tvos_app_extension");
2158296417Sdim
2159296417Sdim    if (NewII) {
2160296417Sdim        AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
2161296417Sdim                                                            SourceRange(),
2162296417Sdim                                                            NewII,
2163296417Sdim                                                            Introduced.Version,
2164296417Sdim                                                            Deprecated.Version,
2165296417Sdim                                                            Obsoleted.Version,
2166296417Sdim                                                            IsUnavailable, Str,
2167296417Sdim                                                            Sema::AMK_None,
2168296417Sdim                                                            Index);
2169296417Sdim        if (NewAttr)
2170296417Sdim          D->addAttr(NewAttr);
2171296417Sdim      }
2172296417Sdim  }
2173221345Sdim}
2174221345Sdim
2175249423Sdimtemplate <class T>
2176249423Sdimstatic T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
2177249423Sdim                              typename T::VisibilityType value,
2178249423Sdim                              unsigned attrSpellingListIndex) {
2179249423Sdim  T *existingAttr = D->getAttr<T>();
2180249423Sdim  if (existingAttr) {
2181249423Sdim    typename T::VisibilityType existingValue = existingAttr->getVisibility();
2182249423Sdim    if (existingValue == value)
2183276479Sdim      return nullptr;
2184249423Sdim    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2185249423Sdim    S.Diag(range.getBegin(), diag::note_previous_attribute);
2186249423Sdim    D->dropAttr<T>();
2187249423Sdim  }
2188249423Sdim  return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
2189249423Sdim}
2190249423Sdim
2191239462SdimVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
2192249423Sdim                                          VisibilityAttr::VisibilityType Vis,
2193249423Sdim                                          unsigned AttrSpellingListIndex) {
2194249423Sdim  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
2195249423Sdim                                               AttrSpellingListIndex);
2196249423Sdim}
2197249423Sdim
2198249423SdimTypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
2199249423Sdim                                      TypeVisibilityAttr::VisibilityType Vis,
2200249423Sdim                                      unsigned AttrSpellingListIndex) {
2201249423Sdim  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
2202249423Sdim                                                   AttrSpellingListIndex);
2203249423Sdim}
2204249423Sdim
2205249423Sdimstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr,
2206249423Sdim                                 bool isTypeVisibility) {
2207249423Sdim  // Visibility attributes don't mean anything on a typedef.
2208239462Sdim  if (isa<TypedefNameDecl>(D)) {
2209249423Sdim    S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored)
2210249423Sdim      << Attr.getName();
2211249423Sdim    return;
2212239462Sdim  }
2213249423Sdim
2214249423Sdim  // 'type_visibility' can only go on a type or namespace.
2215249423Sdim  if (isTypeVisibility &&
2216249423Sdim      !(isa<TagDecl>(D) ||
2217249423Sdim        isa<ObjCInterfaceDecl>(D) ||
2218249423Sdim        isa<NamespaceDecl>(D))) {
2219249423Sdim    S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2220249423Sdim      << Attr.getName() << ExpectedTypeOrNamespace;
2221249423Sdim    return;
2222239462Sdim  }
2223239462Sdim
2224261991Sdim  // Check that the argument is a string literal.
2225261991Sdim  StringRef TypeStr;
2226261991Sdim  SourceLocation LiteralLoc;
2227261991Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc))
2228193326Sed    return;
2229198092Srdivacky
2230261991Sdim  VisibilityAttr::VisibilityType type;
2231261991Sdim  if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2232261991Sdim    S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
2233261991Sdim      << Attr.getName() << TypeStr;
2234193326Sed    return;
2235193326Sed  }
2236249423Sdim
2237261991Sdim  // Complain about attempts to use protected visibility on targets
2238261991Sdim  // (like Darwin) that don't support it.
2239261991Sdim  if (type == VisibilityAttr::Protected &&
2240261991Sdim      !S.Context.getTargetInfo().hasProtectedVisibility()) {
2241261991Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility);
2242212904Sdim    type = VisibilityAttr::Default;
2243193326Sed  }
2244198092Srdivacky
2245249423Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2246249423Sdim  clang::Attr *newAttr;
2247249423Sdim  if (isTypeVisibility) {
2248249423Sdim    newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(),
2249249423Sdim                                    (TypeVisibilityAttr::VisibilityType) type,
2250249423Sdim                                        Index);
2251249423Sdim  } else {
2252249423Sdim    newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index);
2253249423Sdim  }
2254249423Sdim  if (newAttr)
2255249423Sdim    D->addAttr(newAttr);
2256193326Sed}
2257193326Sed
2258224145Sdimstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
2259224145Sdim                                       const AttributeList &Attr) {
2260276479Sdim  ObjCMethodDecl *method = cast<ObjCMethodDecl>(decl);
2261261991Sdim  if (!Attr.isArgIdent(0)) {
2262261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2263261991Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2264221345Sdim    return;
2265221345Sdim  }
2266221345Sdim
2267261991Sdim  IdentifierLoc *IL = Attr.getArgAsIdent(0);
2268261991Sdim  ObjCMethodFamilyAttr::FamilyKind F;
2269261991Sdim  if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
2270261991Sdim    S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName()
2271261991Sdim      << IL->Ident;
2272221345Sdim    return;
2273221345Sdim  }
2274221345Sdim
2275276479Sdim  if (F == ObjCMethodFamilyAttr::OMF_init &&
2276276479Sdim      !method->getReturnType()->isObjCObjectPointerType()) {
2277224145Sdim    S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
2278276479Sdim        << method->getReturnType();
2279224145Sdim    // Ignore the attribute.
2280224145Sdim    return;
2281224145Sdim  }
2282224145Sdim
2283226633Sdim  method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
2284276479Sdim                                                       S.Context, F,
2285276479Sdim                                        Attr.getAttributeSpellingListIndex()));
2286221345Sdim}
2287221345Sdim
2288224145Sdimstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
2289221345Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2290193326Sed    QualType T = TD->getUnderlyingType();
2291243830Sdim    if (!T->isCARCBridgableType()) {
2292193326Sed      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2293193326Sed      return;
2294193326Sed    }
2295193326Sed  }
2296239462Sdim  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2297239462Sdim    QualType T = PD->getType();
2298243830Sdim    if (!T->isCARCBridgableType()) {
2299239462Sdim      S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2300239462Sdim      return;
2301239462Sdim    }
2302239462Sdim  }
2303239462Sdim  else {
2304234353Sdim    // It is okay to include this attribute on properties, e.g.:
2305234353Sdim    //
2306234353Sdim    //  @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2307234353Sdim    //
2308234353Sdim    // In this case it follows tradition and suppresses an error in the above
2309234353Sdim    // case.
2310234353Sdim    S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2311234353Sdim  }
2312249423Sdim  D->addAttr(::new (S.Context)
2313249423Sdim             ObjCNSObjectAttr(Attr.getRange(), S.Context,
2314249423Sdim                              Attr.getAttributeSpellingListIndex()));
2315193326Sed}
2316193326Sed
2317288943Sdimstatic void handleObjCIndependentClass(Sema &S, Decl *D, const AttributeList &Attr) {
2318288943Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
2319288943Sdim    QualType T = TD->getUnderlyingType();
2320288943Sdim    if (!T->isObjCObjectPointerType()) {
2321288943Sdim      S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
2322288943Sdim      return;
2323288943Sdim    }
2324288943Sdim  } else {
2325288943Sdim    S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
2326288943Sdim    return;
2327288943Sdim  }
2328288943Sdim  D->addAttr(::new (S.Context)
2329288943Sdim             ObjCIndependentClassAttr(Attr.getRange(), S.Context,
2330288943Sdim                              Attr.getAttributeSpellingListIndex()));
2331288943Sdim}
2332288943Sdim
2333224145Sdimstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2334261991Sdim  if (!Attr.isArgIdent(0)) {
2335261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2336261991Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2337193326Sed    return;
2338193326Sed  }
2339198092Srdivacky
2340261991Sdim  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
2341212904Sdim  BlocksAttr::BlockType type;
2342261991Sdim  if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
2343193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
2344261991Sdim      << Attr.getName() << II;
2345193326Sed    return;
2346193326Sed  }
2347198092Srdivacky
2348249423Sdim  D->addAttr(::new (S.Context)
2349249423Sdim             BlocksAttr(Attr.getRange(), S.Context, type,
2350249423Sdim                        Attr.getAttributeSpellingListIndex()));
2351193326Sed}
2352193326Sed
2353224145Sdimstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2354276479Sdim  unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
2355193326Sed  if (Attr.getNumArgs() > 0) {
2356261991Sdim    Expr *E = Attr.getArgAsExpr(0);
2357193326Sed    llvm::APSInt Idx(32);
2358208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2359208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2360261991Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2361261991Sdim        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
2362261991Sdim        << E->getSourceRange();
2363193326Sed      return;
2364193326Sed    }
2365198092Srdivacky
2366226633Sdim    if (Idx.isSigned() && Idx.isNegative()) {
2367193326Sed      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2368193326Sed        << E->getSourceRange();
2369193326Sed      return;
2370193326Sed    }
2371226633Sdim
2372226633Sdim    sentinel = Idx.getZExtValue();
2373193326Sed  }
2374193326Sed
2375276479Sdim  unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
2376193326Sed  if (Attr.getNumArgs() > 1) {
2377261991Sdim    Expr *E = Attr.getArgAsExpr(1);
2378193326Sed    llvm::APSInt Idx(32);
2379208600Srdivacky    if (E->isTypeDependent() || E->isValueDependent() ||
2380208600Srdivacky        !E->isIntegerConstantExpr(Idx, S.Context)) {
2381261991Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2382261991Sdim        << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
2383261991Sdim        << E->getSourceRange();
2384193326Sed      return;
2385193326Sed    }
2386193326Sed    nullPos = Idx.getZExtValue();
2387198092Srdivacky
2388226633Sdim    if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) {
2389193326Sed      // FIXME: This error message could be improved, it would be nice
2390193326Sed      // to say what the bounds actually are.
2391193326Sed      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2392193326Sed        << E->getSourceRange();
2393193326Sed      return;
2394193326Sed    }
2395193326Sed  }
2396193326Sed
2397224145Sdim  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2398226633Sdim    const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2399193326Sed    if (isa<FunctionNoProtoType>(FT)) {
2400193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2401193326Sed      return;
2402193326Sed    }
2403198092Srdivacky
2404193326Sed    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2405193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2406193326Sed      return;
2407198092Srdivacky    }
2408224145Sdim  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2409193326Sed    if (!MD->isVariadic()) {
2410193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2411193326Sed      return;
2412193326Sed    }
2413234353Sdim  } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
2414234353Sdim    if (!BD->isVariadic()) {
2415234353Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2416234353Sdim      return;
2417234353Sdim    }
2418224145Sdim  } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
2419193326Sed    QualType Ty = V->getType();
2420193326Sed    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
2421276479Sdim      const FunctionType *FT = Ty->isFunctionPointerType()
2422276479Sdim       ? D->getFunctionType()
2423218893Sdim       : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
2424193326Sed      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2425193326Sed        int m = Ty->isFunctionPointerType() ? 0 : 1;
2426193326Sed        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
2427193326Sed        return;
2428193326Sed      }
2429198092Srdivacky    } else {
2430193326Sed      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2431221345Sdim        << Attr.getName() << ExpectedFunctionMethodOrBlock;
2432193326Sed      return;
2433193326Sed    }
2434193326Sed  } else {
2435193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2436221345Sdim      << Attr.getName() << ExpectedFunctionMethodOrBlock;
2437193326Sed    return;
2438193326Sed  }
2439249423Sdim  D->addAttr(::new (S.Context)
2440249423Sdim             SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
2441249423Sdim                          Attr.getAttributeSpellingListIndex()));
2442193326Sed}
2443193326Sed
2444224145Sdimstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
2445276479Sdim  if (D->getFunctionType() &&
2446276479Sdim      D->getFunctionType()->getReturnType()->isVoidType()) {
2447206084Srdivacky    S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2448206084Srdivacky      << Attr.getName() << 0;
2449201361Srdivacky    return;
2450201361Srdivacky  }
2451206084Srdivacky  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
2452276479Sdim    if (MD->getReturnType()->isVoidType()) {
2453206084Srdivacky      S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
2454206084Srdivacky      << Attr.getName() << 1;
2455206084Srdivacky      return;
2456206084Srdivacky    }
2457206084Srdivacky
2458249423Sdim  D->addAttr(::new (S.Context)
2459249423Sdim             WarnUnusedResultAttr(Attr.getRange(), S.Context,
2460249423Sdim                                  Attr.getAttributeSpellingListIndex()));
2461193326Sed}
2462193326Sed
2463224145Sdimstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2464193326Sed  // weak_import only applies to variable & function declarations.
2465193326Sed  bool isDef = false;
2466221345Sdim  if (!D->canBeWeakImported(isDef)) {
2467221345Sdim    if (isDef)
2468261991Sdim      S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition)
2469261991Sdim        << "weak_import";
2470221345Sdim    else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2471226633Sdim             (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
2472234353Sdim              (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2473221345Sdim      // Nothing to warn about here.
2474221345Sdim    } else
2475207619Srdivacky      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2476221345Sdim        << Attr.getName() << ExpectedVariableOrFunction;
2477193326Sed
2478193326Sed    return;
2479193326Sed  }
2480193326Sed
2481249423Sdim  D->addAttr(::new (S.Context)
2482249423Sdim             WeakImportAttr(Attr.getRange(), S.Context,
2483249423Sdim                            Attr.getAttributeSpellingListIndex()));
2484193326Sed}
2485193326Sed
2486239462Sdim// Handles reqd_work_group_size and work_group_size_hint.
2487276479Sdimtemplate <typename WorkGroupAttr>
2488239462Sdimstatic void handleWorkGroupSize(Sema &S, Decl *D,
2489239462Sdim                                const AttributeList &Attr) {
2490276479Sdim  uint32_t WGSize[3];
2491195099Sed  for (unsigned i = 0; i < 3; ++i) {
2492276479Sdim    const Expr *E = Attr.getArgAsExpr(i);
2493276479Sdim    if (!checkUInt32Argument(S, Attr, E, WGSize[i], i))
2494195099Sed      return;
2495276479Sdim    if (WGSize[i] == 0) {
2496276479Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
2497276479Sdim        << Attr.getName() << E->getSourceRange();
2498276479Sdim      return;
2499195099Sed    }
2500195099Sed  }
2501239462Sdim
2502276479Sdim  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
2503276479Sdim  if (Existing && !(Existing->getXDim() == WGSize[0] &&
2504276479Sdim                    Existing->getYDim() == WGSize[1] &&
2505276479Sdim                    Existing->getZDim() == WGSize[2]))
2506276479Sdim    S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
2507239462Sdim
2508276479Sdim  D->addAttr(::new (S.Context) WorkGroupAttr(Attr.getRange(), S.Context,
2509276479Sdim                                             WGSize[0], WGSize[1], WGSize[2],
2510249423Sdim                                       Attr.getAttributeSpellingListIndex()));
2511195099Sed}
2512195099Sed
2513249423Sdimstatic void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
2514261991Sdim  if (!Attr.hasParsedType()) {
2515261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
2516261991Sdim      << Attr.getName() << 1;
2517249423Sdim    return;
2518261991Sdim  }
2519249423Sdim
2520276479Sdim  TypeSourceInfo *ParmTSI = nullptr;
2521261991Sdim  QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI);
2522261991Sdim  assert(ParmTSI && "no type source info for attribute argument");
2523249423Sdim
2524249423Sdim  if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
2525249423Sdim      (ParmType->isBooleanType() ||
2526249423Sdim       !ParmType->isIntegralType(S.getASTContext()))) {
2527249423Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint)
2528249423Sdim        << ParmType;
2529249423Sdim    return;
2530249423Sdim  }
2531249423Sdim
2532276479Sdim  if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
2533261991Sdim    if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
2534249423Sdim      S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
2535249423Sdim      return;
2536249423Sdim    }
2537249423Sdim  }
2538249423Sdim
2539249423Sdim  D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
2540276479Sdim                                               ParmTSI,
2541276479Sdim                                        Attr.getAttributeSpellingListIndex()));
2542249423Sdim}
2543249423Sdim
2544239462SdimSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
2545249423Sdim                                    StringRef Name,
2546249423Sdim                                    unsigned AttrSpellingListIndex) {
2547239462Sdim  if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
2548239462Sdim    if (ExistingAttr->getName() == Name)
2549276479Sdim      return nullptr;
2550239462Sdim    Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
2551239462Sdim    Diag(Range.getBegin(), diag::note_previous_attribute);
2552276479Sdim    return nullptr;
2553239462Sdim  }
2554249423Sdim  return ::new (Context) SectionAttr(Range, Context, Name,
2555249423Sdim                                     AttrSpellingListIndex);
2556239462Sdim}
2557239462Sdim
2558288943Sdimbool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
2559288943Sdim  std::string Error = Context.getTargetInfo().isValidSectionSpecifier(SecName);
2560288943Sdim  if (!Error.empty()) {
2561288943Sdim    Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error;
2562288943Sdim    return false;
2563288943Sdim  }
2564288943Sdim  return true;
2565288943Sdim}
2566288943Sdim
2567224145Sdimstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2568193326Sed  // Make sure that there is a string literal as the sections's single
2569193326Sed  // argument.
2570261991Sdim  StringRef Str;
2571261991Sdim  SourceLocation LiteralLoc;
2572261991Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc))
2573193326Sed    return;
2574198092Srdivacky
2575288943Sdim  if (!S.checkSectionName(LiteralLoc, Str))
2576288943Sdim    return;
2577288943Sdim
2578198092Srdivacky  // If the target wants to validate the section specifier, make it happen.
2579261991Sdim  std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str);
2580202379Srdivacky  if (!Error.empty()) {
2581261991Sdim    S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
2582202379Srdivacky    << Error;
2583198092Srdivacky    return;
2584198092Srdivacky  }
2585198092Srdivacky
2586249423Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2587261991Sdim  SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index);
2588239462Sdim  if (NewAttr)
2589239462Sdim    D->addAttr(NewAttr);
2590193326Sed}
2591193326Sed
2592288943Sdim// Check for things we'd like to warn about, no errors or validation for now.
2593288943Sdim// TODO: Validation should use a backend target library that specifies
2594288943Sdim// the allowable subtarget features and cpus. We could use something like a
2595288943Sdim// TargetCodeGenInfo hook here to do validation.
2596288943Sdimvoid Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
2597288943Sdim  for (auto Str : {"tune=", "fpmath="})
2598288943Sdim    if (AttrStr.find(Str) != StringRef::npos)
2599288943Sdim      Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Str;
2600288943Sdim}
2601199482Srdivacky
2602288943Sdimstatic void handleTargetAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2603288943Sdim  StringRef Str;
2604288943Sdim  SourceLocation LiteralLoc;
2605288943Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc))
2606288943Sdim    return;
2607288943Sdim  S.checkTargetAttr(LiteralLoc, Str);
2608288943Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
2609288943Sdim  TargetAttr *NewAttr =
2610288943Sdim      ::new (S.Context) TargetAttr(Attr.getRange(), S.Context, Str, Index);
2611288943Sdim  D->addAttr(NewAttr);
2612288943Sdim}
2613288943Sdim
2614288943Sdim
2615224145Sdimstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2616276479Sdim  VarDecl *VD = cast<VarDecl>(D);
2617276479Sdim  if (!VD->hasLocalStorage()) {
2618261991Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2619193326Sed    return;
2620193326Sed  }
2621198092Srdivacky
2622261991Sdim  Expr *E = Attr.getArgAsExpr(0);
2623261991Sdim  SourceLocation Loc = E->getExprLoc();
2624276479Sdim  FunctionDecl *FD = nullptr;
2625261991Sdim  DeclarationNameInfo NI;
2626198092Srdivacky
2627261991Sdim  // gcc only allows for simple identifiers. Since we support more than gcc, we
2628261991Sdim  // will warn the user.
2629261991Sdim  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
2630261991Sdim    if (DRE->hasQualifier())
2631261991Sdim      S.Diag(Loc, diag::warn_cleanup_ext);
2632261991Sdim    FD = dyn_cast<FunctionDecl>(DRE->getDecl());
2633261991Sdim    NI = DRE->getNameInfo();
2634261991Sdim    if (!FD) {
2635261991Sdim      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
2636261991Sdim        << NI.getName();
2637261991Sdim      return;
2638261991Sdim    }
2639261991Sdim  } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
2640261991Sdim    if (ULE->hasExplicitTemplateArgs())
2641261991Sdim      S.Diag(Loc, diag::warn_cleanup_ext);
2642261991Sdim    FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
2643261991Sdim    NI = ULE->getNameInfo();
2644261991Sdim    if (!FD) {
2645261991Sdim      S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
2646261991Sdim        << NI.getName();
2647261991Sdim      if (ULE->getType() == S.Context.OverloadTy)
2648261991Sdim        S.NoteAllOverloadCandidates(ULE);
2649261991Sdim      return;
2650261991Sdim    }
2651261991Sdim  } else {
2652261991Sdim    S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
2653193326Sed    return;
2654193326Sed  }
2655193326Sed
2656193326Sed  if (FD->getNumParams() != 1) {
2657261991Sdim    S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
2658261991Sdim      << NI.getName();
2659193326Sed    return;
2660193326Sed  }
2661198092Srdivacky
2662193326Sed  // We're currently more strict than GCC about what function types we accept.
2663193326Sed  // If this ever proves to be a problem it should be easy to fix.
2664193326Sed  QualType Ty = S.Context.getPointerType(VD->getType());
2665193326Sed  QualType ParamTy = FD->getParamDecl(0)->getType();
2666218893Sdim  if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
2667218893Sdim                                   ParamTy, Ty) != Sema::Compatible) {
2668261991Sdim    S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
2669261991Sdim      << NI.getName() << ParamTy << Ty;
2670193326Sed    return;
2671193326Sed  }
2672198092Srdivacky
2673249423Sdim  D->addAttr(::new (S.Context)
2674249423Sdim             CleanupAttr(Attr.getRange(), S.Context, FD,
2675249423Sdim                         Attr.getAttributeSpellingListIndex()));
2676193326Sed}
2677193326Sed
2678198092Srdivacky/// Handle __attribute__((format_arg((idx)))) attribute based on
2679198092Srdivacky/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
2680224145Sdimstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2681261991Sdim  Expr *IdxExpr = Attr.getArgAsExpr(0);
2682276479Sdim  uint64_t Idx;
2683276479Sdim  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, IdxExpr, Idx))
2684193326Sed    return;
2685198092Srdivacky
2686296417Sdim  // Make sure the format string is really a string.
2687276479Sdim  QualType Ty = getFunctionOrMethodParamType(D, Idx);
2688198092Srdivacky
2689296417Sdim  bool NotNSStringTy = !isNSStringType(Ty, S.Context);
2690296417Sdim  if (NotNSStringTy &&
2691193326Sed      !isCFStringType(Ty, S.Context) &&
2692193326Sed      (!Ty->isPointerType() ||
2693198092Srdivacky       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
2694193326Sed    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2695296417Sdim        << "a string type" << IdxExpr->getSourceRange()
2696296417Sdim        << getFunctionOrMethodParamRange(D, 0);
2697193326Sed    return;
2698198092Srdivacky  }
2699224145Sdim  Ty = getFunctionOrMethodResultType(D);
2700193326Sed  if (!isNSStringType(Ty, S.Context) &&
2701193326Sed      !isCFStringType(Ty, S.Context) &&
2702193326Sed      (!Ty->isPointerType() ||
2703198092Srdivacky       !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) {
2704193326Sed    S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not)
2705296417Sdim        << (NotNSStringTy ? "string type" : "NSString")
2706280031Sdim        << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
2707193326Sed    return;
2708198092Srdivacky  }
2709198092Srdivacky
2710276479Sdim  // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex
2711261991Sdim  // because that has corrected for the implicit this parameter, and is zero-
2712261991Sdim  // based.  The attribute expects what the user wrote explicitly.
2713261991Sdim  llvm::APSInt Val;
2714261991Sdim  IdxExpr->EvaluateAsInt(Val, S.Context);
2715261991Sdim
2716249423Sdim  D->addAttr(::new (S.Context)
2717261991Sdim             FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(),
2718249423Sdim                           Attr.getAttributeSpellingListIndex()));
2719193326Sed}
2720193326Sed
2721198398Srdivackyenum FormatAttrKind {
2722198398Srdivacky  CFStringFormat,
2723198398Srdivacky  NSStringFormat,
2724198398Srdivacky  StrftimeFormat,
2725198398Srdivacky  SupportedFormat,
2726206084Srdivacky  IgnoredFormat,
2727198398Srdivacky  InvalidFormat
2728198398Srdivacky};
2729198398Srdivacky
2730198398Srdivacky/// getFormatAttrKind - Map from format attribute names to supported format
2731198398Srdivacky/// types.
2732226633Sdimstatic FormatAttrKind getFormatAttrKind(StringRef Format) {
2733239462Sdim  return llvm::StringSwitch<FormatAttrKind>(Format)
2734239462Sdim    // Check for formats that get handled specially.
2735239462Sdim    .Case("NSString", NSStringFormat)
2736239462Sdim    .Case("CFString", CFStringFormat)
2737239462Sdim    .Case("strftime", StrftimeFormat)
2738198398Srdivacky
2739239462Sdim    // Otherwise, check for supported formats.
2740239462Sdim    .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
2741239462Sdim    .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
2742239462Sdim    .Case("kprintf", SupportedFormat) // OpenBSD.
2743280031Sdim    .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
2744288943Sdim    .Case("os_trace", SupportedFormat)
2745198398Srdivacky
2746239462Sdim    .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
2747239462Sdim    .Default(InvalidFormat);
2748198398Srdivacky}
2749198398Srdivacky
2750210299Sed/// Handle __attribute__((init_priority(priority))) attributes based on
2751210299Sed/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
2752224145Sdimstatic void handleInitPriorityAttr(Sema &S, Decl *D,
2753224145Sdim                                   const AttributeList &Attr) {
2754234353Sdim  if (!S.getLangOpts().CPlusPlus) {
2755210299Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2756210299Sed    return;
2757210299Sed  }
2758210299Sed
2759276479Sdim  if (S.getCurFunctionOrMethodDecl()) {
2760210299Sed    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2761210299Sed    Attr.setInvalid();
2762210299Sed    return;
2763210299Sed  }
2764276479Sdim  QualType T = cast<VarDecl>(D)->getType();
2765210299Sed  if (S.Context.getAsArrayType(T))
2766210299Sed    T = S.Context.getBaseElementType(T);
2767210299Sed  if (!T->getAs<RecordType>()) {
2768210299Sed    S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
2769210299Sed    Attr.setInvalid();
2770210299Sed    return;
2771210299Sed  }
2772276479Sdim
2773276479Sdim  Expr *E = Attr.getArgAsExpr(0);
2774276479Sdim  uint32_t prioritynum;
2775276479Sdim  if (!checkUInt32Argument(S, Attr, E, prioritynum)) {
2776210299Sed    Attr.setInvalid();
2777210299Sed    return;
2778210299Sed  }
2779276479Sdim
2780210299Sed  if (prioritynum < 101 || prioritynum > 65535) {
2781210299Sed    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
2782296417Sdim      << E->getSourceRange() << Attr.getName() << 101 << 65535;
2783210299Sed    Attr.setInvalid();
2784210299Sed    return;
2785210299Sed  }
2786249423Sdim  D->addAttr(::new (S.Context)
2787249423Sdim             InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
2788249423Sdim                              Attr.getAttributeSpellingListIndex()));
2789210299Sed}
2790210299Sed
2791261991SdimFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range,
2792261991Sdim                                  IdentifierInfo *Format, int FormatIdx,
2793261991Sdim                                  int FirstArg,
2794249423Sdim                                  unsigned AttrSpellingListIndex) {
2795239462Sdim  // Check whether we already have an equivalent format attribute.
2796276479Sdim  for (auto *F : D->specific_attrs<FormatAttr>()) {
2797276479Sdim    if (F->getType() == Format &&
2798276479Sdim        F->getFormatIdx() == FormatIdx &&
2799276479Sdim        F->getFirstArg() == FirstArg) {
2800239462Sdim      // If we don't have a valid location for this attribute, adopt the
2801239462Sdim      // location.
2802276479Sdim      if (F->getLocation().isInvalid())
2803276479Sdim        F->setRange(Range);
2804276479Sdim      return nullptr;
2805239462Sdim    }
2806239462Sdim  }
2807239462Sdim
2808261991Sdim  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
2809261991Sdim                                    FirstArg, AttrSpellingListIndex);
2810239462Sdim}
2811239462Sdim
2812198092Srdivacky/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
2813198092Srdivacky/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
2814224145Sdimstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) {
2815261991Sdim  if (!Attr.isArgIdent(0)) {
2816261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
2817261991Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
2818193326Sed    return;
2819193326Sed  }
2820193326Sed
2821218893Sdim  // In C++ the implicit 'this' function parameter also counts, and they are
2822218893Sdim  // counted from one.
2823224145Sdim  bool HasImplicitThisParam = isInstanceMethod(D);
2824276479Sdim  unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
2825193326Sed
2826261991Sdim  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
2827261991Sdim  StringRef Format = II->getName();
2828193326Sed
2829296417Sdim  if (normalizeName(Format)) {
2830261991Sdim    // If we've modified the string name, we need a new identifier for it.
2831261991Sdim    II = &S.Context.Idents.get(Format);
2832261991Sdim  }
2833193326Sed
2834198398Srdivacky  // Check for supported formats.
2835198398Srdivacky  FormatAttrKind Kind = getFormatAttrKind(Format);
2836206084Srdivacky
2837206084Srdivacky  if (Kind == IgnoredFormat)
2838206084Srdivacky    return;
2839206084Srdivacky
2840198398Srdivacky  if (Kind == InvalidFormat) {
2841193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
2842276479Sdim      << Attr.getName() << II->getName();
2843193326Sed    return;
2844193326Sed  }
2845193326Sed
2846193326Sed  // checks for the 2nd argument
2847261991Sdim  Expr *IdxExpr = Attr.getArgAsExpr(1);
2848276479Sdim  uint32_t Idx;
2849276479Sdim  if (!checkUInt32Argument(S, Attr, IdxExpr, Idx, 2))
2850193326Sed    return;
2851193326Sed
2852276479Sdim  if (Idx < 1 || Idx > NumArgs) {
2853193326Sed    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
2854276479Sdim      << Attr.getName() << 2 << IdxExpr->getSourceRange();
2855193326Sed    return;
2856193326Sed  }
2857193326Sed
2858193326Sed  // FIXME: Do we need to bounds check?
2859276479Sdim  unsigned ArgIdx = Idx - 1;
2860198092Srdivacky
2861199482Srdivacky  if (HasImplicitThisParam) {
2862199482Srdivacky    if (ArgIdx == 0) {
2863218893Sdim      S.Diag(Attr.getLoc(),
2864218893Sdim             diag::err_format_attribute_implicit_this_format_string)
2865218893Sdim        << IdxExpr->getSourceRange();
2866199482Srdivacky      return;
2867199482Srdivacky    }
2868199482Srdivacky    ArgIdx--;
2869199482Srdivacky  }
2870198092Srdivacky
2871193326Sed  // make sure the format string is really a string
2872276479Sdim  QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
2873193326Sed
2874198398Srdivacky  if (Kind == CFStringFormat) {
2875193326Sed    if (!isCFStringType(Ty, S.Context)) {
2876193326Sed      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2877280031Sdim        << "a CFString" << IdxExpr->getSourceRange()
2878280031Sdim        << getFunctionOrMethodParamRange(D, ArgIdx);
2879193326Sed      return;
2880193326Sed    }
2881198398Srdivacky  } else if (Kind == NSStringFormat) {
2882193326Sed    // FIXME: do we need to check if the type is NSString*?  What are the
2883193326Sed    // semantics?
2884193326Sed    if (!isNSStringType(Ty, S.Context)) {
2885193326Sed      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2886280031Sdim        << "an NSString" << IdxExpr->getSourceRange()
2887280031Sdim        << getFunctionOrMethodParamRange(D, ArgIdx);
2888193326Sed      return;
2889198092Srdivacky    }
2890193326Sed  } else if (!Ty->isPointerType() ||
2891198092Srdivacky             !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) {
2892193326Sed    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
2893280031Sdim      << "a string type" << IdxExpr->getSourceRange()
2894280031Sdim      << getFunctionOrMethodParamRange(D, ArgIdx);
2895193326Sed    return;
2896193326Sed  }
2897193326Sed
2898193326Sed  // check the 3rd argument
2899261991Sdim  Expr *FirstArgExpr = Attr.getArgAsExpr(2);
2900276479Sdim  uint32_t FirstArg;
2901276479Sdim  if (!checkUInt32Argument(S, Attr, FirstArgExpr, FirstArg, 3))
2902193326Sed    return;
2903193326Sed
2904193326Sed  // check if the function is variadic if the 3rd argument non-zero
2905193326Sed  if (FirstArg != 0) {
2906224145Sdim    if (isFunctionOrMethodVariadic(D)) {
2907193326Sed      ++NumArgs; // +1 for ...
2908193326Sed    } else {
2909224145Sdim      S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
2910193326Sed      return;
2911193326Sed    }
2912193326Sed  }
2913193326Sed
2914193326Sed  // strftime requires FirstArg to be 0 because it doesn't read from any
2915193326Sed  // variable the input is just the current time + the format string.
2916198398Srdivacky  if (Kind == StrftimeFormat) {
2917193326Sed    if (FirstArg != 0) {
2918193326Sed      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
2919193326Sed        << FirstArgExpr->getSourceRange();
2920193326Sed      return;
2921193326Sed    }
2922193326Sed  // if 0 it disables parameter checking (to use with e.g. va_list)
2923193326Sed  } else if (FirstArg != 0 && FirstArg != NumArgs) {
2924193326Sed    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
2925276479Sdim      << Attr.getName() << 3 << FirstArgExpr->getSourceRange();
2926193326Sed    return;
2927193326Sed  }
2928193326Sed
2929261991Sdim  FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II,
2930276479Sdim                                          Idx, FirstArg,
2931249423Sdim                                          Attr.getAttributeSpellingListIndex());
2932239462Sdim  if (NewAttr)
2933239462Sdim    D->addAttr(NewAttr);
2934193326Sed}
2935193326Sed
2936224145Sdimstatic void handleTransparentUnionAttr(Sema &S, Decl *D,
2937224145Sdim                                       const AttributeList &Attr) {
2938193326Sed  // Try to find the underlying union declaration.
2939276479Sdim  RecordDecl *RD = nullptr;
2940224145Sdim  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
2941193326Sed  if (TD && TD->getUnderlyingType()->isUnionType())
2942193326Sed    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
2943193326Sed  else
2944224145Sdim    RD = dyn_cast<RecordDecl>(D);
2945193326Sed
2946193326Sed  if (!RD || !RD->isUnion()) {
2947193326Sed    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
2948221345Sdim      << Attr.getName() << ExpectedUnion;
2949193326Sed    return;
2950193326Sed  }
2951193326Sed
2952226633Sdim  if (!RD->isCompleteDefinition()) {
2953198092Srdivacky    S.Diag(Attr.getLoc(),
2954193326Sed        diag::warn_transparent_union_attribute_not_definition);
2955193326Sed    return;
2956193326Sed  }
2957193326Sed
2958195341Sed  RecordDecl::field_iterator Field = RD->field_begin(),
2959195341Sed                          FieldEnd = RD->field_end();
2960193326Sed  if (Field == FieldEnd) {
2961193326Sed    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
2962193326Sed    return;
2963193326Sed  }
2964193326Sed
2965193326Sed  FieldDecl *FirstField = *Field;
2966193326Sed  QualType FirstType = FirstField->getType();
2967210299Sed  if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
2968198092Srdivacky    S.Diag(FirstField->getLocation(),
2969210299Sed           diag::warn_transparent_union_attribute_floating)
2970210299Sed      << FirstType->isVectorType() << FirstType;
2971193326Sed    return;
2972193326Sed  }
2973193326Sed
2974193326Sed  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
2975193326Sed  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
2976193326Sed  for (; Field != FieldEnd; ++Field) {
2977193326Sed    QualType FieldType = Field->getType();
2978276479Sdim    // FIXME: this isn't fully correct; we also need to test whether the
2979276479Sdim    // members of the union would all have the same calling convention as the
2980276479Sdim    // first member of the union. Checking just the size and alignment isn't
2981276479Sdim    // sufficient (consider structs passed on the stack instead of in registers
2982276479Sdim    // as an example).
2983193326Sed    if (S.Context.getTypeSize(FieldType) != FirstSize ||
2984276479Sdim        S.Context.getTypeAlign(FieldType) > FirstAlign) {
2985193326Sed      // Warn if we drop the attribute.
2986193326Sed      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
2987198092Srdivacky      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
2988193326Sed                                 : S.Context.getTypeAlign(FieldType);
2989198092Srdivacky      S.Diag(Field->getLocation(),
2990193326Sed          diag::warn_transparent_union_attribute_field_size_align)
2991193326Sed        << isSize << Field->getDeclName() << FieldBits;
2992193326Sed      unsigned FirstBits = isSize? FirstSize : FirstAlign;
2993198092Srdivacky      S.Diag(FirstField->getLocation(),
2994193326Sed             diag::note_transparent_union_first_field_size_align)
2995193326Sed        << isSize << FirstBits;
2996193326Sed      return;
2997193326Sed    }
2998193326Sed  }
2999193326Sed
3000249423Sdim  RD->addAttr(::new (S.Context)
3001249423Sdim              TransparentUnionAttr(Attr.getRange(), S.Context,
3002249423Sdim                                   Attr.getAttributeSpellingListIndex()));
3003193326Sed}
3004193326Sed
3005224145Sdimstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3006193326Sed  // Make sure that there is a string literal as the annotation's single
3007193326Sed  // argument.
3008261991Sdim  StringRef Str;
3009261991Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
3010193326Sed    return;
3011226633Sdim
3012226633Sdim  // Don't duplicate annotations that are already set.
3013276479Sdim  for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
3014276479Sdim    if (I->getAnnotation() == Str)
3015261991Sdim      return;
3016226633Sdim  }
3017249423Sdim
3018249423Sdim  D->addAttr(::new (S.Context)
3019261991Sdim             AnnotateAttr(Attr.getRange(), S.Context, Str,
3020249423Sdim                          Attr.getAttributeSpellingListIndex()));
3021193326Sed}
3022193326Sed
3023280031Sdimstatic void handleAlignValueAttr(Sema &S, Decl *D,
3024280031Sdim                                 const AttributeList &Attr) {
3025280031Sdim  S.AddAlignValueAttr(Attr.getRange(), D, Attr.getArgAsExpr(0),
3026280031Sdim                      Attr.getAttributeSpellingListIndex());
3027280031Sdim}
3028280031Sdim
3029280031Sdimvoid Sema::AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E,
3030280031Sdim                             unsigned SpellingListIndex) {
3031280031Sdim  AlignValueAttr TmpAttr(AttrRange, Context, E, SpellingListIndex);
3032280031Sdim  SourceLocation AttrLoc = AttrRange.getBegin();
3033280031Sdim
3034280031Sdim  QualType T;
3035280031Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3036280031Sdim    T = TD->getUnderlyingType();
3037280031Sdim  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3038280031Sdim    T = VD->getType();
3039280031Sdim  else
3040280031Sdim    llvm_unreachable("Unknown decl type for align_value");
3041280031Sdim
3042280031Sdim  if (!T->isDependentType() && !T->isAnyPointerType() &&
3043280031Sdim      !T->isReferenceType() && !T->isMemberPointerType()) {
3044280031Sdim    Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
3045280031Sdim      << &TmpAttr /*TmpAttr.getName()*/ << T << D->getSourceRange();
3046280031Sdim    return;
3047280031Sdim  }
3048280031Sdim
3049280031Sdim  if (!E->isValueDependent()) {
3050296417Sdim    llvm::APSInt Alignment;
3051280031Sdim    ExprResult ICE
3052280031Sdim      = VerifyIntegerConstantExpression(E, &Alignment,
3053280031Sdim          diag::err_align_value_attribute_argument_not_int,
3054280031Sdim            /*AllowFold*/ false);
3055280031Sdim    if (ICE.isInvalid())
3056280031Sdim      return;
3057280031Sdim
3058280031Sdim    if (!Alignment.isPowerOf2()) {
3059280031Sdim      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
3060280031Sdim        << E->getSourceRange();
3061280031Sdim      return;
3062280031Sdim    }
3063280031Sdim
3064280031Sdim    D->addAttr(::new (Context)
3065280031Sdim               AlignValueAttr(AttrRange, Context, ICE.get(),
3066280031Sdim               SpellingListIndex));
3067280031Sdim    return;
3068280031Sdim  }
3069280031Sdim
3070280031Sdim  // Save dependent expressions in the AST to be instantiated.
3071280031Sdim  D->addAttr(::new (Context) AlignValueAttr(TmpAttr));
3072280031Sdim  return;
3073280031Sdim}
3074280031Sdim
3075224145Sdimstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3076193326Sed  // check the attribute arguments.
3077193326Sed  if (Attr.getNumArgs() > 1) {
3078261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
3079261991Sdim      << Attr.getName() << 1;
3080193326Sed    return;
3081193326Sed  }
3082239462Sdim
3083193326Sed  if (Attr.getNumArgs() == 0) {
3084249423Sdim    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
3085276479Sdim               true, nullptr, Attr.getAttributeSpellingListIndex()));
3086193326Sed    return;
3087193326Sed  }
3088198092Srdivacky
3089261991Sdim  Expr *E = Attr.getArgAsExpr(0);
3090249423Sdim  if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
3091249423Sdim    S.Diag(Attr.getEllipsisLoc(),
3092249423Sdim           diag::err_pack_expansion_without_parameter_packs);
3093249423Sdim    return;
3094249423Sdim  }
3095210299Sed
3096249423Sdim  if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
3097234353Sdim    return;
3098234353Sdim
3099288943Sdim  if (E->isValueDependent()) {
3100288943Sdim    if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
3101288943Sdim      if (!TND->getUnderlyingType()->isDependentType()) {
3102288943Sdim        S.Diag(Attr.getLoc(), diag::err_alignment_dependent_typedef_name)
3103288943Sdim            << E->getSourceRange();
3104288943Sdim        return;
3105288943Sdim      }
3106288943Sdim    }
3107288943Sdim  }
3108288943Sdim
3109249423Sdim  S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(),
3110249423Sdim                   Attr.isPackExpansion());
3111249423Sdim}
3112249423Sdim
3113249423Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
3114249423Sdim                          unsigned SpellingListIndex, bool IsPackExpansion) {
3115249423Sdim  AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex);
3116249423Sdim  SourceLocation AttrLoc = AttrRange.getBegin();
3117249423Sdim
3118249423Sdim  // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
3119249423Sdim  if (TmpAttr.isAlignas()) {
3120249423Sdim    // C++11 [dcl.align]p1:
3121249423Sdim    //   An alignment-specifier may be applied to a variable or to a class
3122249423Sdim    //   data member, but it shall not be applied to a bit-field, a function
3123249423Sdim    //   parameter, the formal parameter of a catch clause, or a variable
3124249423Sdim    //   declared with the register storage class specifier. An
3125249423Sdim    //   alignment-specifier may also be applied to the declaration of a class
3126249423Sdim    //   or enumeration type.
3127249423Sdim    // C11 6.7.5/2:
3128249423Sdim    //   An alignment attribute shall not be specified in a declaration of
3129249423Sdim    //   a typedef, or a bit-field, or a function, or a parameter, or an
3130249423Sdim    //   object declared with the register storage-class specifier.
3131249423Sdim    int DiagKind = -1;
3132249423Sdim    if (isa<ParmVarDecl>(D)) {
3133249423Sdim      DiagKind = 0;
3134249423Sdim    } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
3135249423Sdim      if (VD->getStorageClass() == SC_Register)
3136249423Sdim        DiagKind = 1;
3137249423Sdim      if (VD->isExceptionVariable())
3138249423Sdim        DiagKind = 2;
3139249423Sdim    } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
3140249423Sdim      if (FD->isBitField())
3141249423Sdim        DiagKind = 3;
3142249423Sdim    } else if (!isa<TagDecl>(D)) {
3143276479Sdim      Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr
3144249423Sdim        << (TmpAttr.isC11() ? ExpectedVariableOrField
3145249423Sdim                            : ExpectedVariableFieldOrTag);
3146249423Sdim      return;
3147249423Sdim    }
3148249423Sdim    if (DiagKind != -1) {
3149249423Sdim      Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
3150276479Sdim        << &TmpAttr << DiagKind;
3151249423Sdim      return;
3152249423Sdim    }
3153249423Sdim  }
3154249423Sdim
3155210299Sed  if (E->isTypeDependent() || E->isValueDependent()) {
3156210299Sed    // Save dependent expressions in the AST to be instantiated.
3157249423Sdim    AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr);
3158249423Sdim    AA->setPackExpansion(IsPackExpansion);
3159249423Sdim    D->addAttr(AA);
3160210299Sed    return;
3161210299Sed  }
3162249423Sdim
3163212904Sdim  // FIXME: Cache the number on the Attr object?
3164296417Sdim  llvm::APSInt Alignment;
3165239462Sdim  ExprResult ICE
3166239462Sdim    = VerifyIntegerConstantExpression(E, &Alignment,
3167239462Sdim        diag::err_aligned_attribute_argument_not_int,
3168239462Sdim        /*AllowFold*/ false);
3169234353Sdim  if (ICE.isInvalid())
3170193326Sed    return;
3171249423Sdim
3172296417Sdim  uint64_t AlignVal = Alignment.getZExtValue();
3173296417Sdim
3174249423Sdim  // C++11 [dcl.align]p2:
3175249423Sdim  //   -- if the constant expression evaluates to zero, the alignment
3176249423Sdim  //      specifier shall have no effect
3177249423Sdim  // C11 6.7.5p6:
3178249423Sdim  //   An alignment specification of zero has no effect.
3179288943Sdim  if (!(TmpAttr.isAlignas() && !Alignment)) {
3180296417Sdim    if (!llvm::isPowerOf2_64(AlignVal)) {
3181288943Sdim      Diag(AttrLoc, diag::err_alignment_not_power_of_two)
3182288943Sdim        << E->getSourceRange();
3183288943Sdim      return;
3184288943Sdim    }
3185193326Sed  }
3186249423Sdim
3187276479Sdim  // Alignment calculations can wrap around if it's greater than 2**28.
3188296417Sdim  unsigned MaxValidAlignment =
3189296417Sdim      Context.getTargetInfo().getTriple().isOSBinFormatCOFF() ? 8192
3190296417Sdim                                                              : 268435456;
3191296417Sdim  if (AlignVal > MaxValidAlignment) {
3192276479Sdim    Diag(AttrLoc, diag::err_attribute_aligned_too_great) << MaxValidAlignment
3193276479Sdim                                                         << E->getSourceRange();
3194276479Sdim    return;
3195239462Sdim  }
3196193326Sed
3197296417Sdim  if (Context.getTargetInfo().isTLSSupported()) {
3198296417Sdim    unsigned MaxTLSAlign =
3199296417Sdim        Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())
3200296417Sdim            .getQuantity();
3201296417Sdim    auto *VD = dyn_cast<VarDecl>(D);
3202296417Sdim    if (MaxTLSAlign && AlignVal > MaxTLSAlign && VD &&
3203296417Sdim        VD->getTLSKind() != VarDecl::TLS_None) {
3204296417Sdim      Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
3205296417Sdim          << (unsigned)AlignVal << VD << MaxTLSAlign;
3206296417Sdim      return;
3207296417Sdim    }
3208296417Sdim  }
3209296417Sdim
3210249423Sdim  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
3211276479Sdim                                                ICE.get(), SpellingListIndex);
3212249423Sdim  AA->setPackExpansion(IsPackExpansion);
3213249423Sdim  D->addAttr(AA);
3214193326Sed}
3215193326Sed
3216249423Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
3217249423Sdim                          unsigned SpellingListIndex, bool IsPackExpansion) {
3218212904Sdim  // FIXME: Cache the number on the Attr object if non-dependent?
3219212904Sdim  // FIXME: Perform checking of type validity
3220249423Sdim  AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS,
3221249423Sdim                                                SpellingListIndex);
3222249423Sdim  AA->setPackExpansion(IsPackExpansion);
3223249423Sdim  D->addAttr(AA);
3224212904Sdim}
3225212904Sdim
3226249423Sdimvoid Sema::CheckAlignasUnderalignment(Decl *D) {
3227249423Sdim  assert(D->hasAttrs() && "no attributes on decl");
3228249423Sdim
3229288943Sdim  QualType UnderlyingTy, DiagTy;
3230288943Sdim  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
3231288943Sdim    UnderlyingTy = DiagTy = VD->getType();
3232288943Sdim  } else {
3233288943Sdim    UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));
3234288943Sdim    if (EnumDecl *ED = dyn_cast<EnumDecl>(D))
3235288943Sdim      UnderlyingTy = ED->getIntegerType();
3236288943Sdim  }
3237288943Sdim  if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
3238249423Sdim    return;
3239249423Sdim
3240249423Sdim  // C++11 [dcl.align]p5, C11 6.7.5/4:
3241249423Sdim  //   The combined effect of all alignment attributes in a declaration shall
3242249423Sdim  //   not specify an alignment that is less strict than the alignment that
3243249423Sdim  //   would otherwise be required for the entity being declared.
3244276479Sdim  AlignedAttr *AlignasAttr = nullptr;
3245249423Sdim  unsigned Align = 0;
3246276479Sdim  for (auto *I : D->specific_attrs<AlignedAttr>()) {
3247249423Sdim    if (I->isAlignmentDependent())
3248249423Sdim      return;
3249249423Sdim    if (I->isAlignas())
3250276479Sdim      AlignasAttr = I;
3251249423Sdim    Align = std::max(Align, I->getAlignment(Context));
3252249423Sdim  }
3253249423Sdim
3254249423Sdim  if (AlignasAttr && Align) {
3255249423Sdim    CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
3256288943Sdim    CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
3257249423Sdim    if (NaturalAlign > RequestedAlign)
3258249423Sdim      Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
3259288943Sdim        << DiagTy << (unsigned)NaturalAlign.getQuantity();
3260249423Sdim  }
3261249423Sdim}
3262249423Sdim
3263276479Sdimbool Sema::checkMSInheritanceAttrOnDefinition(
3264276479Sdim    CXXRecordDecl *RD, SourceRange Range, bool BestCase,
3265276479Sdim    MSInheritanceAttr::Spelling SemanticSpelling) {
3266276479Sdim  assert(RD->hasDefinition() && "RD has no definition!");
3267276479Sdim
3268276479Sdim  // We may not have seen base specifiers or any virtual methods yet.  We will
3269276479Sdim  // have to wait until the record is defined to catch any mismatches.
3270276479Sdim  if (!RD->getDefinition()->isCompleteDefinition())
3271276479Sdim    return false;
3272276479Sdim
3273276479Sdim  // The unspecified model never matches what a definition could need.
3274276479Sdim  if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance)
3275276479Sdim    return false;
3276276479Sdim
3277276479Sdim  if (BestCase) {
3278276479Sdim    if (RD->calculateInheritanceModel() == SemanticSpelling)
3279276479Sdim      return false;
3280276479Sdim  } else {
3281276479Sdim    if (RD->calculateInheritanceModel() <= SemanticSpelling)
3282276479Sdim      return false;
3283276479Sdim  }
3284276479Sdim
3285276479Sdim  Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
3286276479Sdim      << 0 /*definition*/;
3287276479Sdim  Diag(RD->getDefinition()->getLocation(), diag::note_defined_here)
3288276479Sdim      << RD->getNameAsString();
3289276479Sdim  return true;
3290276479Sdim}
3291276479Sdim
3292296417Sdim/// parseModeAttrArg - Parses attribute mode string and returns parsed type
3293296417Sdim/// attribute.
3294296417Sdimstatic void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
3295296417Sdim                             bool &IntegerMode, bool &ComplexMode) {
3296198398Srdivacky  switch (Str.size()) {
3297193326Sed  case 2:
3298193326Sed    switch (Str[0]) {
3299296417Sdim    case 'Q':
3300296417Sdim      DestWidth = 8;
3301296417Sdim      break;
3302296417Sdim    case 'H':
3303296417Sdim      DestWidth = 16;
3304296417Sdim      break;
3305296417Sdim    case 'S':
3306296417Sdim      DestWidth = 32;
3307296417Sdim      break;
3308296417Sdim    case 'D':
3309296417Sdim      DestWidth = 64;
3310296417Sdim      break;
3311296417Sdim    case 'X':
3312296417Sdim      DestWidth = 96;
3313296417Sdim      break;
3314296417Sdim    case 'T':
3315296417Sdim      DestWidth = 128;
3316296417Sdim      break;
3317193326Sed    }
3318193326Sed    if (Str[1] == 'F') {
3319193326Sed      IntegerMode = false;
3320193326Sed    } else if (Str[1] == 'C') {
3321193326Sed      IntegerMode = false;
3322193326Sed      ComplexMode = true;
3323193326Sed    } else if (Str[1] != 'I') {
3324193326Sed      DestWidth = 0;
3325193326Sed    }
3326193326Sed    break;
3327193326Sed  case 4:
3328193326Sed    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
3329193326Sed    // pointer on PIC16 and other embedded platforms.
3330198398Srdivacky    if (Str == "word")
3331226633Sdim      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3332198398Srdivacky    else if (Str == "byte")
3333226633Sdim      DestWidth = S.Context.getTargetInfo().getCharWidth();
3334193326Sed    break;
3335193326Sed  case 7:
3336198398Srdivacky    if (Str == "pointer")
3337226633Sdim      DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
3338193326Sed    break;
3339249423Sdim  case 11:
3340249423Sdim    if (Str == "unwind_word")
3341249423Sdim      DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
3342249423Sdim    break;
3343193326Sed  }
3344296417Sdim}
3345193326Sed
3346296417Sdim/// handleModeAttr - This attribute modifies the width of a decl with primitive
3347296417Sdim/// type.
3348296417Sdim///
3349296417Sdim/// Despite what would be logical, the mode attribute is a decl attribute, not a
3350296417Sdim/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
3351296417Sdim/// HImode, not an intermediate pointer.
3352296417Sdimstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3353296417Sdim  // This attribute isn't documented, but glibc uses it.  It changes
3354296417Sdim  // the width of an int or unsigned int to the specified size.
3355296417Sdim  if (!Attr.isArgIdent(0)) {
3356296417Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
3357296417Sdim      << AANT_ArgumentIdentifier;
3358296417Sdim    return;
3359296417Sdim  }
3360296417Sdim
3361296417Sdim  IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident;
3362296417Sdim  StringRef Str = Name->getName();
3363296417Sdim
3364296417Sdim  normalizeName(Str);
3365296417Sdim
3366296417Sdim  unsigned DestWidth = 0;
3367296417Sdim  bool IntegerMode = true;
3368296417Sdim  bool ComplexMode = false;
3369296417Sdim  llvm::APInt VectorSize(64, 0);
3370296417Sdim  if (Str.size() >= 4 && Str[0] == 'V') {
3371296417Sdim    // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
3372296417Sdim    size_t StrSize = Str.size();
3373296417Sdim    size_t VectorStringLength = 0;
3374296417Sdim    while ((VectorStringLength + 1) < StrSize &&
3375296417Sdim           isdigit(Str[VectorStringLength + 1]))
3376296417Sdim      ++VectorStringLength;
3377296417Sdim    if (VectorStringLength &&
3378296417Sdim        !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
3379296417Sdim        VectorSize.isPowerOf2()) {
3380296417Sdim      parseModeAttrArg(S, Str.substr(VectorStringLength + 1), DestWidth,
3381296417Sdim                       IntegerMode, ComplexMode);
3382296417Sdim      S.Diag(Attr.getLoc(), diag::warn_vector_mode_deprecated);
3383296417Sdim    } else {
3384296417Sdim      VectorSize = 0;
3385296417Sdim    }
3386296417Sdim  }
3387296417Sdim
3388296417Sdim  if (!VectorSize)
3389296417Sdim    parseModeAttrArg(S, Str, DestWidth, IntegerMode, ComplexMode);
3390296417Sdim
3391193326Sed  QualType OldTy;
3392221345Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3393193326Sed    OldTy = TD->getUnderlyingType();
3394193326Sed  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
3395193326Sed    OldTy = VD->getType();
3396193326Sed  else {
3397193326Sed    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
3398276479Sdim      << Attr.getName() << Attr.getRange();
3399193326Sed    return;
3400193326Sed  }
3401193326Sed
3402288943Sdim  // Base type can also be a vector type (see PR17453).
3403288943Sdim  // Distinguish between base type and base element type.
3404288943Sdim  QualType OldElemTy = OldTy;
3405288943Sdim  if (const VectorType *VT = OldTy->getAs<VectorType>())
3406288943Sdim    OldElemTy = VT->getElementType();
3407288943Sdim
3408288943Sdim  if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType())
3409193326Sed    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
3410193326Sed  else if (IntegerMode) {
3411288943Sdim    if (!OldElemTy->isIntegralOrEnumerationType())
3412193326Sed      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3413193326Sed  } else if (ComplexMode) {
3414288943Sdim    if (!OldElemTy->isComplexType())
3415193326Sed      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3416193326Sed  } else {
3417288943Sdim    if (!OldElemTy->isFloatingType())
3418193326Sed      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3419193326Sed  }
3420193326Sed
3421193326Sed  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
3422193326Sed  // and friends, at least with glibc.
3423193326Sed  // FIXME: Make sure floating-point mappings are accurate
3424193326Sed  // FIXME: Support XF and TF types
3425261991Sdim  if (!DestWidth) {
3426276479Sdim    S.Diag(Attr.getLoc(), diag::err_machine_mode) << 0 /*Unknown*/ << Name;
3427193326Sed    return;
3428261991Sdim  }
3429261991Sdim
3430288943Sdim  QualType NewElemTy;
3431261991Sdim
3432261991Sdim  if (IntegerMode)
3433288943Sdim    NewElemTy = S.Context.getIntTypeForBitwidth(
3434288943Sdim        DestWidth, OldElemTy->isSignedIntegerType());
3435261991Sdim  else
3436288943Sdim    NewElemTy = S.Context.getRealTypeForBitwidth(DestWidth);
3437261991Sdim
3438288943Sdim  if (NewElemTy.isNull()) {
3439276479Sdim    S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
3440193326Sed    return;
3441193326Sed  }
3442193326Sed
3443193326Sed  if (ComplexMode) {
3444288943Sdim    NewElemTy = S.Context.getComplexType(NewElemTy);
3445193326Sed  }
3446193326Sed
3447288943Sdim  QualType NewTy = NewElemTy;
3448296417Sdim  if (VectorSize.getBoolValue()) {
3449296417Sdim    NewTy = S.Context.getVectorType(NewTy, VectorSize.getZExtValue(),
3450296417Sdim                                    VectorType::GenericVector);
3451296417Sdim  } else if (const VectorType *OldVT = OldTy->getAs<VectorType>()) {
3452288943Sdim    // Complex machine mode does not support base vector types.
3453288943Sdim    if (ComplexMode) {
3454288943Sdim      S.Diag(Attr.getLoc(), diag::err_complex_mode_vector_type);
3455288943Sdim      return;
3456288943Sdim    }
3457288943Sdim    unsigned NumElements = S.Context.getTypeSize(OldElemTy) *
3458288943Sdim                           OldVT->getNumElements() /
3459288943Sdim                           S.Context.getTypeSize(NewElemTy);
3460288943Sdim    NewTy =
3461288943Sdim        S.Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
3462288943Sdim  }
3463288943Sdim
3464288943Sdim  if (NewTy.isNull()) {
3465288943Sdim    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
3466288943Sdim    return;
3467288943Sdim  }
3468288943Sdim
3469193326Sed  // Install the new type.
3470261991Sdim  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
3471261991Sdim    TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
3472261991Sdim  else
3473193326Sed    cast<ValueDecl>(D)->setType(NewTy);
3474261991Sdim
3475261991Sdim  D->addAttr(::new (S.Context)
3476261991Sdim             ModeAttr(Attr.getRange(), S.Context, Name,
3477261991Sdim                      Attr.getAttributeSpellingListIndex()));
3478193326Sed}
3479193326Sed
3480224145Sdimstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3481239462Sdim  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3482239462Sdim    if (!VD->hasGlobalStorage())
3483239462Sdim      S.Diag(Attr.getLoc(),
3484239462Sdim             diag::warn_attribute_requires_functions_or_static_globals)
3485239462Sdim        << Attr.getName();
3486239462Sdim  } else if (!isFunctionOrMethod(D)) {
3487239462Sdim    S.Diag(Attr.getLoc(),
3488239462Sdim           diag::warn_attribute_requires_functions_or_static_globals)
3489239462Sdim      << Attr.getName();
3490193326Sed    return;
3491193326Sed  }
3492198092Srdivacky
3493249423Sdim  D->addAttr(::new (S.Context)
3494249423Sdim             NoDebugAttr(Attr.getRange(), S.Context,
3495249423Sdim                         Attr.getAttributeSpellingListIndex()));
3496193326Sed}
3497193326Sed
3498280031SdimAlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D, SourceRange Range,
3499280031Sdim                                              IdentifierInfo *Ident,
3500280031Sdim                                              unsigned AttrSpellingListIndex) {
3501280031Sdim  if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
3502280031Sdim    Diag(Range.getBegin(), diag::warn_attribute_ignored) << Ident;
3503280031Sdim    Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
3504280031Sdim    return nullptr;
3505280031Sdim  }
3506280031Sdim
3507280031Sdim  if (D->hasAttr<AlwaysInlineAttr>())
3508280031Sdim    return nullptr;
3509280031Sdim
3510280031Sdim  return ::new (Context) AlwaysInlineAttr(Range, Context,
3511280031Sdim                                          AttrSpellingListIndex);
3512280031Sdim}
3513280031Sdim
3514296417SdimCommonAttr *Sema::mergeCommonAttr(Decl *D, SourceRange Range,
3515296417Sdim                                  IdentifierInfo *Ident,
3516296417Sdim                                  unsigned AttrSpellingListIndex) {
3517296417Sdim  if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, Range, Ident))
3518296417Sdim    return nullptr;
3519296417Sdim
3520296417Sdim  return ::new (Context) CommonAttr(Range, Context, AttrSpellingListIndex);
3521296417Sdim}
3522296417Sdim
3523296417SdimInternalLinkageAttr *
3524296417SdimSema::mergeInternalLinkageAttr(Decl *D, SourceRange Range,
3525296417Sdim                               IdentifierInfo *Ident,
3526296417Sdim                               unsigned AttrSpellingListIndex) {
3527296417Sdim  if (auto VD = dyn_cast<VarDecl>(D)) {
3528296417Sdim    // Attribute applies to Var but not any subclass of it (like ParmVar,
3529296417Sdim    // ImplicitParm or VarTemplateSpecialization).
3530296417Sdim    if (VD->getKind() != Decl::Var) {
3531296417Sdim      Diag(Range.getBegin(), diag::warn_attribute_wrong_decl_type)
3532296417Sdim          << Ident << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
3533296417Sdim                                               : ExpectedVariableOrFunction);
3534296417Sdim      return nullptr;
3535296417Sdim    }
3536296417Sdim    // Attribute does not apply to non-static local variables.
3537296417Sdim    if (VD->hasLocalStorage()) {
3538296417Sdim      Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
3539296417Sdim      return nullptr;
3540296417Sdim    }
3541296417Sdim  }
3542296417Sdim
3543296417Sdim  if (checkAttrMutualExclusion<CommonAttr>(*this, D, Range, Ident))
3544296417Sdim    return nullptr;
3545296417Sdim
3546296417Sdim  return ::new (Context)
3547296417Sdim      InternalLinkageAttr(Range, Context, AttrSpellingListIndex);
3548296417Sdim}
3549296417Sdim
3550280031SdimMinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range,
3551280031Sdim                                    unsigned AttrSpellingListIndex) {
3552280031Sdim  if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
3553280031Sdim    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'minsize'";
3554280031Sdim    Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
3555280031Sdim    return nullptr;
3556280031Sdim  }
3557280031Sdim
3558280031Sdim  if (D->hasAttr<MinSizeAttr>())
3559280031Sdim    return nullptr;
3560280031Sdim
3561280031Sdim  return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex);
3562280031Sdim}
3563280031Sdim
3564280031SdimOptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
3565280031Sdim                                              unsigned AttrSpellingListIndex) {
3566280031Sdim  if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
3567280031Sdim    Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
3568280031Sdim    Diag(Range.getBegin(), diag::note_conflicting_attribute);
3569280031Sdim    D->dropAttr<AlwaysInlineAttr>();
3570280031Sdim  }
3571280031Sdim  if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
3572280031Sdim    Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
3573280031Sdim    Diag(Range.getBegin(), diag::note_conflicting_attribute);
3574280031Sdim    D->dropAttr<MinSizeAttr>();
3575280031Sdim  }
3576280031Sdim
3577280031Sdim  if (D->hasAttr<OptimizeNoneAttr>())
3578280031Sdim    return nullptr;
3579280031Sdim
3580280031Sdim  return ::new (Context) OptimizeNoneAttr(Range, Context,
3581280031Sdim                                          AttrSpellingListIndex);
3582280031Sdim}
3583280031Sdim
3584276479Sdimstatic void handleAlwaysInlineAttr(Sema &S, Decl *D,
3585276479Sdim                                   const AttributeList &Attr) {
3586296417Sdim  if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, Attr.getRange(),
3587296417Sdim                                                  Attr.getName()))
3588296417Sdim    return;
3589296417Sdim
3590280031Sdim  if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr(
3591280031Sdim          D, Attr.getRange(), Attr.getName(),
3592280031Sdim          Attr.getAttributeSpellingListIndex()))
3593280031Sdim    D->addAttr(Inline);
3594280031Sdim}
3595198092Srdivacky
3596280031Sdimstatic void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3597280031Sdim  if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(
3598280031Sdim          D, Attr.getRange(), Attr.getAttributeSpellingListIndex()))
3599280031Sdim    D->addAttr(MinSize);
3600193326Sed}
3601193326Sed
3602276479Sdimstatic void handleOptimizeNoneAttr(Sema &S, Decl *D,
3603276479Sdim                                   const AttributeList &Attr) {
3604280031Sdim  if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(
3605280031Sdim          D, Attr.getRange(), Attr.getAttributeSpellingListIndex()))
3606280031Sdim    D->addAttr(Optnone);
3607218893Sdim}
3608218893Sdim
3609224145Sdimstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3610296417Sdim  if (checkAttrMutualExclusion<CUDADeviceAttr>(S, D, Attr.getRange(),
3611296417Sdim                                               Attr.getName()) ||
3612296417Sdim      checkAttrMutualExclusion<CUDAHostAttr>(S, D, Attr.getRange(),
3613296417Sdim                                             Attr.getName())) {
3614296417Sdim    return;
3615296417Sdim  }
3616276479Sdim  FunctionDecl *FD = cast<FunctionDecl>(D);
3617276479Sdim  if (!FD->getReturnType()->isVoidType()) {
3618276479Sdim    SourceRange RTRange = FD->getReturnTypeSourceRange();
3619276479Sdim    S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
3620276479Sdim        << FD->getType()
3621276479Sdim        << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
3622276479Sdim                              : FixItHint());
3623276479Sdim    return;
3624218893Sdim  }
3625218893Sdim
3626276479Sdim  D->addAttr(::new (S.Context)
3627276479Sdim              CUDAGlobalAttr(Attr.getRange(), S.Context,
3628280031Sdim                             Attr.getAttributeSpellingListIndex()));
3629296417Sdim
3630218893Sdim}
3631218893Sdim
3632224145Sdimstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3633276479Sdim  FunctionDecl *Fn = cast<FunctionDecl>(D);
3634198893Srdivacky  if (!Fn->isInlineSpecified()) {
3635193326Sed    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
3636193326Sed    return;
3637193326Sed  }
3638198092Srdivacky
3639249423Sdim  D->addAttr(::new (S.Context)
3640249423Sdim             GNUInlineAttr(Attr.getRange(), S.Context,
3641249423Sdim                           Attr.getAttributeSpellingListIndex()));
3642193326Sed}
3643193326Sed
3644224145Sdimstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3645224145Sdim  if (hasDeclarator(D)) return;
3646218893Sdim
3647224145Sdim  // Diagnostic is emitted elsewhere: here we store the (valid) Attr
3648207619Srdivacky  // in the Decl node for syntactic reasoning, e.g., pretty-printing.
3649218893Sdim  CallingConv CC;
3650288943Sdim  if (S.CheckCallingConvAttr(Attr, CC, /*FD*/nullptr))
3651218893Sdim    return;
3652207619Srdivacky
3653224145Sdim  if (!isa<ObjCMethodDecl>(D)) {
3654224145Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3655224145Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
3656218893Sdim    return;
3657218893Sdim  }
3658218893Sdim
3659224145Sdim  switch (Attr.getKind()) {
3660239462Sdim  case AttributeList::AT_FastCall:
3661249423Sdim    D->addAttr(::new (S.Context)
3662249423Sdim               FastCallAttr(Attr.getRange(), S.Context,
3663249423Sdim                            Attr.getAttributeSpellingListIndex()));
3664207619Srdivacky    return;
3665239462Sdim  case AttributeList::AT_StdCall:
3666249423Sdim    D->addAttr(::new (S.Context)
3667249423Sdim               StdCallAttr(Attr.getRange(), S.Context,
3668249423Sdim                           Attr.getAttributeSpellingListIndex()));
3669207619Srdivacky    return;
3670239462Sdim  case AttributeList::AT_ThisCall:
3671249423Sdim    D->addAttr(::new (S.Context)
3672249423Sdim               ThisCallAttr(Attr.getRange(), S.Context,
3673249423Sdim                            Attr.getAttributeSpellingListIndex()));
3674212904Sdim    return;
3675239462Sdim  case AttributeList::AT_CDecl:
3676249423Sdim    D->addAttr(::new (S.Context)
3677249423Sdim               CDeclAttr(Attr.getRange(), S.Context,
3678249423Sdim                         Attr.getAttributeSpellingListIndex()));
3679207619Srdivacky    return;
3680239462Sdim  case AttributeList::AT_Pascal:
3681249423Sdim    D->addAttr(::new (S.Context)
3682249423Sdim               PascalAttr(Attr.getRange(), S.Context,
3683249423Sdim                          Attr.getAttributeSpellingListIndex()));
3684212904Sdim    return;
3685280031Sdim  case AttributeList::AT_VectorCall:
3686280031Sdim    D->addAttr(::new (S.Context)
3687280031Sdim               VectorCallAttr(Attr.getRange(), S.Context,
3688280031Sdim                              Attr.getAttributeSpellingListIndex()));
3689280031Sdim    return;
3690256030Sdim  case AttributeList::AT_MSABI:
3691256030Sdim    D->addAttr(::new (S.Context)
3692256030Sdim               MSABIAttr(Attr.getRange(), S.Context,
3693256030Sdim                         Attr.getAttributeSpellingListIndex()));
3694256030Sdim    return;
3695256030Sdim  case AttributeList::AT_SysVABI:
3696256030Sdim    D->addAttr(::new (S.Context)
3697256030Sdim               SysVABIAttr(Attr.getRange(), S.Context,
3698256030Sdim                           Attr.getAttributeSpellingListIndex()));
3699256030Sdim    return;
3700239462Sdim  case AttributeList::AT_Pcs: {
3701221345Sdim    PcsAttr::PCSType PCS;
3702239462Sdim    switch (CC) {
3703239462Sdim    case CC_AAPCS:
3704221345Sdim      PCS = PcsAttr::AAPCS;
3705239462Sdim      break;
3706239462Sdim    case CC_AAPCS_VFP:
3707221345Sdim      PCS = PcsAttr::AAPCS_VFP;
3708239462Sdim      break;
3709239462Sdim    default:
3710239462Sdim      llvm_unreachable("unexpected calling convention in pcs attribute");
3711221345Sdim    }
3712221345Sdim
3713249423Sdim    D->addAttr(::new (S.Context)
3714249423Sdim               PcsAttr(Attr.getRange(), S.Context, PCS,
3715249423Sdim                       Attr.getAttributeSpellingListIndex()));
3716243830Sdim    return;
3717221345Sdim  }
3718249423Sdim  case AttributeList::AT_IntelOclBicc:
3719249423Sdim    D->addAttr(::new (S.Context)
3720249423Sdim               IntelOclBiccAttr(Attr.getRange(), S.Context,
3721249423Sdim                                Attr.getAttributeSpellingListIndex()));
3722249423Sdim    return;
3723243830Sdim
3724207619Srdivacky  default:
3725207619Srdivacky    llvm_unreachable("unexpected attribute kind");
3726207619Srdivacky  }
3727207619Srdivacky}
3728207619Srdivacky
3729249423Sdimbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
3730249423Sdim                                const FunctionDecl *FD) {
3731218893Sdim  if (attr.isInvalid())
3732218893Sdim    return true;
3733218893Sdim
3734239462Sdim  unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
3735261991Sdim  if (!checkAttributeNumArgs(*this, attr, ReqArgs)) {
3736218893Sdim    attr.setInvalid();
3737218893Sdim    return true;
3738193326Sed  }
3739193326Sed
3740276479Sdim  // TODO: diagnose uses of these conventions on the wrong target.
3741218893Sdim  switch (attr.getKind()) {
3742239462Sdim  case AttributeList::AT_CDecl: CC = CC_C; break;
3743239462Sdim  case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
3744239462Sdim  case AttributeList::AT_StdCall: CC = CC_X86StdCall; break;
3745239462Sdim  case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break;
3746239462Sdim  case AttributeList::AT_Pascal: CC = CC_X86Pascal; break;
3747280031Sdim  case AttributeList::AT_VectorCall: CC = CC_X86VectorCall; break;
3748256030Sdim  case AttributeList::AT_MSABI:
3749256030Sdim    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
3750256030Sdim                                                             CC_X86_64Win64;
3751256030Sdim    break;
3752256030Sdim  case AttributeList::AT_SysVABI:
3753256030Sdim    CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
3754256030Sdim                                                             CC_C;
3755256030Sdim    break;
3756239462Sdim  case AttributeList::AT_Pcs: {
3757261991Sdim    StringRef StrRef;
3758261991Sdim    if (!checkStringLiteralArgumentAttr(attr, 0, StrRef)) {
3759221345Sdim      attr.setInvalid();
3760221345Sdim      return true;
3761221345Sdim    }
3762221345Sdim    if (StrRef == "aapcs") {
3763221345Sdim      CC = CC_AAPCS;
3764221345Sdim      break;
3765221345Sdim    } else if (StrRef == "aapcs-vfp") {
3766221345Sdim      CC = CC_AAPCS_VFP;
3767221345Sdim      break;
3768221345Sdim    }
3769239462Sdim
3770239462Sdim    attr.setInvalid();
3771239462Sdim    Diag(attr.getLoc(), diag::err_invalid_pcs);
3772239462Sdim    return true;
3773221345Sdim  }
3774249423Sdim  case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break;
3775234353Sdim  default: llvm_unreachable("unexpected attribute kind");
3776218893Sdim  }
3777218893Sdim
3778243830Sdim  const TargetInfo &TI = Context.getTargetInfo();
3779243830Sdim  TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
3780288943Sdim  if (A != TargetInfo::CCCR_OK) {
3781288943Sdim    if (A == TargetInfo::CCCR_Warning)
3782288943Sdim      Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName();
3783249423Sdim
3784288943Sdim    // This convention is not valid for the target. Use the default function or
3785288943Sdim    // method calling convention.
3786249423Sdim    TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown;
3787249423Sdim    if (FD)
3788249423Sdim      MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member :
3789249423Sdim                                    TargetInfo::CCMT_NonMember;
3790249423Sdim    CC = TI.getDefaultCallingConv(MT);
3791243830Sdim  }
3792243830Sdim
3793218893Sdim  return false;
3794218893Sdim}
3795218893Sdim
3796218893Sdim/// Checks a regparm attribute, returning true if it is ill-formed and
3797218893Sdim/// otherwise setting numParams to the appropriate value.
3798224145Sdimbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
3799224145Sdim  if (Attr.isInvalid())
3800218893Sdim    return true;
3801218893Sdim
3802261991Sdim  if (!checkAttributeNumArgs(*this, Attr, 1)) {
3803224145Sdim    Attr.setInvalid();
3804218893Sdim    return true;
3805218893Sdim  }
3806218893Sdim
3807276479Sdim  uint32_t NP;
3808261991Sdim  Expr *NumParamsExpr = Attr.getArgAsExpr(0);
3809276479Sdim  if (!checkUInt32Argument(*this, Attr, NumParamsExpr, NP)) {
3810224145Sdim    Attr.setInvalid();
3811218893Sdim    return true;
3812193326Sed  }
3813193326Sed
3814226633Sdim  if (Context.getTargetInfo().getRegParmMax() == 0) {
3815224145Sdim    Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
3816193326Sed      << NumParamsExpr->getSourceRange();
3817224145Sdim    Attr.setInvalid();
3818218893Sdim    return true;
3819193326Sed  }
3820193326Sed
3821276479Sdim  numParams = NP;
3822226633Sdim  if (numParams > Context.getTargetInfo().getRegParmMax()) {
3823224145Sdim    Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
3824226633Sdim      << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
3825224145Sdim    Attr.setInvalid();
3826218893Sdim    return true;
3827193326Sed  }
3828193326Sed
3829218893Sdim  return false;
3830193326Sed}
3831193326Sed
3832288943Sdim// Checks whether an argument of launch_bounds attribute is acceptable
3833288943Sdim// May output an error.
3834288943Sdimstatic bool checkLaunchBoundsArgument(Sema &S, Expr *E,
3835288943Sdim                                      const CUDALaunchBoundsAttr &Attr,
3836288943Sdim                                      const unsigned Idx) {
3837288943Sdim
3838288943Sdim  if (S.DiagnoseUnexpandedParameterPack(E))
3839288943Sdim    return false;
3840288943Sdim
3841288943Sdim  // Accept template arguments for now as they depend on something else.
3842288943Sdim  // We'll get to check them when they eventually get instantiated.
3843288943Sdim  if (E->isValueDependent())
3844288943Sdim    return true;
3845288943Sdim
3846288943Sdim  llvm::APSInt I(64);
3847288943Sdim  if (!E->isIntegerConstantExpr(I, S.Context)) {
3848288943Sdim    S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
3849288943Sdim        << &Attr << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
3850288943Sdim    return false;
3851288943Sdim  }
3852288943Sdim  // Make sure we can fit it in 32 bits.
3853288943Sdim  if (!I.isIntN(32)) {
3854288943Sdim    S.Diag(E->getExprLoc(), diag::err_ice_too_large) << I.toString(10, false)
3855288943Sdim                                                     << 32 << /* Unsigned */ 1;
3856288943Sdim    return false;
3857288943Sdim  }
3858288943Sdim  if (I < 0)
3859288943Sdim    S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
3860288943Sdim        << &Attr << Idx << E->getSourceRange();
3861288943Sdim
3862288943Sdim  return true;
3863288943Sdim}
3864288943Sdim
3865288943Sdimvoid Sema::AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads,
3866288943Sdim                               Expr *MinBlocks, unsigned SpellingListIndex) {
3867288943Sdim  CUDALaunchBoundsAttr TmpAttr(AttrRange, Context, MaxThreads, MinBlocks,
3868288943Sdim                               SpellingListIndex);
3869288943Sdim
3870288943Sdim  if (!checkLaunchBoundsArgument(*this, MaxThreads, TmpAttr, 0))
3871288943Sdim    return;
3872288943Sdim
3873288943Sdim  if (MinBlocks && !checkLaunchBoundsArgument(*this, MinBlocks, TmpAttr, 1))
3874288943Sdim    return;
3875288943Sdim
3876288943Sdim  D->addAttr(::new (Context) CUDALaunchBoundsAttr(
3877288943Sdim      AttrRange, Context, MaxThreads, MinBlocks, SpellingListIndex));
3878288943Sdim}
3879288943Sdim
3880276479Sdimstatic void handleLaunchBoundsAttr(Sema &S, Decl *D,
3881276479Sdim                                   const AttributeList &Attr) {
3882288943Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1) ||
3883288943Sdim      !checkAttributeAtMostNumArgs(S, Attr, 2))
3884276479Sdim    return;
3885218893Sdim
3886288943Sdim  S.AddLaunchBoundsAttr(Attr.getRange(), D, Attr.getArgAsExpr(0),
3887288943Sdim                        Attr.getNumArgs() > 1 ? Attr.getArgAsExpr(1) : nullptr,
3888288943Sdim                        Attr.getAttributeSpellingListIndex());
3889199990Srdivacky}
3890199990Srdivacky
3891239462Sdimstatic void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
3892239462Sdim                                          const AttributeList &Attr) {
3893261991Sdim  if (!Attr.isArgIdent(0)) {
3894261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3895261991Sdim      << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier;
3896239462Sdim    return;
3897239462Sdim  }
3898261991Sdim
3899261991Sdim  if (!checkAttributeNumArgs(S, Attr, 3))
3900239462Sdim    return;
3901239462Sdim
3902261991Sdim  IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident;
3903239462Sdim
3904239462Sdim  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
3905239462Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
3906239462Sdim      << Attr.getName() << ExpectedFunctionOrMethod;
3907239462Sdim    return;
3908239462Sdim  }
3909239462Sdim
3910239462Sdim  uint64_t ArgumentIdx;
3911276479Sdim  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 2, Attr.getArgAsExpr(1),
3912276479Sdim                                           ArgumentIdx))
3913239462Sdim    return;
3914239462Sdim
3915239462Sdim  uint64_t TypeTagIdx;
3916276479Sdim  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 3, Attr.getArgAsExpr(2),
3917276479Sdim                                           TypeTagIdx))
3918239462Sdim    return;
3919239462Sdim
3920276479Sdim  bool IsPointer = (Attr.getName()->getName() == "pointer_with_type_tag");
3921239462Sdim  if (IsPointer) {
3922239462Sdim    // Ensure that buffer has a pointer type.
3923276479Sdim    QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx);
3924239462Sdim    if (!BufferTy->isPointerType()) {
3925239462Sdim      S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
3926296417Sdim        << Attr.getName() << 0;
3927239462Sdim    }
3928239462Sdim  }
3929239462Sdim
3930249423Sdim  D->addAttr(::new (S.Context)
3931249423Sdim             ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
3932249423Sdim                                     ArgumentIdx, TypeTagIdx, IsPointer,
3933249423Sdim                                     Attr.getAttributeSpellingListIndex()));
3934239462Sdim}
3935239462Sdim
3936239462Sdimstatic void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
3937239462Sdim                                         const AttributeList &Attr) {
3938261991Sdim  if (!Attr.isArgIdent(0)) {
3939261991Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
3940261991Sdim      << Attr.getName() << 1 << AANT_ArgumentIdentifier;
3941239462Sdim    return;
3942239462Sdim  }
3943261991Sdim
3944261991Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
3945261991Sdim    return;
3946239462Sdim
3947276479Sdim  if (!isa<VarDecl>(D)) {
3948276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
3949276479Sdim      << Attr.getName() << ExpectedVariable;
3950276479Sdim    return;
3951276479Sdim  }
3952276479Sdim
3953261991Sdim  IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
3954276479Sdim  TypeSourceInfo *MatchingCTypeLoc = nullptr;
3955261991Sdim  S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc);
3956261991Sdim  assert(MatchingCTypeLoc && "no type source info for attribute argument");
3957239462Sdim
3958249423Sdim  D->addAttr(::new (S.Context)
3959249423Sdim             TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
3960261991Sdim                                    MatchingCTypeLoc,
3961249423Sdim                                    Attr.getLayoutCompatible(),
3962249423Sdim                                    Attr.getMustBeNull(),
3963249423Sdim                                    Attr.getAttributeSpellingListIndex()));
3964239462Sdim}
3965239462Sdim
3966193326Sed//===----------------------------------------------------------------------===//
3967218893Sdim// Checker-specific attribute handlers.
3968199990Srdivacky//===----------------------------------------------------------------------===//
3969199990Srdivacky
3970276479Sdimstatic bool isValidSubjectOfNSReturnsRetainedAttribute(QualType type) {
3971276479Sdim  return type->isDependentType() ||
3972276479Sdim         type->isObjCRetainableType();
3973276479Sdim}
3974276479Sdim
3975218893Sdimstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
3976226633Sdim  return type->isDependentType() ||
3977226633Sdim         type->isObjCObjectPointerType() ||
3978226633Sdim         S.Context.isObjCNSObjectType(type);
3979199990Srdivacky}
3980218893Sdimstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) {
3981226633Sdim  return type->isDependentType() ||
3982226633Sdim         type->isPointerType() ||
3983226633Sdim         isValidSubjectOfNSAttribute(S, type);
3984218893Sdim}
3985199990Srdivacky
3986224145Sdimstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
3987276479Sdim  ParmVarDecl *param = cast<ParmVarDecl>(D);
3988276479Sdim  bool typeOK, cf;
3989199990Srdivacky
3990239462Sdim  if (Attr.getKind() == AttributeList::AT_NSConsumed) {
3991218893Sdim    typeOK = isValidSubjectOfNSAttribute(S, param->getType());
3992218893Sdim    cf = false;
3993218893Sdim  } else {
3994218893Sdim    typeOK = isValidSubjectOfCFAttribute(S, param->getType());
3995218893Sdim    cf = true;
3996199990Srdivacky  }
3997199990Srdivacky
3998218893Sdim  if (!typeOK) {
3999224145Sdim    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
4000226633Sdim      << Attr.getRange() << Attr.getName() << cf;
4001199990Srdivacky    return;
4002199990Srdivacky  }
4003199990Srdivacky
4004218893Sdim  if (cf)
4005249423Sdim    param->addAttr(::new (S.Context)
4006249423Sdim                   CFConsumedAttr(Attr.getRange(), S.Context,
4007249423Sdim                                  Attr.getAttributeSpellingListIndex()));
4008218893Sdim  else
4009249423Sdim    param->addAttr(::new (S.Context)
4010249423Sdim                   NSConsumedAttr(Attr.getRange(), S.Context,
4011249423Sdim                                  Attr.getAttributeSpellingListIndex()));
4012199990Srdivacky}
4013199990Srdivacky
4014224145Sdimstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
4015224145Sdim                                        const AttributeList &Attr) {
4016193326Sed
4017218893Sdim  QualType returnType;
4018198092Srdivacky
4019224145Sdim  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
4020276479Sdim    returnType = MD->getReturnType();
4021234353Sdim  else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
4022239462Sdim           (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
4023224145Sdim    return; // ignore: was handled as a type attribute
4024243830Sdim  else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
4025243830Sdim    returnType = PD->getType();
4026224145Sdim  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
4027276479Sdim    returnType = FD->getReturnType();
4028288943Sdim  else if (auto *Param = dyn_cast<ParmVarDecl>(D)) {
4029288943Sdim    returnType = Param->getType()->getPointeeType();
4030288943Sdim    if (returnType.isNull()) {
4031288943Sdim      S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
4032288943Sdim          << Attr.getName() << /*pointer-to-CF*/2
4033288943Sdim          << Attr.getRange();
4034288943Sdim      return;
4035288943Sdim    }
4036288943Sdim  } else {
4037288943Sdim    AttributeDeclKind ExpectedDeclKind;
4038288943Sdim    switch (Attr.getKind()) {
4039288943Sdim    default: llvm_unreachable("invalid ownership attribute");
4040288943Sdim    case AttributeList::AT_NSReturnsRetained:
4041288943Sdim    case AttributeList::AT_NSReturnsAutoreleased:
4042288943Sdim    case AttributeList::AT_NSReturnsNotRetained:
4043288943Sdim      ExpectedDeclKind = ExpectedFunctionOrMethod;
4044288943Sdim      break;
4045288943Sdim
4046288943Sdim    case AttributeList::AT_CFReturnsRetained:
4047288943Sdim    case AttributeList::AT_CFReturnsNotRetained:
4048288943Sdim      ExpectedDeclKind = ExpectedFunctionMethodOrParameter;
4049288943Sdim      break;
4050288943Sdim    }
4051224145Sdim    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
4052288943Sdim        << Attr.getRange() << Attr.getName() << ExpectedDeclKind;
4053193326Sed    return;
4054193326Sed  }
4055198092Srdivacky
4056218893Sdim  bool typeOK;
4057218893Sdim  bool cf;
4058224145Sdim  switch (Attr.getKind()) {
4059234353Sdim  default: llvm_unreachable("invalid ownership attribute");
4060276479Sdim  case AttributeList::AT_NSReturnsRetained:
4061276479Sdim    typeOK = isValidSubjectOfNSReturnsRetainedAttribute(returnType);
4062276479Sdim    cf = false;
4063276479Sdim    break;
4064276479Sdim
4065239462Sdim  case AttributeList::AT_NSReturnsAutoreleased:
4066239462Sdim  case AttributeList::AT_NSReturnsNotRetained:
4067218893Sdim    typeOK = isValidSubjectOfNSAttribute(S, returnType);
4068218893Sdim    cf = false;
4069218893Sdim    break;
4070218893Sdim
4071239462Sdim  case AttributeList::AT_CFReturnsRetained:
4072239462Sdim  case AttributeList::AT_CFReturnsNotRetained:
4073218893Sdim    typeOK = isValidSubjectOfCFAttribute(S, returnType);
4074218893Sdim    cf = true;
4075218893Sdim    break;
4076218893Sdim  }
4077218893Sdim
4078218893Sdim  if (!typeOK) {
4079288943Sdim    if (isa<ParmVarDecl>(D)) {
4080288943Sdim      S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
4081288943Sdim          << Attr.getName() << /*pointer-to-CF*/2
4082288943Sdim          << Attr.getRange();
4083288943Sdim    } else {
4084288943Sdim      // Needs to be kept in sync with warn_ns_attribute_wrong_return_type.
4085288943Sdim      enum : unsigned {
4086288943Sdim        Function,
4087288943Sdim        Method,
4088288943Sdim        Property
4089288943Sdim      } SubjectKind = Function;
4090288943Sdim      if (isa<ObjCMethodDecl>(D))
4091288943Sdim        SubjectKind = Method;
4092288943Sdim      else if (isa<ObjCPropertyDecl>(D))
4093288943Sdim        SubjectKind = Property;
4094288943Sdim      S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4095288943Sdim          << Attr.getName() << SubjectKind << cf
4096288943Sdim          << Attr.getRange();
4097288943Sdim    }
4098198092Srdivacky    return;
4099193326Sed  }
4100198092Srdivacky
4101224145Sdim  switch (Attr.getKind()) {
4102193326Sed    default:
4103226633Sdim      llvm_unreachable("invalid ownership attribute");
4104239462Sdim    case AttributeList::AT_NSReturnsAutoreleased:
4105280031Sdim      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(
4106280031Sdim          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
4107218893Sdim      return;
4108239462Sdim    case AttributeList::AT_CFReturnsNotRetained:
4109280031Sdim      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(
4110280031Sdim          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
4111204643Srdivacky      return;
4112239462Sdim    case AttributeList::AT_NSReturnsNotRetained:
4113280031Sdim      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(
4114280031Sdim          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
4115204643Srdivacky      return;
4116239462Sdim    case AttributeList::AT_CFReturnsRetained:
4117280031Sdim      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(
4118280031Sdim          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
4119193326Sed      return;
4120239462Sdim    case AttributeList::AT_NSReturnsRetained:
4121280031Sdim      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(
4122280031Sdim          Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
4123193326Sed      return;
4124193326Sed  };
4125193326Sed}
4126193326Sed
4127226633Sdimstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
4128226633Sdim                                              const AttributeList &attr) {
4129261991Sdim  const int EP_ObjCMethod = 1;
4130261991Sdim  const int EP_ObjCProperty = 2;
4131261991Sdim
4132226633Sdim  SourceLocation loc = attr.getLoc();
4133261991Sdim  QualType resultType;
4134276479Sdim  if (isa<ObjCMethodDecl>(D))
4135276479Sdim    resultType = cast<ObjCMethodDecl>(D)->getReturnType();
4136261991Sdim  else
4137276479Sdim    resultType = cast<ObjCPropertyDecl>(D)->getType();
4138226633Sdim
4139226633Sdim  if (!resultType->isReferenceType() &&
4140226633Sdim      (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
4141261991Sdim    S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
4142226633Sdim      << SourceRange(loc)
4143276479Sdim    << attr.getName()
4144276479Sdim    << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
4145261991Sdim    << /*non-retainable pointer*/ 2;
4146226633Sdim
4147226633Sdim    // Drop the attribute.
4148226633Sdim    return;
4149226633Sdim  }
4150226633Sdim
4151280031Sdim  D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr(
4152280031Sdim      attr.getRange(), S.Context, attr.getAttributeSpellingListIndex()));
4153226633Sdim}
4154226633Sdim
4155243830Sdimstatic void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
4156243830Sdim                                        const AttributeList &attr) {
4157276479Sdim  ObjCMethodDecl *method = cast<ObjCMethodDecl>(D);
4158243830Sdim
4159243830Sdim  DeclContext *DC = method->getDeclContext();
4160243830Sdim  if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
4161243830Sdim    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4162243830Sdim    << attr.getName() << 0;
4163243830Sdim    S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
4164243830Sdim    return;
4165243830Sdim  }
4166243830Sdim  if (method->getMethodFamily() == OMF_dealloc) {
4167243830Sdim    S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
4168243830Sdim    << attr.getName() << 1;
4169243830Sdim    return;
4170243830Sdim  }
4171243830Sdim
4172249423Sdim  method->addAttr(::new (S.Context)
4173249423Sdim                  ObjCRequiresSuperAttr(attr.getRange(), S.Context,
4174249423Sdim                                        attr.getAttributeSpellingListIndex()));
4175243830Sdim}
4176243830Sdim
4177276479Sdimstatic void handleCFAuditedTransferAttr(Sema &S, Decl *D,
4178276479Sdim                                        const AttributeList &Attr) {
4179296417Sdim  if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr.getRange(),
4180296417Sdim                                                      Attr.getName()))
4181226633Sdim    return;
4182226633Sdim
4183276479Sdim  D->addAttr(::new (S.Context)
4184276479Sdim             CFAuditedTransferAttr(Attr.getRange(), S.Context,
4185276479Sdim                                   Attr.getAttributeSpellingListIndex()));
4186276479Sdim}
4187226633Sdim
4188276479Sdimstatic void handleCFUnknownTransferAttr(Sema &S, Decl *D,
4189276479Sdim                                        const AttributeList &Attr) {
4190296417Sdim  if (checkAttrMutualExclusion<CFAuditedTransferAttr>(S, D, Attr.getRange(),
4191296417Sdim                                                      Attr.getName()))
4192226633Sdim    return;
4193226633Sdim
4194276479Sdim  D->addAttr(::new (S.Context)
4195276479Sdim             CFUnknownTransferAttr(Attr.getRange(), S.Context,
4196276479Sdim             Attr.getAttributeSpellingListIndex()));
4197226633Sdim}
4198226633Sdim
4199276479Sdimstatic void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
4200226633Sdim                                const AttributeList &Attr) {
4201276479Sdim  IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
4202226633Sdim
4203276479Sdim  if (!Parm) {
4204276479Sdim    S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
4205276479Sdim    return;
4206226633Sdim  }
4207288943Sdim
4208288943Sdim  // Typedefs only allow objc_bridge(id) and have some additional checking.
4209288943Sdim  if (auto TD = dyn_cast<TypedefNameDecl>(D)) {
4210288943Sdim    if (!Parm->Ident->isStr("id")) {
4211288943Sdim      S.Diag(Attr.getLoc(), diag::err_objc_attr_typedef_not_id)
4212288943Sdim        << Attr.getName();
4213288943Sdim      return;
4214288943Sdim    }
4215288943Sdim
4216288943Sdim    // Only allow 'cv void *'.
4217288943Sdim    QualType T = TD->getUnderlyingType();
4218288943Sdim    if (!T->isVoidPointerType()) {
4219288943Sdim      S.Diag(Attr.getLoc(), diag::err_objc_attr_typedef_not_void_pointer);
4220288943Sdim      return;
4221288943Sdim    }
4222288943Sdim  }
4223276479Sdim
4224249423Sdim  D->addAttr(::new (S.Context)
4225276479Sdim             ObjCBridgeAttr(Attr.getRange(), S.Context, Parm->Ident,
4226249423Sdim                           Attr.getAttributeSpellingListIndex()));
4227226633Sdim}
4228226633Sdim
4229276479Sdimstatic void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D,
4230276479Sdim                                        const AttributeList &Attr) {
4231276479Sdim  IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
4232276479Sdim
4233276479Sdim  if (!Parm) {
4234276479Sdim    S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
4235261991Sdim    return;
4236261991Sdim  }
4237261991Sdim
4238276479Sdim  D->addAttr(::new (S.Context)
4239276479Sdim             ObjCBridgeMutableAttr(Attr.getRange(), S.Context, Parm->Ident,
4240276479Sdim                            Attr.getAttributeSpellingListIndex()));
4241276479Sdim}
4242276479Sdim
4243276479Sdimstatic void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D,
4244276479Sdim                                 const AttributeList &Attr) {
4245276479Sdim  IdentifierInfo *RelatedClass =
4246276479Sdim    Attr.isArgIdent(0) ? Attr.getArgAsIdent(0)->Ident : nullptr;
4247276479Sdim  if (!RelatedClass) {
4248276479Sdim    S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
4249261991Sdim    return;
4250261991Sdim  }
4251276479Sdim  IdentifierInfo *ClassMethod =
4252276479Sdim    Attr.getArgAsIdent(1) ? Attr.getArgAsIdent(1)->Ident : nullptr;
4253276479Sdim  IdentifierInfo *InstanceMethod =
4254276479Sdim    Attr.getArgAsIdent(2) ? Attr.getArgAsIdent(2)->Ident : nullptr;
4255276479Sdim  D->addAttr(::new (S.Context)
4256276479Sdim             ObjCBridgeRelatedAttr(Attr.getRange(), S.Context, RelatedClass,
4257276479Sdim                                   ClassMethod, InstanceMethod,
4258276479Sdim                                   Attr.getAttributeSpellingListIndex()));
4259276479Sdim}
4260276479Sdim
4261276479Sdimstatic void handleObjCDesignatedInitializer(Sema &S, Decl *D,
4262276479Sdim                                            const AttributeList &Attr) {
4263276479Sdim  ObjCInterfaceDecl *IFace;
4264280031Sdim  if (ObjCCategoryDecl *CatDecl =
4265280031Sdim          dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
4266276479Sdim    IFace = CatDecl->getClassInterface();
4267276479Sdim  else
4268276479Sdim    IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
4269288943Sdim
4270288943Sdim  if (!IFace)
4271288943Sdim    return;
4272288943Sdim
4273276479Sdim  IFace->setHasDesignatedInitializers();
4274276479Sdim  D->addAttr(::new (S.Context)
4275276479Sdim                  ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,
4276276479Sdim                                         Attr.getAttributeSpellingListIndex()));
4277276479Sdim}
4278276479Sdim
4279276479Sdimstatic void handleObjCRuntimeName(Sema &S, Decl *D,
4280276479Sdim                                  const AttributeList &Attr) {
4281276479Sdim  StringRef MetaDataName;
4282276479Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName))
4283261991Sdim    return;
4284261991Sdim  D->addAttr(::new (S.Context)
4285276479Sdim             ObjCRuntimeNameAttr(Attr.getRange(), S.Context,
4286276479Sdim                                 MetaDataName,
4287276479Sdim                                 Attr.getAttributeSpellingListIndex()));
4288261991Sdim}
4289261991Sdim
4290288943Sdim// when a user wants to use objc_boxable with a union or struct
4291288943Sdim// but she doesn't have access to the declaration (legacy/third-party code)
4292288943Sdim// then she can 'enable' this feature via trick with a typedef
4293288943Sdim// e.g.:
4294288943Sdim// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct;
4295288943Sdimstatic void handleObjCBoxable(Sema &S, Decl *D, const AttributeList &Attr) {
4296288943Sdim  bool notify = false;
4297288943Sdim
4298288943Sdim  RecordDecl *RD = dyn_cast<RecordDecl>(D);
4299288943Sdim  if (RD && RD->getDefinition()) {
4300288943Sdim    RD = RD->getDefinition();
4301288943Sdim    notify = true;
4302288943Sdim  }
4303288943Sdim
4304288943Sdim  if (RD) {
4305288943Sdim    ObjCBoxableAttr *BoxableAttr = ::new (S.Context)
4306288943Sdim                          ObjCBoxableAttr(Attr.getRange(), S.Context,
4307288943Sdim                                          Attr.getAttributeSpellingListIndex());
4308288943Sdim    RD->addAttr(BoxableAttr);
4309288943Sdim    if (notify) {
4310288943Sdim      // we need to notify ASTReader/ASTWriter about
4311288943Sdim      // modification of existing declaration
4312288943Sdim      if (ASTMutationListener *L = S.getASTMutationListener())
4313288943Sdim        L->AddedAttributeToRecord(BoxableAttr, RD);
4314288943Sdim    }
4315288943Sdim  }
4316288943Sdim}
4317288943Sdim
4318224145Sdimstatic void handleObjCOwnershipAttr(Sema &S, Decl *D,
4319224145Sdim                                    const AttributeList &Attr) {
4320224145Sdim  if (hasDeclarator(D)) return;
4321224145Sdim
4322224145Sdim  S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
4323234353Sdim    << Attr.getRange() << Attr.getName() << ExpectedVariable;
4324224145Sdim}
4325224145Sdim
4326224145Sdimstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
4327224145Sdim                                          const AttributeList &Attr) {
4328224145Sdim  ValueDecl *vd = cast<ValueDecl>(D);
4329224145Sdim  QualType type = vd->getType();
4330224145Sdim
4331224145Sdim  if (!type->isDependentType() &&
4332224145Sdim      !type->isObjCLifetimeType()) {
4333224145Sdim    S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type)
4334224145Sdim      << type;
4335224145Sdim    return;
4336224145Sdim  }
4337224145Sdim
4338224145Sdim  Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime();
4339224145Sdim
4340224145Sdim  // If we have no lifetime yet, check the lifetime we're presumably
4341224145Sdim  // going to infer.
4342224145Sdim  if (lifetime == Qualifiers::OCL_None && !type->isDependentType())
4343224145Sdim    lifetime = type->getObjCARCImplicitLifetime();
4344224145Sdim
4345224145Sdim  switch (lifetime) {
4346224145Sdim  case Qualifiers::OCL_None:
4347224145Sdim    assert(type->isDependentType() &&
4348224145Sdim           "didn't infer lifetime for non-dependent type?");
4349224145Sdim    break;
4350224145Sdim
4351224145Sdim  case Qualifiers::OCL_Weak:   // meaningful
4352224145Sdim  case Qualifiers::OCL_Strong: // meaningful
4353224145Sdim    break;
4354224145Sdim
4355224145Sdim  case Qualifiers::OCL_ExplicitNone:
4356224145Sdim  case Qualifiers::OCL_Autoreleasing:
4357224145Sdim    S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
4358224145Sdim      << (lifetime == Qualifiers::OCL_Autoreleasing);
4359224145Sdim    break;
4360224145Sdim  }
4361224145Sdim
4362224145Sdim  D->addAttr(::new (S.Context)
4363249423Sdim             ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
4364249423Sdim                                     Attr.getAttributeSpellingListIndex()));
4365224145Sdim}
4366224145Sdim
4367193326Sed//===----------------------------------------------------------------------===//
4368218893Sdim// Microsoft specific attribute handlers.
4369218893Sdim//===----------------------------------------------------------------------===//
4370218893Sdim
4371224145Sdimstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4372276479Sdim  if (!S.LangOpts.CPlusPlus) {
4373276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
4374276479Sdim      << Attr.getName() << AttributeLangSupport::C;
4375261991Sdim    return;
4376276479Sdim  }
4377224145Sdim
4378276479Sdim  if (!isa<CXXRecordDecl>(D)) {
4379276479Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4380276479Sdim      << Attr.getName() << ExpectedClass;
4381276479Sdim    return;
4382276479Sdim  }
4383276479Sdim
4384261991Sdim  StringRef StrRef;
4385261991Sdim  SourceLocation LiteralLoc;
4386261991Sdim  if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc))
4387261991Sdim    return;
4388218893Sdim
4389261991Sdim  // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
4390261991Sdim  // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
4391261991Sdim  if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
4392261991Sdim    StrRef = StrRef.drop_front().drop_back();
4393218893Sdim
4394261991Sdim  // Validate GUID length.
4395261991Sdim  if (StrRef.size() != 36) {
4396261991Sdim    S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4397261991Sdim    return;
4398261991Sdim  }
4399234353Sdim
4400261991Sdim  for (unsigned i = 0; i < 36; ++i) {
4401261991Sdim    if (i == 8 || i == 13 || i == 18 || i == 23) {
4402261991Sdim      if (StrRef[i] != '-') {
4403261991Sdim        S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4404218893Sdim        return;
4405218893Sdim      }
4406261991Sdim    } else if (!isHexDigit(StrRef[i])) {
4407261991Sdim      S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
4408261991Sdim      return;
4409218893Sdim    }
4410261991Sdim  }
4411218893Sdim
4412261991Sdim  D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef,
4413261991Sdim                                        Attr.getAttributeSpellingListIndex()));
4414218893Sdim}
4415218893Sdim
4416276479Sdimstatic void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4417276479Sdim  if (!S.LangOpts.CPlusPlus) {
4418276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
4419276479Sdim      << Attr.getName() << AttributeLangSupport::C;
4420243830Sdim    return;
4421276479Sdim  }
4422276479Sdim  MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
4423276479Sdim      D, Attr.getRange(), /*BestCase=*/true,
4424276479Sdim      Attr.getAttributeSpellingListIndex(),
4425276479Sdim      (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling());
4426276479Sdim  if (IA)
4427276479Sdim    D->addAttr(IA);
4428276479Sdim}
4429243830Sdim
4430276479Sdimstatic void handleDeclspecThreadAttr(Sema &S, Decl *D,
4431276479Sdim                                     const AttributeList &Attr) {
4432276479Sdim  VarDecl *VD = cast<VarDecl>(D);
4433276479Sdim  if (!S.Context.getTargetInfo().isTLSSupported()) {
4434276479Sdim    S.Diag(Attr.getLoc(), diag::err_thread_unsupported);
4435276479Sdim    return;
4436276479Sdim  }
4437276479Sdim  if (VD->getTSCSpec() != TSCS_unspecified) {
4438276479Sdim    S.Diag(Attr.getLoc(), diag::err_declspec_thread_on_thread_variable);
4439276479Sdim    return;
4440276479Sdim  }
4441276479Sdim  if (VD->hasLocalStorage()) {
4442276479Sdim    S.Diag(Attr.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
4443276479Sdim    return;
4444276479Sdim  }
4445276479Sdim  VD->addAttr(::new (S.Context) ThreadAttr(
4446276479Sdim      Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
4447239462Sdim}
4448239462Sdim
4449276479Sdimstatic void handleARMInterruptAttr(Sema &S, Decl *D,
4450276479Sdim                                   const AttributeList &Attr) {
4451276479Sdim  // Check the attribute arguments.
4452276479Sdim  if (Attr.getNumArgs() > 1) {
4453276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
4454276479Sdim      << Attr.getName() << 1;
4455261991Sdim    return;
4456276479Sdim  }
4457261991Sdim
4458276479Sdim  StringRef Str;
4459276479Sdim  SourceLocation ArgLoc;
4460276479Sdim
4461276479Sdim  if (Attr.getNumArgs() == 0)
4462276479Sdim    Str = "";
4463276479Sdim  else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
4464276479Sdim    return;
4465276479Sdim
4466276479Sdim  ARMInterruptAttr::InterruptType Kind;
4467276479Sdim  if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
4468276479Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
4469276479Sdim      << Attr.getName() << Str << ArgLoc;
4470276479Sdim    return;
4471276479Sdim  }
4472276479Sdim
4473276479Sdim  unsigned Index = Attr.getAttributeSpellingListIndex();
4474276479Sdim  D->addAttr(::new (S.Context)
4475276479Sdim             ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
4476239462Sdim}
4477239462Sdim
4478276479Sdimstatic void handleMSP430InterruptAttr(Sema &S, Decl *D,
4479276479Sdim                                      const AttributeList &Attr) {
4480276479Sdim  if (!checkAttributeNumArgs(S, Attr, 1))
4481261991Sdim    return;
4482276479Sdim
4483276479Sdim  if (!Attr.isArgExpr(0)) {
4484276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
4485276479Sdim      << AANT_ArgumentIntegerConstant;
4486276479Sdim    return;
4487276479Sdim  }
4488276479Sdim
4489276479Sdim  // FIXME: Check for decl - it should be void ()(void).
4490276479Sdim
4491276479Sdim  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
4492276479Sdim  llvm::APSInt NumParams(32);
4493276479Sdim  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
4494276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
4495276479Sdim      << Attr.getName() << AANT_ArgumentIntegerConstant
4496276479Sdim      << NumParamsExpr->getSourceRange();
4497276479Sdim    return;
4498276479Sdim  }
4499276479Sdim
4500276479Sdim  unsigned Num = NumParams.getLimitedValue(255);
4501276479Sdim  if ((Num & 1) || Num > 30) {
4502276479Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
4503276479Sdim      << Attr.getName() << (int)NumParams.getSExtValue()
4504276479Sdim      << NumParamsExpr->getSourceRange();
4505276479Sdim    return;
4506276479Sdim  }
4507276479Sdim
4508261991Sdim  D->addAttr(::new (S.Context)
4509276479Sdim              MSP430InterruptAttr(Attr.getLoc(), S.Context, Num,
4510276479Sdim                                  Attr.getAttributeSpellingListIndex()));
4511276479Sdim  D->addAttr(UsedAttr::CreateImplicit(S.Context));
4512239462Sdim}
4513239462Sdim
4514296417Sdimstatic void handleMipsInterruptAttr(Sema &S, Decl *D,
4515296417Sdim                                    const AttributeList &Attr) {
4516296417Sdim  // Only one optional argument permitted.
4517296417Sdim  if (Attr.getNumArgs() > 1) {
4518296417Sdim    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
4519296417Sdim        << Attr.getName() << 1;
4520296417Sdim    return;
4521296417Sdim  }
4522296417Sdim
4523296417Sdim  StringRef Str;
4524296417Sdim  SourceLocation ArgLoc;
4525296417Sdim
4526296417Sdim  if (Attr.getNumArgs() == 0)
4527296417Sdim    Str = "";
4528296417Sdim  else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
4529296417Sdim    return;
4530296417Sdim
4531296417Sdim  // Semantic checks for a function with the 'interrupt' attribute for MIPS:
4532296417Sdim  // a) Must be a function.
4533296417Sdim  // b) Must have no parameters.
4534296417Sdim  // c) Must have the 'void' return type.
4535296417Sdim  // d) Cannot have the 'mips16' attribute, as that instruction set
4536296417Sdim  //    lacks the 'eret' instruction.
4537296417Sdim  // e) The attribute itself must either have no argument or one of the
4538296417Sdim  //    valid interrupt types, see [MipsInterruptDocs].
4539296417Sdim
4540296417Sdim  if (!isFunctionOrMethod(D)) {
4541296417Sdim    S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
4542296417Sdim        << "'interrupt'" << ExpectedFunctionOrMethod;
4543296417Sdim    return;
4544296417Sdim  }
4545296417Sdim
4546296417Sdim  if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
4547296417Sdim    S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute)
4548296417Sdim        << 0;
4549296417Sdim    return;
4550296417Sdim  }
4551296417Sdim
4552296417Sdim  if (!getFunctionOrMethodResultType(D)->isVoidType()) {
4553296417Sdim    S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute)
4554296417Sdim        << 1;
4555296417Sdim    return;
4556296417Sdim  }
4557296417Sdim
4558296417Sdim  if (checkAttrMutualExclusion<Mips16Attr>(S, D, Attr.getRange(),
4559296417Sdim                                           Attr.getName()))
4560296417Sdim    return;
4561296417Sdim
4562296417Sdim  MipsInterruptAttr::InterruptType Kind;
4563296417Sdim  if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
4564296417Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
4565296417Sdim        << Attr.getName() << "'" + std::string(Str) + "'";
4566296417Sdim    return;
4567296417Sdim  }
4568296417Sdim
4569296417Sdim  D->addAttr(::new (S.Context) MipsInterruptAttr(
4570296417Sdim      Attr.getLoc(), S.Context, Kind, Attr.getAttributeSpellingListIndex()));
4571296417Sdim}
4572296417Sdim
4573276479Sdimstatic void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4574276479Sdim  // Dispatch the interrupt attribute based on the current target.
4575276479Sdim  if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430)
4576276479Sdim    handleMSP430InterruptAttr(S, D, Attr);
4577296417Sdim  else if (S.Context.getTargetInfo().getTriple().getArch() ==
4578296417Sdim               llvm::Triple::mipsel ||
4579296417Sdim           S.Context.getTargetInfo().getTriple().getArch() ==
4580296417Sdim               llvm::Triple::mips)
4581296417Sdim    handleMipsInterruptAttr(S, D, Attr);
4582276479Sdim  else
4583276479Sdim    handleARMInterruptAttr(S, D, Attr);
4584276479Sdim}
4585276479Sdim
4586280031Sdimstatic void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D,
4587280031Sdim                                    const AttributeList &Attr) {
4588280031Sdim  uint32_t NumRegs;
4589280031Sdim  Expr *NumRegsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
4590280031Sdim  if (!checkUInt32Argument(S, Attr, NumRegsExpr, NumRegs))
4591280031Sdim    return;
4592280031Sdim
4593280031Sdim  D->addAttr(::new (S.Context)
4594280031Sdim             AMDGPUNumVGPRAttr(Attr.getLoc(), S.Context,
4595280031Sdim                               NumRegs,
4596280031Sdim                               Attr.getAttributeSpellingListIndex()));
4597280031Sdim}
4598280031Sdim
4599280031Sdimstatic void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D,
4600280031Sdim                                    const AttributeList &Attr) {
4601280031Sdim  uint32_t NumRegs;
4602280031Sdim  Expr *NumRegsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
4603280031Sdim  if (!checkUInt32Argument(S, Attr, NumRegsExpr, NumRegs))
4604280031Sdim    return;
4605280031Sdim
4606280031Sdim  D->addAttr(::new (S.Context)
4607280031Sdim             AMDGPUNumSGPRAttr(Attr.getLoc(), S.Context,
4608280031Sdim                               NumRegs,
4609280031Sdim                               Attr.getAttributeSpellingListIndex()));
4610280031Sdim}
4611280031Sdim
4612276479Sdimstatic void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,
4613276479Sdim                                              const AttributeList& Attr) {
4614276479Sdim  // If we try to apply it to a function pointer, don't warn, but don't
4615276479Sdim  // do anything, either. It doesn't matter anyway, because there's nothing
4616276479Sdim  // special about calling a force_align_arg_pointer function.
4617276479Sdim  ValueDecl *VD = dyn_cast<ValueDecl>(D);
4618276479Sdim  if (VD && VD->getType()->isFunctionPointerType())
4619261991Sdim    return;
4620276479Sdim  // Also don't warn on function pointer typedefs.
4621276479Sdim  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
4622276479Sdim  if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
4623276479Sdim    TD->getUnderlyingType()->isFunctionType()))
4624276479Sdim    return;
4625276479Sdim  // Attribute can only be applied to function types.
4626276479Sdim  if (!isa<FunctionDecl>(D)) {
4627276479Sdim    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4628276479Sdim      << Attr.getName() << /* function */0;
4629276479Sdim    return;
4630276479Sdim  }
4631276479Sdim
4632261991Sdim  D->addAttr(::new (S.Context)
4633276479Sdim              X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context,
4634276479Sdim                                        Attr.getAttributeSpellingListIndex()));
4635261991Sdim}
4636261991Sdim
4637276479SdimDLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
4638276479Sdim                                        unsigned AttrSpellingListIndex) {
4639276479Sdim  if (D->hasAttr<DLLExportAttr>()) {
4640276479Sdim    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'";
4641276479Sdim    return nullptr;
4642276479Sdim  }
4643276479Sdim
4644276479Sdim  if (D->hasAttr<DLLImportAttr>())
4645276479Sdim    return nullptr;
4646276479Sdim
4647276479Sdim  return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
4648276479Sdim}
4649276479Sdim
4650276479SdimDLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
4651276479Sdim                                        unsigned AttrSpellingListIndex) {
4652276479Sdim  if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
4653276479Sdim    Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
4654276479Sdim    D->dropAttr<DLLImportAttr>();
4655276479Sdim  }
4656276479Sdim
4657276479Sdim  if (D->hasAttr<DLLExportAttr>())
4658276479Sdim    return nullptr;
4659276479Sdim
4660276479Sdim  return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex);
4661276479Sdim}
4662276479Sdim
4663276479Sdimstatic void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {
4664276479Sdim  if (isa<ClassTemplatePartialSpecializationDecl>(D) &&
4665276479Sdim      S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
4666276479Sdim    S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored)
4667276479Sdim        << A.getName();
4668276479Sdim    return;
4669276479Sdim  }
4670276479Sdim
4671280031Sdim  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
4672280031Sdim    if (FD->isInlined() && A.getKind() == AttributeList::AT_DLLImport &&
4673280031Sdim        !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
4674280031Sdim      // MinGW doesn't allow dllimport on inline functions.
4675280031Sdim      S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
4676280031Sdim          << A.getName();
4677280031Sdim      return;
4678280031Sdim    }
4679280031Sdim  }
4680280031Sdim
4681296417Sdim  if (auto *MD = dyn_cast<CXXMethodDecl>(D)) {
4682296417Sdim    if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
4683296417Sdim        MD->getParent()->isLambda()) {
4684296417Sdim      S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A.getName();
4685296417Sdim      return;
4686296417Sdim    }
4687296417Sdim  }
4688296417Sdim
4689276479Sdim  unsigned Index = A.getAttributeSpellingListIndex();
4690276479Sdim  Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport
4691276479Sdim                      ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
4692276479Sdim                      : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index);
4693276479Sdim  if (NewAttr)
4694276479Sdim    D->addAttr(NewAttr);
4695276479Sdim}
4696276479Sdim
4697276479SdimMSInheritanceAttr *
4698276479SdimSema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
4699276479Sdim                             unsigned AttrSpellingListIndex,
4700276479Sdim                             MSInheritanceAttr::Spelling SemanticSpelling) {
4701276479Sdim  if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
4702276479Sdim    if (IA->getSemanticSpelling() == SemanticSpelling)
4703276479Sdim      return nullptr;
4704276479Sdim    Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
4705276479Sdim        << 1 /*previous declaration*/;
4706276479Sdim    Diag(Range.getBegin(), diag::note_previous_ms_inheritance);
4707276479Sdim    D->dropAttr<MSInheritanceAttr>();
4708276479Sdim  }
4709276479Sdim
4710276479Sdim  CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
4711276479Sdim  if (RD->hasDefinition()) {
4712276479Sdim    if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase,
4713276479Sdim                                           SemanticSpelling)) {
4714276479Sdim      return nullptr;
4715276479Sdim    }
4716276479Sdim  } else {
4717276479Sdim    if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {
4718276479Sdim      Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
4719276479Sdim          << 1 /*partial specialization*/;
4720276479Sdim      return nullptr;
4721276479Sdim    }
4722276479Sdim    if (RD->getDescribedClassTemplate()) {
4723276479Sdim      Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
4724276479Sdim          << 0 /*primary template*/;
4725276479Sdim      return nullptr;
4726276479Sdim    }
4727276479Sdim  }
4728276479Sdim
4729276479Sdim  return ::new (Context)
4730276479Sdim      MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex);
4731276479Sdim}
4732276479Sdim
4733276479Sdimstatic void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4734276479Sdim  // The capability attributes take a single string parameter for the name of
4735276479Sdim  // the capability they represent. The lockable attribute does not take any
4736276479Sdim  // parameters. However, semantically, both attributes represent the same
4737276479Sdim  // concept, and so they use the same semantic attribute. Eventually, the
4738276479Sdim  // lockable attribute will be removed.
4739276479Sdim  //
4740276479Sdim  // For backward compatibility, any capability which has no specified string
4741276479Sdim  // literal will be considered a "mutex."
4742276479Sdim  StringRef N("mutex");
4743276479Sdim  SourceLocation LiteralLoc;
4744276479Sdim  if (Attr.getKind() == AttributeList::AT_Capability &&
4745276479Sdim      !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc))
4746276479Sdim    return;
4747276479Sdim
4748276479Sdim  // Currently, there are only two names allowed for a capability: role and
4749276479Sdim  // mutex (case insensitive). Diagnose other capability names.
4750276479Sdim  if (!N.equals_lower("mutex") && !N.equals_lower("role"))
4751276479Sdim    S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N;
4752276479Sdim
4753276479Sdim  D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N,
4754276479Sdim                                        Attr.getAttributeSpellingListIndex()));
4755276479Sdim}
4756276479Sdim
4757276479Sdimstatic void handleAssertCapabilityAttr(Sema &S, Decl *D,
4758276479Sdim                                       const AttributeList &Attr) {
4759276479Sdim  D->addAttr(::new (S.Context) AssertCapabilityAttr(Attr.getRange(), S.Context,
4760276479Sdim                                                    Attr.getArgAsExpr(0),
4761276479Sdim                                        Attr.getAttributeSpellingListIndex()));
4762276479Sdim}
4763276479Sdim
4764276479Sdimstatic void handleAcquireCapabilityAttr(Sema &S, Decl *D,
4765276479Sdim                                        const AttributeList &Attr) {
4766276479Sdim  SmallVector<Expr*, 1> Args;
4767276479Sdim  if (!checkLockFunAttrCommon(S, D, Attr, Args))
4768276479Sdim    return;
4769276479Sdim
4770276479Sdim  D->addAttr(::new (S.Context) AcquireCapabilityAttr(Attr.getRange(),
4771276479Sdim                                                     S.Context,
4772276479Sdim                                                     Args.data(), Args.size(),
4773276479Sdim                                        Attr.getAttributeSpellingListIndex()));
4774276479Sdim}
4775276479Sdim
4776276479Sdimstatic void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
4777276479Sdim                                           const AttributeList &Attr) {
4778276479Sdim  SmallVector<Expr*, 2> Args;
4779276479Sdim  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
4780276479Sdim    return;
4781276479Sdim
4782276479Sdim  D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(Attr.getRange(),
4783276479Sdim                                                        S.Context,
4784276479Sdim                                                        Attr.getArgAsExpr(0),
4785276479Sdim                                                        Args.data(),
4786276479Sdim                                                        Args.size(),
4787276479Sdim                                        Attr.getAttributeSpellingListIndex()));
4788276479Sdim}
4789276479Sdim
4790276479Sdimstatic void handleReleaseCapabilityAttr(Sema &S, Decl *D,
4791276479Sdim                                        const AttributeList &Attr) {
4792276479Sdim  // Check that all arguments are lockable objects.
4793276479Sdim  SmallVector<Expr *, 1> Args;
4794276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, true);
4795276479Sdim
4796276479Sdim  D->addAttr(::new (S.Context) ReleaseCapabilityAttr(
4797276479Sdim      Attr.getRange(), S.Context, Args.data(), Args.size(),
4798276479Sdim      Attr.getAttributeSpellingListIndex()));
4799276479Sdim}
4800276479Sdim
4801276479Sdimstatic void handleRequiresCapabilityAttr(Sema &S, Decl *D,
4802276479Sdim                                         const AttributeList &Attr) {
4803276479Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
4804276479Sdim    return;
4805276479Sdim
4806276479Sdim  // check that all arguments are lockable objects
4807276479Sdim  SmallVector<Expr*, 1> Args;
4808276479Sdim  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
4809276479Sdim  if (Args.empty())
4810276479Sdim    return;
4811276479Sdim
4812276479Sdim  RequiresCapabilityAttr *RCA = ::new (S.Context)
4813276479Sdim    RequiresCapabilityAttr(Attr.getRange(), S.Context, Args.data(),
4814276479Sdim                           Args.size(), Attr.getAttributeSpellingListIndex());
4815276479Sdim
4816276479Sdim  D->addAttr(RCA);
4817276479Sdim}
4818276479Sdim
4819280031Sdimstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4820280031Sdim  if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {
4821280031Sdim    if (NSD->isAnonymousNamespace()) {
4822280031Sdim      S.Diag(Attr.getLoc(), diag::warn_deprecated_anonymous_namespace);
4823280031Sdim      // Do not want to attach the attribute to the namespace because that will
4824280031Sdim      // cause confusing diagnostic reports for uses of declarations within the
4825280031Sdim      // namespace.
4826280031Sdim      return;
4827280031Sdim    }
4828280031Sdim  }
4829288943Sdim
4830288943Sdim  if (!S.getLangOpts().CPlusPlus14)
4831288943Sdim    if (Attr.isCXX11Attribute() &&
4832288943Sdim        !(Attr.hasScope() && Attr.getScopeName()->isStr("gnu")))
4833288943Sdim      S.Diag(Attr.getLoc(), diag::ext_deprecated_attr_is_a_cxx14_extension);
4834288943Sdim
4835280031Sdim  handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
4836280031Sdim}
4837280031Sdim
4838288943Sdimstatic void handleNoSanitizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
4839288943Sdim  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
4840288943Sdim    return;
4841288943Sdim
4842288943Sdim  std::vector<std::string> Sanitizers;
4843288943Sdim
4844288943Sdim  for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) {
4845288943Sdim    StringRef SanitizerName;
4846288943Sdim    SourceLocation LiteralLoc;
4847288943Sdim
4848288943Sdim    if (!S.checkStringLiteralArgumentAttr(Attr, I, SanitizerName, &LiteralLoc))
4849288943Sdim      return;
4850288943Sdim
4851288943Sdim    if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) == 0)
4852288943Sdim      S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
4853288943Sdim
4854288943Sdim    Sanitizers.push_back(SanitizerName);
4855288943Sdim  }
4856288943Sdim
4857288943Sdim  D->addAttr(::new (S.Context) NoSanitizeAttr(
4858288943Sdim      Attr.getRange(), S.Context, Sanitizers.data(), Sanitizers.size(),
4859288943Sdim      Attr.getAttributeSpellingListIndex()));
4860288943Sdim}
4861288943Sdim
4862288943Sdimstatic void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
4863288943Sdim                                         const AttributeList &Attr) {
4864296417Sdim  StringRef AttrName = Attr.getName()->getName();
4865296417Sdim  normalizeName(AttrName);
4866288943Sdim  std::string SanitizerName =
4867296417Sdim      llvm::StringSwitch<std::string>(AttrName)
4868288943Sdim          .Case("no_address_safety_analysis", "address")
4869288943Sdim          .Case("no_sanitize_address", "address")
4870288943Sdim          .Case("no_sanitize_thread", "thread")
4871288943Sdim          .Case("no_sanitize_memory", "memory");
4872288943Sdim  D->addAttr(::new (S.Context)
4873288943Sdim                 NoSanitizeAttr(Attr.getRange(), S.Context, &SanitizerName, 1,
4874288943Sdim                                Attr.getAttributeSpellingListIndex()));
4875288943Sdim}
4876288943Sdim
4877296417Sdimstatic void handleInternalLinkageAttr(Sema &S, Decl *D,
4878296417Sdim                                      const AttributeList &Attr) {
4879296417Sdim  if (InternalLinkageAttr *Internal =
4880296417Sdim          S.mergeInternalLinkageAttr(D, Attr.getRange(), Attr.getName(),
4881296417Sdim                                     Attr.getAttributeSpellingListIndex()))
4882296417Sdim    D->addAttr(Internal);
4883296417Sdim}
4884296417Sdim
4885261991Sdim/// Handles semantic checking for features that are common to all attributes,
4886261991Sdim/// such as checking whether a parameter was properly specified, or the correct
4887261991Sdim/// number of arguments were passed, etc.
4888261991Sdimstatic bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
4889261991Sdim                                          const AttributeList &Attr) {
4890261991Sdim  // Several attributes carry different semantics than the parsing requires, so
4891261991Sdim  // those are opted out of the common handling.
4892261991Sdim  //
4893261991Sdim  // We also bail on unknown and ignored attributes because those are handled
4894261991Sdim  // as part of the target-specific handling logic.
4895261991Sdim  if (Attr.hasCustomParsing() ||
4896276479Sdim      Attr.getKind() == AttributeList::UnknownAttribute)
4897261991Sdim    return false;
4898261991Sdim
4899276479Sdim  // Check whether the attribute requires specific language extensions to be
4900276479Sdim  // enabled.
4901276479Sdim  if (!Attr.diagnoseLangOpts(S))
4902276479Sdim    return true;
4903276479Sdim
4904280031Sdim  if (Attr.getMinArgs() == Attr.getMaxArgs()) {
4905280031Sdim    // If there are no optional arguments, then checking for the argument count
4906280031Sdim    // is trivial.
4907280031Sdim    if (!checkAttributeNumArgs(S, Attr, Attr.getMinArgs()))
4908280031Sdim      return true;
4909280031Sdim  } else {
4910280031Sdim    // There are optional arguments, so checking is slightly more involved.
4911280031Sdim    if (Attr.getMinArgs() &&
4912280031Sdim        !checkAttributeAtLeastNumArgs(S, Attr, Attr.getMinArgs()))
4913280031Sdim      return true;
4914280031Sdim    else if (!Attr.hasVariadicArg() && Attr.getMaxArgs() &&
4915280031Sdim             !checkAttributeAtMostNumArgs(S, Attr, Attr.getMaxArgs()))
4916280031Sdim      return true;
4917280031Sdim  }
4918276479Sdim
4919276479Sdim  // Check whether the attribute appertains to the given subject.
4920276479Sdim  if (!Attr.diagnoseAppertainsTo(S, D))
4921276479Sdim    return true;
4922276479Sdim
4923261991Sdim  return false;
4924261991Sdim}
4925261991Sdim
4926218893Sdim//===----------------------------------------------------------------------===//
4927193326Sed// Top Level Sema Entry Points
4928193326Sed//===----------------------------------------------------------------------===//
4929193326Sed
4930261991Sdim/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
4931261991Sdim/// the attribute applies to decls.  If the attribute is a type attribute, just
4932261991Sdim/// silently ignore it if a GNU attribute.
4933261991Sdimstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
4934261991Sdim                                 const AttributeList &Attr,
4935261991Sdim                                 bool IncludeCXX11Attributes) {
4936276479Sdim  if (Attr.isInvalid() || Attr.getKind() == AttributeList::IgnoredAttribute)
4937261991Sdim    return;
4938207619Srdivacky
4939261991Sdim  // Ignore C++11 attributes on declarator chunks: they appertain to the type
4940261991Sdim  // instead.
4941261991Sdim  if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
4942261991Sdim    return;
4943261991Sdim
4944276479Sdim  // Unknown attributes are automatically warned on. Target-specific attributes
4945276479Sdim  // which do not apply to the current target architecture are treated as
4946276479Sdim  // though they were unknown attributes.
4947276479Sdim  if (Attr.getKind() == AttributeList::UnknownAttribute ||
4948296417Sdim      !Attr.existsInTarget(S.Context.getTargetInfo())) {
4949276479Sdim    S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute()
4950276479Sdim                              ? diag::warn_unhandled_ms_attribute_ignored
4951276479Sdim                              : diag::warn_unknown_attribute_ignored)
4952276479Sdim        << Attr.getName();
4953276479Sdim    return;
4954276479Sdim  }
4955276479Sdim
4956261991Sdim  if (handleCommonAttributeFeatures(S, scope, D, Attr))
4957261991Sdim    return;
4958261991Sdim
4959193326Sed  switch (Attr.getKind()) {
4960276479Sdim  default:
4961276479Sdim    // Type attributes are handled elsewhere; silently move on.
4962276479Sdim    assert(Attr.isTypeAttr() && "Non-type attribute not handled");
4963276479Sdim    break;
4964276479Sdim  case AttributeList::AT_Interrupt:
4965276479Sdim    handleInterruptAttr(S, D, Attr);
4966276479Sdim    break;
4967276479Sdim  case AttributeList::AT_X86ForceAlignArgPointer:
4968276479Sdim    handleX86ForceAlignArgPointerAttr(S, D, Attr);
4969276479Sdim    break;
4970276479Sdim  case AttributeList::AT_DLLExport:
4971276479Sdim  case AttributeList::AT_DLLImport:
4972276479Sdim    handleDLLAttr(S, D, Attr);
4973276479Sdim    break;
4974276479Sdim  case AttributeList::AT_Mips16:
4975296417Sdim    handleSimpleAttributeWithExclusions<Mips16Attr, MipsInterruptAttr>(S, D,
4976296417Sdim                                                                       Attr);
4977276479Sdim    break;
4978276479Sdim  case AttributeList::AT_NoMips16:
4979276479Sdim    handleSimpleAttribute<NoMips16Attr>(S, D, Attr);
4980276479Sdim    break;
4981280031Sdim  case AttributeList::AT_AMDGPUNumVGPR:
4982280031Sdim    handleAMDGPUNumVGPRAttr(S, D, Attr);
4983280031Sdim    break;
4984280031Sdim  case AttributeList::AT_AMDGPUNumSGPR:
4985280031Sdim    handleAMDGPUNumSGPRAttr(S, D, Attr);
4986280031Sdim    break;
4987276479Sdim  case AttributeList::AT_IBAction:
4988276479Sdim    handleSimpleAttribute<IBActionAttr>(S, D, Attr);
4989276479Sdim    break;
4990276479Sdim  case AttributeList::AT_IBOutlet:
4991276479Sdim    handleIBOutlet(S, D, Attr);
4992276479Sdim    break;
4993249423Sdim  case AttributeList::AT_IBOutletCollection:
4994276479Sdim    handleIBOutletCollection(S, D, Attr);
4995193326Sed    break;
4996276479Sdim  case AttributeList::AT_Alias:
4997276479Sdim    handleAliasAttr(S, D, Attr);
4998276479Sdim    break;
4999276479Sdim  case AttributeList::AT_Aligned:
5000276479Sdim    handleAlignedAttr(S, D, Attr);
5001276479Sdim    break;
5002280031Sdim  case AttributeList::AT_AlignValue:
5003280031Sdim    handleAlignValueAttr(S, D, Attr);
5004280031Sdim    break;
5005239462Sdim  case AttributeList::AT_AlwaysInline:
5006276479Sdim    handleAlwaysInlineAttr(S, D, Attr);
5007276479Sdim    break;
5008239462Sdim  case AttributeList::AT_AnalyzerNoReturn:
5009276479Sdim    handleAnalyzerNoReturnAttr(S, D, Attr);
5010276479Sdim    break;
5011276479Sdim  case AttributeList::AT_TLSModel:
5012276479Sdim    handleTLSModelAttr(S, D, Attr);
5013276479Sdim    break;
5014276479Sdim  case AttributeList::AT_Annotate:
5015276479Sdim    handleAnnotateAttr(S, D, Attr);
5016276479Sdim    break;
5017276479Sdim  case AttributeList::AT_Availability:
5018276479Sdim    handleAvailabilityAttr(S, D, Attr);
5019276479Sdim    break;
5020239462Sdim  case AttributeList::AT_CarriesDependency:
5021249423Sdim    handleDependencyAttr(S, scope, D, Attr);
5022249423Sdim    break;
5023276479Sdim  case AttributeList::AT_Common:
5024276479Sdim    handleCommonAttr(S, D, Attr);
5025276479Sdim    break;
5026276479Sdim  case AttributeList::AT_CUDAConstant:
5027296417Sdim    handleSimpleAttributeWithExclusions<CUDAConstantAttr, CUDASharedAttr>(S, D,
5028296417Sdim                                                                          Attr);
5029276479Sdim    break;
5030296417Sdim  case AttributeList::AT_PassObjectSize:
5031296417Sdim    handlePassObjectSizeAttr(S, D, Attr);
5032296417Sdim    break;
5033276479Sdim  case AttributeList::AT_Constructor:
5034276479Sdim    handleConstructorAttr(S, D, Attr);
5035276479Sdim    break;
5036249423Sdim  case AttributeList::AT_CXX11NoReturn:
5037276479Sdim    handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);
5038249423Sdim    break;
5039239462Sdim  case AttributeList::AT_Deprecated:
5040280031Sdim    handleDeprecatedAttr(S, D, Attr);
5041239462Sdim    break;
5042276479Sdim  case AttributeList::AT_Destructor:
5043276479Sdim    handleDestructorAttr(S, D, Attr);
5044276479Sdim    break;
5045276479Sdim  case AttributeList::AT_EnableIf:
5046276479Sdim    handleEnableIfAttr(S, D, Attr);
5047276479Sdim    break;
5048239462Sdim  case AttributeList::AT_ExtVectorType:
5049224145Sdim    handleExtVectorTypeAttr(S, scope, D, Attr);
5050193326Sed    break;
5051243830Sdim  case AttributeList::AT_MinSize:
5052280031Sdim    handleMinSizeAttr(S, D, Attr);
5053243830Sdim    break;
5054276479Sdim  case AttributeList::AT_OptimizeNone:
5055276479Sdim    handleOptimizeNoneAttr(S, D, Attr);
5056276479Sdim    break;
5057288943Sdim  case AttributeList::AT_FlagEnum:
5058288943Sdim    handleSimpleAttribute<FlagEnumAttr>(S, D, Attr);
5059288943Sdim    break;
5060276479Sdim  case AttributeList::AT_Flatten:
5061276479Sdim    handleSimpleAttribute<FlattenAttr>(S, D, Attr);
5062276479Sdim    break;
5063276479Sdim  case AttributeList::AT_Format:
5064276479Sdim    handleFormatAttr(S, D, Attr);
5065276479Sdim    break;
5066276479Sdim  case AttributeList::AT_FormatArg:
5067276479Sdim    handleFormatArgAttr(S, D, Attr);
5068276479Sdim    break;
5069276479Sdim  case AttributeList::AT_CUDAGlobal:
5070276479Sdim    handleGlobalAttr(S, D, Attr);
5071276479Sdim    break;
5072276479Sdim  case AttributeList::AT_CUDADevice:
5073296417Sdim    handleSimpleAttributeWithExclusions<CUDADeviceAttr, CUDAGlobalAttr>(S, D,
5074296417Sdim                                                                        Attr);
5075276479Sdim    break;
5076276479Sdim  case AttributeList::AT_CUDAHost:
5077296417Sdim    handleSimpleAttributeWithExclusions<CUDAHostAttr, CUDAGlobalAttr>(S, D,
5078296417Sdim                                                                      Attr);
5079276479Sdim    break;
5080276479Sdim  case AttributeList::AT_GNUInline:
5081276479Sdim    handleGNUInlineAttr(S, D, Attr);
5082276479Sdim    break;
5083239462Sdim  case AttributeList::AT_CUDALaunchBounds:
5084224145Sdim    handleLaunchBoundsAttr(S, D, Attr);
5085218893Sdim    break;
5086288943Sdim  case AttributeList::AT_Restrict:
5087288943Sdim    handleRestrictAttr(S, D, Attr);
5088276479Sdim    break;
5089276479Sdim  case AttributeList::AT_MayAlias:
5090276479Sdim    handleSimpleAttribute<MayAliasAttr>(S, D, Attr);
5091276479Sdim    break;
5092276479Sdim  case AttributeList::AT_Mode:
5093276479Sdim    handleModeAttr(S, D, Attr);
5094276479Sdim    break;
5095296417Sdim  case AttributeList::AT_NoAlias:
5096296417Sdim    handleSimpleAttribute<NoAliasAttr>(S, D, Attr);
5097296417Sdim    break;
5098276479Sdim  case AttributeList::AT_NoCommon:
5099276479Sdim    handleSimpleAttribute<NoCommonAttr>(S, D, Attr);
5100276479Sdim    break;
5101276479Sdim  case AttributeList::AT_NoSplitStack:
5102276479Sdim    handleSimpleAttribute<NoSplitStackAttr>(S, D, Attr);
5103276479Sdim    break;
5104276479Sdim  case AttributeList::AT_NonNull:
5105276479Sdim    if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(D))
5106276479Sdim      handleNonNullAttrParameter(S, PVD, Attr);
5107276479Sdim    else
5108276479Sdim      handleNonNullAttr(S, D, Attr);
5109276479Sdim    break;
5110276479Sdim  case AttributeList::AT_ReturnsNonNull:
5111276479Sdim    handleReturnsNonNullAttr(S, D, Attr);
5112276479Sdim    break;
5113280031Sdim  case AttributeList::AT_AssumeAligned:
5114280031Sdim    handleAssumeAlignedAttr(S, D, Attr);
5115280031Sdim    break;
5116276479Sdim  case AttributeList::AT_Overloadable:
5117276479Sdim    handleSimpleAttribute<OverloadableAttr>(S, D, Attr);
5118276479Sdim    break;
5119276479Sdim  case AttributeList::AT_Ownership:
5120276479Sdim    handleOwnershipAttr(S, D, Attr);
5121276479Sdim    break;
5122276479Sdim  case AttributeList::AT_Cold:
5123276479Sdim    handleColdAttr(S, D, Attr);
5124276479Sdim    break;
5125276479Sdim  case AttributeList::AT_Hot:
5126276479Sdim    handleHotAttr(S, D, Attr);
5127276479Sdim    break;
5128276479Sdim  case AttributeList::AT_Naked:
5129296417Sdim    handleNakedAttr(S, D, Attr);
5130276479Sdim    break;
5131276479Sdim  case AttributeList::AT_NoReturn:
5132276479Sdim    handleNoReturnAttr(S, D, Attr);
5133276479Sdim    break;
5134276479Sdim  case AttributeList::AT_NoThrow:
5135276479Sdim    handleSimpleAttribute<NoThrowAttr>(S, D, Attr);
5136276479Sdim    break;
5137276479Sdim  case AttributeList::AT_CUDAShared:
5138296417Sdim    handleSimpleAttributeWithExclusions<CUDASharedAttr, CUDAConstantAttr>(S, D,
5139296417Sdim                                                                          Attr);
5140276479Sdim    break;
5141276479Sdim  case AttributeList::AT_VecReturn:
5142276479Sdim    handleVecReturnAttr(S, D, Attr);
5143276479Sdim    break;
5144193326Sed
5145239462Sdim  case AttributeList::AT_ObjCOwnership:
5146276479Sdim    handleObjCOwnershipAttr(S, D, Attr);
5147276479Sdim    break;
5148239462Sdim  case AttributeList::AT_ObjCPreciseLifetime:
5149276479Sdim    handleObjCPreciseLifetimeAttr(S, D, Attr);
5150276479Sdim    break;
5151224145Sdim
5152239462Sdim  case AttributeList::AT_ObjCReturnsInnerPointer:
5153276479Sdim    handleObjCReturnsInnerPointerAttr(S, D, Attr);
5154276479Sdim    break;
5155226633Sdim
5156243830Sdim  case AttributeList::AT_ObjCRequiresSuper:
5157276479Sdim    handleObjCRequiresSuperAttr(S, D, Attr);
5158276479Sdim    break;
5159276479Sdim
5160261991Sdim  case AttributeList::AT_ObjCBridge:
5161276479Sdim    handleObjCBridgeAttr(S, scope, D, Attr);
5162276479Sdim    break;
5163226633Sdim
5164276479Sdim  case AttributeList::AT_ObjCBridgeMutable:
5165276479Sdim    handleObjCBridgeMutableAttr(S, scope, D, Attr);
5166276479Sdim    break;
5167276479Sdim
5168276479Sdim  case AttributeList::AT_ObjCBridgeRelated:
5169276479Sdim    handleObjCBridgeRelatedAttr(S, scope, D, Attr);
5170276479Sdim    break;
5171276479Sdim
5172276479Sdim  case AttributeList::AT_ObjCDesignatedInitializer:
5173276479Sdim    handleObjCDesignatedInitializer(S, D, Attr);
5174276479Sdim    break;
5175276479Sdim
5176276479Sdim  case AttributeList::AT_ObjCRuntimeName:
5177276479Sdim    handleObjCRuntimeName(S, D, Attr);
5178276479Sdim    break;
5179288943Sdim
5180288943Sdim  case AttributeList::AT_ObjCBoxable:
5181288943Sdim    handleObjCBoxable(S, D, Attr);
5182288943Sdim    break;
5183276479Sdim
5184239462Sdim  case AttributeList::AT_CFAuditedTransfer:
5185276479Sdim    handleCFAuditedTransferAttr(S, D, Attr);
5186276479Sdim    break;
5187239462Sdim  case AttributeList::AT_CFUnknownTransfer:
5188276479Sdim    handleCFUnknownTransferAttr(S, D, Attr);
5189276479Sdim    break;
5190226633Sdim
5191239462Sdim  case AttributeList::AT_CFConsumed:
5192276479Sdim  case AttributeList::AT_NSConsumed:
5193276479Sdim    handleNSConsumedAttr(S, D, Attr);
5194276479Sdim    break;
5195239462Sdim  case AttributeList::AT_NSConsumesSelf:
5196276479Sdim    handleSimpleAttribute<NSConsumesSelfAttr>(S, D, Attr);
5197276479Sdim    break;
5198218893Sdim
5199239462Sdim  case AttributeList::AT_NSReturnsAutoreleased:
5200239462Sdim  case AttributeList::AT_NSReturnsNotRetained:
5201239462Sdim  case AttributeList::AT_CFReturnsNotRetained:
5202239462Sdim  case AttributeList::AT_NSReturnsRetained:
5203239462Sdim  case AttributeList::AT_CFReturnsRetained:
5204276479Sdim    handleNSReturnsRetainedAttr(S, D, Attr);
5205276479Sdim    break;
5206239462Sdim  case AttributeList::AT_WorkGroupSizeHint:
5207276479Sdim    handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, Attr);
5208276479Sdim    break;
5209239462Sdim  case AttributeList::AT_ReqdWorkGroupSize:
5210276479Sdim    handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, Attr);
5211276479Sdim    break;
5212249423Sdim  case AttributeList::AT_VecTypeHint:
5213276479Sdim    handleVecTypeHint(S, D, Attr);
5214276479Sdim    break;
5215249423Sdim
5216276479Sdim  case AttributeList::AT_InitPriority:
5217276479Sdim    handleInitPriorityAttr(S, D, Attr);
5218276479Sdim    break;
5219276479Sdim
5220276479Sdim  case AttributeList::AT_Packed:
5221276479Sdim    handlePackedAttr(S, D, Attr);
5222276479Sdim    break;
5223276479Sdim  case AttributeList::AT_Section:
5224276479Sdim    handleSectionAttr(S, D, Attr);
5225276479Sdim    break;
5226288943Sdim  case AttributeList::AT_Target:
5227288943Sdim    handleTargetAttr(S, D, Attr);
5228288943Sdim    break;
5229239462Sdim  case AttributeList::AT_Unavailable:
5230261991Sdim    handleAttrWithMessage<UnavailableAttr>(S, D, Attr);
5231239462Sdim    break;
5232276479Sdim  case AttributeList::AT_ArcWeakrefUnavailable:
5233276479Sdim    handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, Attr);
5234193326Sed    break;
5235239462Sdim  case AttributeList::AT_ObjCRootClass:
5236276479Sdim    handleSimpleAttribute<ObjCRootClassAttr>(S, D, Attr);
5237234353Sdim    break;
5238276479Sdim  case AttributeList::AT_ObjCExplicitProtocolImpl:
5239276479Sdim    handleObjCSuppresProtocolAttr(S, D, Attr);
5240234353Sdim    break;
5241276479Sdim  case AttributeList::AT_ObjCRequiresPropertyDefs:
5242276479Sdim    handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, Attr);
5243276479Sdim    break;
5244276479Sdim  case AttributeList::AT_Unused:
5245276479Sdim    handleSimpleAttribute<UnusedAttr>(S, D, Attr);
5246276479Sdim    break;
5247239462Sdim  case AttributeList::AT_ReturnsTwice:
5248276479Sdim    handleSimpleAttribute<ReturnsTwiceAttr>(S, D, Attr);
5249226633Sdim    break;
5250296417Sdim  case AttributeList::AT_NotTailCalled:
5251296417Sdim    handleNotTailCalledAttr(S, D, Attr);
5252296417Sdim    break;
5253296417Sdim  case AttributeList::AT_DisableTailCalls:
5254296417Sdim    handleDisableTailCallsAttr(S, D, Attr);
5255296417Sdim    break;
5256276479Sdim  case AttributeList::AT_Used:
5257276479Sdim    handleUsedAttr(S, D, Attr);
5258276479Sdim    break;
5259249423Sdim  case AttributeList::AT_Visibility:
5260249423Sdim    handleVisibilityAttr(S, D, Attr, false);
5261249423Sdim    break;
5262249423Sdim  case AttributeList::AT_TypeVisibility:
5263249423Sdim    handleVisibilityAttr(S, D, Attr, true);
5264249423Sdim    break;
5265261991Sdim  case AttributeList::AT_WarnUnused:
5266276479Sdim    handleSimpleAttribute<WarnUnusedAttr>(S, D, Attr);
5267261991Sdim    break;
5268276479Sdim  case AttributeList::AT_WarnUnusedResult:
5269276479Sdim    handleWarnUnusedResult(S, D, Attr);
5270224145Sdim    break;
5271276479Sdim  case AttributeList::AT_Weak:
5272276479Sdim    handleSimpleAttribute<WeakAttr>(S, D, Attr);
5273276479Sdim    break;
5274276479Sdim  case AttributeList::AT_WeakRef:
5275276479Sdim    handleWeakRefAttr(S, D, Attr);
5276276479Sdim    break;
5277276479Sdim  case AttributeList::AT_WeakImport:
5278276479Sdim    handleWeakImportAttr(S, D, Attr);
5279276479Sdim    break;
5280239462Sdim  case AttributeList::AT_TransparentUnion:
5281224145Sdim    handleTransparentUnionAttr(S, D, Attr);
5282193326Sed    break;
5283239462Sdim  case AttributeList::AT_ObjCException:
5284276479Sdim    handleSimpleAttribute<ObjCExceptionAttr>(S, D, Attr);
5285193326Sed    break;
5286239462Sdim  case AttributeList::AT_ObjCMethodFamily:
5287224145Sdim    handleObjCMethodFamilyAttr(S, D, Attr);
5288221345Sdim    break;
5289276479Sdim  case AttributeList::AT_ObjCNSObject:
5290276479Sdim    handleObjCNSObject(S, D, Attr);
5291193326Sed    break;
5292288943Sdim  case AttributeList::AT_ObjCIndependentClass:
5293288943Sdim    handleObjCIndependentClass(S, D, Attr);
5294288943Sdim    break;
5295276479Sdim  case AttributeList::AT_Blocks:
5296276479Sdim    handleBlocksAttr(S, D, Attr);
5297210299Sed    break;
5298276479Sdim  case AttributeList::AT_Sentinel:
5299276479Sdim    handleSentinelAttr(S, D, Attr);
5300276479Sdim    break;
5301276479Sdim  case AttributeList::AT_Const:
5302276479Sdim    handleSimpleAttribute<ConstAttr>(S, D, Attr);
5303276479Sdim    break;
5304276479Sdim  case AttributeList::AT_Pure:
5305276479Sdim    handleSimpleAttribute<PureAttr>(S, D, Attr);
5306276479Sdim    break;
5307276479Sdim  case AttributeList::AT_Cleanup:
5308276479Sdim    handleCleanupAttr(S, D, Attr);
5309276479Sdim    break;
5310276479Sdim  case AttributeList::AT_NoDebug:
5311276479Sdim    handleNoDebugAttr(S, D, Attr);
5312276479Sdim    break;
5313276479Sdim  case AttributeList::AT_NoDuplicate:
5314276479Sdim    handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr);
5315276479Sdim    break;
5316276479Sdim  case AttributeList::AT_NoInline:
5317276479Sdim    handleSimpleAttribute<NoInlineAttr>(S, D, Attr);
5318276479Sdim    break;
5319276479Sdim  case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
5320276479Sdim    handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, Attr);
5321276479Sdim    break;
5322239462Sdim  case AttributeList::AT_StdCall:
5323239462Sdim  case AttributeList::AT_CDecl:
5324239462Sdim  case AttributeList::AT_FastCall:
5325239462Sdim  case AttributeList::AT_ThisCall:
5326239462Sdim  case AttributeList::AT_Pascal:
5327280031Sdim  case AttributeList::AT_VectorCall:
5328256030Sdim  case AttributeList::AT_MSABI:
5329256030Sdim  case AttributeList::AT_SysVABI:
5330239462Sdim  case AttributeList::AT_Pcs:
5331249423Sdim  case AttributeList::AT_IntelOclBicc:
5332224145Sdim    handleCallConvAttr(S, D, Attr);
5333203955Srdivacky    break;
5334239462Sdim  case AttributeList::AT_OpenCLKernel:
5335276479Sdim    handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr);
5336218893Sdim    break;
5337249423Sdim  case AttributeList::AT_OpenCLImageAccess:
5338276479Sdim    handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr);
5339249423Sdim    break;
5340296417Sdim  case AttributeList::AT_InternalLinkage:
5341296417Sdim    handleInternalLinkageAttr(S, D, Attr);
5342296417Sdim    break;
5343239462Sdim
5344239462Sdim  // Microsoft attributes:
5345288943Sdim  case AttributeList::AT_MSNoVTable:
5346288943Sdim    handleSimpleAttribute<MSNoVTableAttr>(S, D, Attr);
5347239462Sdim    break;
5348288943Sdim  case AttributeList::AT_MSStruct:
5349288943Sdim    handleSimpleAttribute<MSStructAttr>(S, D, Attr);
5350288943Sdim    break;
5351239462Sdim  case AttributeList::AT_Uuid:
5352224145Sdim    handleUuidAttr(S, D, Attr);
5353218893Sdim    break;
5354276479Sdim  case AttributeList::AT_MSInheritance:
5355276479Sdim    handleMSInheritanceAttr(S, D, Attr);
5356239462Sdim    break;
5357276479Sdim  case AttributeList::AT_SelectAny:
5358276479Sdim    handleSimpleAttribute<SelectAnyAttr>(S, D, Attr);
5359239462Sdim    break;
5360276479Sdim  case AttributeList::AT_Thread:
5361276479Sdim    handleDeclspecThreadAttr(S, D, Attr);
5362239462Sdim    break;
5363226633Sdim
5364226633Sdim  // Thread safety attributes:
5365261991Sdim  case AttributeList::AT_AssertExclusiveLock:
5366261991Sdim    handleAssertExclusiveLockAttr(S, D, Attr);
5367261991Sdim    break;
5368261991Sdim  case AttributeList::AT_AssertSharedLock:
5369261991Sdim    handleAssertSharedLockAttr(S, D, Attr);
5370261991Sdim    break;
5371239462Sdim  case AttributeList::AT_GuardedVar:
5372276479Sdim    handleSimpleAttribute<GuardedVarAttr>(S, D, Attr);
5373226633Sdim    break;
5374239462Sdim  case AttributeList::AT_PtGuardedVar:
5375239462Sdim    handlePtGuardedVarAttr(S, D, Attr);
5376226633Sdim    break;
5377239462Sdim  case AttributeList::AT_ScopedLockable:
5378276479Sdim    handleSimpleAttribute<ScopedLockableAttr>(S, D, Attr);
5379226633Sdim    break;
5380288943Sdim  case AttributeList::AT_NoSanitize:
5381288943Sdim    handleNoSanitizeAttr(S, D, Attr);
5382234353Sdim    break;
5383288943Sdim  case AttributeList::AT_NoSanitizeSpecific:
5384288943Sdim    handleNoSanitizeSpecificAttr(S, D, Attr);
5385288943Sdim    break;
5386239462Sdim  case AttributeList::AT_NoThreadSafetyAnalysis:
5387276479Sdim    handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, Attr);
5388226633Sdim    break;
5389239462Sdim  case AttributeList::AT_GuardedBy:
5390226633Sdim    handleGuardedByAttr(S, D, Attr);
5391226633Sdim    break;
5392239462Sdim  case AttributeList::AT_PtGuardedBy:
5393239462Sdim    handlePtGuardedByAttr(S, D, Attr);
5394226633Sdim    break;
5395239462Sdim  case AttributeList::AT_ExclusiveTrylockFunction:
5396239462Sdim    handleExclusiveTrylockFunctionAttr(S, D, Attr);
5397226633Sdim    break;
5398239462Sdim  case AttributeList::AT_LockReturned:
5399226633Sdim    handleLockReturnedAttr(S, D, Attr);
5400226633Sdim    break;
5401239462Sdim  case AttributeList::AT_LocksExcluded:
5402226633Sdim    handleLocksExcludedAttr(S, D, Attr);
5403226633Sdim    break;
5404239462Sdim  case AttributeList::AT_SharedTrylockFunction:
5405239462Sdim    handleSharedTrylockFunctionAttr(S, D, Attr);
5406226633Sdim    break;
5407239462Sdim  case AttributeList::AT_AcquiredBefore:
5408239462Sdim    handleAcquiredBeforeAttr(S, D, Attr);
5409226633Sdim    break;
5410239462Sdim  case AttributeList::AT_AcquiredAfter:
5411239462Sdim    handleAcquiredAfterAttr(S, D, Attr);
5412226633Sdim    break;
5413226633Sdim
5414276479Sdim  // Capability analysis attributes.
5415276479Sdim  case AttributeList::AT_Capability:
5416276479Sdim  case AttributeList::AT_Lockable:
5417276479Sdim    handleCapabilityAttr(S, D, Attr);
5418276479Sdim    break;
5419276479Sdim  case AttributeList::AT_RequiresCapability:
5420276479Sdim    handleRequiresCapabilityAttr(S, D, Attr);
5421276479Sdim    break;
5422276479Sdim
5423276479Sdim  case AttributeList::AT_AssertCapability:
5424276479Sdim    handleAssertCapabilityAttr(S, D, Attr);
5425276479Sdim    break;
5426276479Sdim  case AttributeList::AT_AcquireCapability:
5427276479Sdim    handleAcquireCapabilityAttr(S, D, Attr);
5428276479Sdim    break;
5429276479Sdim  case AttributeList::AT_ReleaseCapability:
5430276479Sdim    handleReleaseCapabilityAttr(S, D, Attr);
5431276479Sdim    break;
5432276479Sdim  case AttributeList::AT_TryAcquireCapability:
5433276479Sdim    handleTryAcquireCapabilityAttr(S, D, Attr);
5434276479Sdim    break;
5435276479Sdim
5436261991Sdim  // Consumed analysis attributes.
5437261991Sdim  case AttributeList::AT_Consumable:
5438261991Sdim    handleConsumableAttr(S, D, Attr);
5439261991Sdim    break;
5440276479Sdim  case AttributeList::AT_ConsumableAutoCast:
5441276479Sdim    handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, Attr);
5442276479Sdim    break;
5443276479Sdim  case AttributeList::AT_ConsumableSetOnRead:
5444276479Sdim    handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, Attr);
5445276479Sdim    break;
5446261991Sdim  case AttributeList::AT_CallableWhen:
5447261991Sdim    handleCallableWhenAttr(S, D, Attr);
5448261991Sdim    break;
5449261991Sdim  case AttributeList::AT_ParamTypestate:
5450261991Sdim    handleParamTypestateAttr(S, D, Attr);
5451261991Sdim    break;
5452261991Sdim  case AttributeList::AT_ReturnTypestate:
5453261991Sdim    handleReturnTypestateAttr(S, D, Attr);
5454261991Sdim    break;
5455261991Sdim  case AttributeList::AT_SetTypestate:
5456261991Sdim    handleSetTypestateAttr(S, D, Attr);
5457261991Sdim    break;
5458261991Sdim  case AttributeList::AT_TestTypestate:
5459261991Sdim    handleTestTypestateAttr(S, D, Attr);
5460261991Sdim    break;
5461261991Sdim
5462239462Sdim  // Type safety attributes.
5463239462Sdim  case AttributeList::AT_ArgumentWithTypeTag:
5464239462Sdim    handleArgumentWithTypeTagAttr(S, D, Attr);
5465239462Sdim    break;
5466239462Sdim  case AttributeList::AT_TypeTagForDatatype:
5467239462Sdim    handleTypeTagForDatatypeAttr(S, D, Attr);
5468239462Sdim    break;
5469193326Sed  }
5470193326Sed}
5471193326Sed
5472193326Sed/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
5473193326Sed/// attribute list to the specified decl, ignoring any type attributes.
5474218893Sdimvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
5475218893Sdim                                    const AttributeList *AttrList,
5476249423Sdim                                    bool IncludeCXX11Attributes) {
5477249423Sdim  for (const AttributeList* l = AttrList; l; l = l->getNext())
5478261991Sdim    ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes);
5479204643Srdivacky
5480276479Sdim  // FIXME: We should be able to handle these cases in TableGen.
5481204643Srdivacky  // GCC accepts
5482204643Srdivacky  // static int a9 __attribute__((weakref));
5483204643Srdivacky  // but that looks really pointless. We reject it.
5484261991Sdim  if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
5485276479Sdim    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias)
5486276479Sdim      << cast<NamedDecl>(D);
5487249423Sdim    D->dropAttr<WeakRefAttr>();
5488204643Srdivacky    return;
5489204643Srdivacky  }
5490276479Sdim
5491280031Sdim  // FIXME: We should be able to handle this in TableGen as well. It would be
5492280031Sdim  // good to have a way to specify "these attributes must appear as a group",
5493280031Sdim  // for these. Additionally, it would be good to have a way to specify "these
5494280031Sdim  // attribute must never appear as a group" for attributes like cold and hot.
5495276479Sdim  if (!D->hasAttr<OpenCLKernelAttr>()) {
5496276479Sdim    // These attributes cannot be applied to a non-kernel function.
5497276479Sdim    if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
5498280031Sdim      // FIXME: This emits a different error message than
5499280031Sdim      // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
5500276479Sdim      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
5501276479Sdim      D->setInvalidDecl();
5502280031Sdim    } else if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) {
5503276479Sdim      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
5504276479Sdim      D->setInvalidDecl();
5505280031Sdim    } else if (Attr *A = D->getAttr<VecTypeHintAttr>()) {
5506276479Sdim      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
5507276479Sdim      D->setInvalidDecl();
5508280031Sdim    } else if (Attr *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
5509280031Sdim      Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
5510280031Sdim        << A << ExpectedKernelFunction;
5511280031Sdim      D->setInvalidDecl();
5512280031Sdim    } else if (Attr *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
5513280031Sdim      Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
5514280031Sdim        << A << ExpectedKernelFunction;
5515280031Sdim      D->setInvalidDecl();
5516276479Sdim    }
5517276479Sdim  }
5518193326Sed}
5519193326Sed
5520226633Sdim// Annotation attributes are the only attributes allowed after an access
5521226633Sdim// specifier.
5522226633Sdimbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
5523226633Sdim                                          const AttributeList *AttrList) {
5524226633Sdim  for (const AttributeList* l = AttrList; l; l = l->getNext()) {
5525239462Sdim    if (l->getKind() == AttributeList::AT_Annotate) {
5526280031Sdim      ProcessDeclAttribute(*this, nullptr, ASDecl, *l, l->isCXX11Attribute());
5527226633Sdim    } else {
5528226633Sdim      Diag(l->getLoc(), diag::err_only_annotate_after_access_spec);
5529226633Sdim      return true;
5530226633Sdim    }
5531226633Sdim  }
5532226633Sdim
5533226633Sdim  return false;
5534226633Sdim}
5535226633Sdim
5536226633Sdim/// checkUnusedDeclAttributes - Check a list of attributes to see if it
5537226633Sdim/// contains any decl attributes that we should warn about.
5538226633Sdimstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) {
5539226633Sdim  for ( ; A; A = A->getNext()) {
5540226633Sdim    // Only warn if the attribute is an unignored, non-type attribute.
5541249423Sdim    if (A->isUsedAsTypeAttr() || A->isInvalid()) continue;
5542226633Sdim    if (A->getKind() == AttributeList::IgnoredAttribute) continue;
5543226633Sdim
5544226633Sdim    if (A->getKind() == AttributeList::UnknownAttribute) {
5545226633Sdim      S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored)
5546226633Sdim        << A->getName() << A->getRange();
5547226633Sdim    } else {
5548226633Sdim      S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl)
5549226633Sdim        << A->getName() << A->getRange();
5550226633Sdim    }
5551226633Sdim  }
5552226633Sdim}
5553226633Sdim
5554226633Sdim/// checkUnusedDeclAttributes - Given a declarator which is not being
5555226633Sdim/// used to build a declaration, complain about any decl attributes
5556226633Sdim/// which might be lying around on it.
5557226633Sdimvoid Sema::checkUnusedDeclAttributes(Declarator &D) {
5558226633Sdim  ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList());
5559226633Sdim  ::checkUnusedDeclAttributes(*this, D.getAttributes());
5560226633Sdim  for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
5561226633Sdim    ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
5562226633Sdim}
5563226633Sdim
5564198092Srdivacky/// DeclClonePragmaWeak - clone existing decl (maybe definition),
5565239462Sdim/// \#pragma weak needs a non-definition decl and source may not have one.
5566226633SdimNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
5567226633Sdim                                      SourceLocation Loc) {
5568198092Srdivacky  assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
5569276479Sdim  NamedDecl *NewD = nullptr;
5570198092Srdivacky  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
5571226633Sdim    FunctionDecl *NewFD;
5572226633Sdim    // FIXME: Missing call to CheckFunctionDeclaration().
5573226633Sdim    // FIXME: Mangling?
5574226633Sdim    // FIXME: Is the qualifier info correct?
5575226633Sdim    // FIXME: Is the DeclContext correct?
5576226633Sdim    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
5577226633Sdim                                 Loc, Loc, DeclarationName(II),
5578226633Sdim                                 FD->getType(), FD->getTypeSourceInfo(),
5579249423Sdim                                 SC_None, false/*isInlineSpecified*/,
5580226633Sdim                                 FD->hasPrototype(),
5581226633Sdim                                 false/*isConstexprSpecified*/);
5582226633Sdim    NewD = NewFD;
5583226633Sdim
5584226633Sdim    if (FD->getQualifier())
5585219077Sdim      NewFD->setQualifierInfo(FD->getQualifierLoc());
5586226633Sdim
5587226633Sdim    // Fake up parameter variables; they are declared as if this were
5588226633Sdim    // a typedef.
5589226633Sdim    QualType FDTy = FD->getType();
5590226633Sdim    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
5591226633Sdim      SmallVector<ParmVarDecl*, 16> Params;
5592276479Sdim      for (const auto &AI : FT->param_types()) {
5593276479Sdim        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
5594226633Sdim        Param->setScopeInfo(0, Params.size());
5595226633Sdim        Params.push_back(Param);
5596226633Sdim      }
5597226633Sdim      NewFD->setParams(Params);
5598205219Srdivacky    }
5599198092Srdivacky  } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
5600198092Srdivacky    NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
5601221345Sdim                           VD->getInnerLocStart(), VD->getLocation(), II,
5602200583Srdivacky                           VD->getType(), VD->getTypeSourceInfo(),
5603249423Sdim                           VD->getStorageClass());
5604205219Srdivacky    if (VD->getQualifier()) {
5605205219Srdivacky      VarDecl *NewVD = cast<VarDecl>(NewD);
5606219077Sdim      NewVD->setQualifierInfo(VD->getQualifierLoc());
5607205219Srdivacky    }
5608198092Srdivacky  }
5609198092Srdivacky  return NewD;
5610198092Srdivacky}
5611198092Srdivacky
5612239462Sdim/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak
5613198092Srdivacky/// applied to it, possibly with an alias.
5614198092Srdivackyvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
5615198092Srdivacky  if (W.getUsed()) return; // only do this once
5616198092Srdivacky  W.setUsed(true);
5617198092Srdivacky  if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
5618198092Srdivacky    IdentifierInfo *NDId = ND->getIdentifier();
5619226633Sdim    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
5620276479Sdim    NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(),
5621276479Sdim                                            W.getLocation()));
5622276479Sdim    NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
5623198092Srdivacky    WeakTopLevelDecl.push_back(NewD);
5624198092Srdivacky    // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
5625198092Srdivacky    // to insert Decl at TU scope, sorry.
5626198092Srdivacky    DeclContext *SavedContext = CurContext;
5627198092Srdivacky    CurContext = Context.getTranslationUnitDecl();
5628276479Sdim    NewD->setDeclContext(CurContext);
5629276479Sdim    NewD->setLexicalDeclContext(CurContext);
5630198092Srdivacky    PushOnScopeChains(NewD, S);
5631198092Srdivacky    CurContext = SavedContext;
5632198092Srdivacky  } else { // just add weak to existing
5633276479Sdim    ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
5634198092Srdivacky  }
5635198092Srdivacky}
5636198092Srdivacky
5637249423Sdimvoid Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
5638218893Sdim  // It's valid to "forward-declare" #pragma weak, in which case we
5639218893Sdim  // have to do this.
5640249423Sdim  LoadExternalWeakUndeclaredIdentifiers();
5641249423Sdim  if (!WeakUndeclaredIdentifiers.empty()) {
5642276479Sdim    NamedDecl *ND = nullptr;
5643249423Sdim    if (VarDecl *VD = dyn_cast<VarDecl>(D))
5644249423Sdim      if (VD->isExternC())
5645249423Sdim        ND = VD;
5646249423Sdim    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5647249423Sdim      if (FD->isExternC())
5648249423Sdim        ND = FD;
5649249423Sdim    if (ND) {
5650249423Sdim      if (IdentifierInfo *Id = ND->getIdentifier()) {
5651288943Sdim        auto I = WeakUndeclaredIdentifiers.find(Id);
5652249423Sdim        if (I != WeakUndeclaredIdentifiers.end()) {
5653249423Sdim          WeakInfo W = I->second;
5654249423Sdim          DeclApplyPragmaWeak(S, ND, W);
5655249423Sdim          WeakUndeclaredIdentifiers[Id] = W;
5656218893Sdim        }
5657198092Srdivacky      }
5658198092Srdivacky    }
5659198092Srdivacky  }
5660249423Sdim}
5661198092Srdivacky
5662249423Sdim/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
5663249423Sdim/// it, apply them to D.  This is a bit tricky because PD can have attributes
5664249423Sdim/// specified in many different places, and we need to find and apply them all.
5665261991Sdimvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
5666193326Sed  // Apply decl attributes from the DeclSpec if present.
5667218893Sdim  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
5668261991Sdim    ProcessDeclAttributeList(S, D, Attrs);
5669198092Srdivacky
5670193326Sed  // Walk the declarator structure, applying decl attributes that were in a type
5671193326Sed  // position to the decl itself.  This handles cases like:
5672193326Sed  //   int *__attr__(x)** D;
5673193326Sed  // when X is a decl attribute.
5674193326Sed  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
5675193326Sed    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
5676261991Sdim      ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false);
5677198092Srdivacky
5678193326Sed  // Finally, apply any attributes on the decl itself.
5679193326Sed  if (const AttributeList *Attrs = PD.getAttributes())
5680261991Sdim    ProcessDeclAttributeList(S, D, Attrs);
5681193326Sed}
5682198893Srdivacky
5683224145Sdim/// Is the given declaration allowed to use a forbidden type?
5684296417Sdim/// If so, it'll still be annotated with an attribute that makes it
5685296417Sdim/// illegal to actually use.
5686296417Sdimstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl,
5687296417Sdim                                   const DelayedDiagnostic &diag,
5688296417Sdim                                   UnavailableAttr::ImplicitReason &reason) {
5689224145Sdim  // Private ivars are always okay.  Unfortunately, people don't
5690224145Sdim  // always properly make their ivars private, even in system headers.
5691224145Sdim  // Plus we need to make fields okay, too.
5692226633Sdim  if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
5693226633Sdim      !isa<FunctionDecl>(decl))
5694224145Sdim    return false;
5695224145Sdim
5696296417Sdim  // Silently accept unsupported uses of __weak in both user and system
5697296417Sdim  // declarations when it's been disabled, for ease of integration with
5698296417Sdim  // -fno-objc-arc files.  We do have to take some care against attempts
5699296417Sdim  // to define such things;  for now, we've only done that for ivars
5700296417Sdim  // and properties.
5701296417Sdim  if ((isa<ObjCIvarDecl>(decl) || isa<ObjCPropertyDecl>(decl))) {
5702296417Sdim    if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
5703296417Sdim        diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
5704296417Sdim      reason = UnavailableAttr::IR_ForbiddenWeak;
5705296417Sdim      return true;
5706296417Sdim    }
5707296417Sdim  }
5708296417Sdim
5709296417Sdim  // Allow all sorts of things in system headers.
5710296417Sdim  if (S.Context.getSourceManager().isInSystemHeader(decl->getLocation())) {
5711296417Sdim    // Currently, all the failures dealt with this way are due to ARC
5712296417Sdim    // restrictions.
5713296417Sdim    reason = UnavailableAttr::IR_ARCForbiddenType;
5714296417Sdim    return true;
5715296417Sdim  }
5716296417Sdim
5717296417Sdim  return false;
5718224145Sdim}
5719224145Sdim
5720224145Sdim/// Handle a delayed forbidden-type diagnostic.
5721224145Sdimstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
5722224145Sdim                                       Decl *decl) {
5723296417Sdim  auto reason = UnavailableAttr::IR_None;
5724296417Sdim  if (decl && isForbiddenTypeAllowed(S, decl, diag, reason)) {
5725296417Sdim    assert(reason && "didn't set reason?");
5726296417Sdim    decl->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", reason,
5727296417Sdim                                                  diag.Loc));
5728224145Sdim    return;
5729224145Sdim  }
5730234353Sdim  if (S.getLangOpts().ObjCAutoRefCount)
5731226633Sdim    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) {
5732239462Sdim      // FIXME: we may want to suppress diagnostics for all
5733226633Sdim      // kind of forbidden type messages on unavailable functions.
5734226633Sdim      if (FD->hasAttr<UnavailableAttr>() &&
5735226633Sdim          diag.getForbiddenTypeDiagnostic() ==
5736226633Sdim          diag::err_arc_array_param_no_ownership) {
5737226633Sdim        diag.Triggered = true;
5738226633Sdim        return;
5739226633Sdim      }
5740226633Sdim    }
5741224145Sdim
5742224145Sdim  S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic())
5743224145Sdim    << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument();
5744224145Sdim  diag.Triggered = true;
5745224145Sdim}
5746224145Sdim
5747280031Sdim
5748280031Sdimstatic bool isDeclDeprecated(Decl *D) {
5749280031Sdim  do {
5750280031Sdim    if (D->isDeprecated())
5751280031Sdim      return true;
5752280031Sdim    // A category implicitly has the availability of the interface.
5753280031Sdim    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
5754288943Sdim      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
5755288943Sdim        return Interface->isDeprecated();
5756280031Sdim  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
5757280031Sdim  return false;
5758280031Sdim}
5759280031Sdim
5760280031Sdimstatic bool isDeclUnavailable(Decl *D) {
5761280031Sdim  do {
5762280031Sdim    if (D->isUnavailable())
5763280031Sdim      return true;
5764280031Sdim    // A category implicitly has the availability of the interface.
5765280031Sdim    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
5766288943Sdim      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
5767288943Sdim        return Interface->isUnavailable();
5768280031Sdim  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
5769280031Sdim  return false;
5770280031Sdim}
5771280031Sdim
5772288943Sdimstatic void DoEmitAvailabilityWarning(Sema &S, Sema::AvailabilityDiagnostic K,
5773280031Sdim                                      Decl *Ctx, const NamedDecl *D,
5774280031Sdim                                      StringRef Message, SourceLocation Loc,
5775280031Sdim                                      const ObjCInterfaceDecl *UnknownObjCClass,
5776280031Sdim                                      const ObjCPropertyDecl *ObjCProperty,
5777280031Sdim                                      bool ObjCPropertyAccess) {
5778280031Sdim  // Diagnostics for deprecated or unavailable.
5779280031Sdim  unsigned diag, diag_message, diag_fwdclass_message;
5780296417Sdim  unsigned diag_available_here = diag::note_availability_specified_here;
5781280031Sdim
5782280031Sdim  // Matches 'diag::note_property_attribute' options.
5783280031Sdim  unsigned property_note_select;
5784280031Sdim
5785280031Sdim  // Matches diag::note_availability_specified_here.
5786280031Sdim  unsigned available_here_select_kind;
5787280031Sdim
5788280031Sdim  // Don't warn if our current context is deprecated or unavailable.
5789280031Sdim  switch (K) {
5790288943Sdim  case Sema::AD_Deprecation:
5791288943Sdim    if (isDeclDeprecated(Ctx) || isDeclUnavailable(Ctx))
5792280031Sdim      return;
5793280031Sdim    diag = !ObjCPropertyAccess ? diag::warn_deprecated
5794280031Sdim                               : diag::warn_property_method_deprecated;
5795280031Sdim    diag_message = diag::warn_deprecated_message;
5796280031Sdim    diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
5797280031Sdim    property_note_select = /* deprecated */ 0;
5798280031Sdim    available_here_select_kind = /* deprecated */ 2;
5799280031Sdim    break;
5800280031Sdim
5801288943Sdim  case Sema::AD_Unavailable:
5802280031Sdim    if (isDeclUnavailable(Ctx))
5803280031Sdim      return;
5804280031Sdim    diag = !ObjCPropertyAccess ? diag::err_unavailable
5805280031Sdim                               : diag::err_property_method_unavailable;
5806280031Sdim    diag_message = diag::err_unavailable_message;
5807280031Sdim    diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
5808280031Sdim    property_note_select = /* unavailable */ 1;
5809280031Sdim    available_here_select_kind = /* unavailable */ 0;
5810296417Sdim
5811296417Sdim    if (auto attr = D->getAttr<UnavailableAttr>()) {
5812296417Sdim      if (attr->isImplicit() && attr->getImplicitReason()) {
5813296417Sdim        // Most of these failures are due to extra restrictions in ARC;
5814296417Sdim        // reflect that in the primary diagnostic when applicable.
5815296417Sdim        auto flagARCError = [&] {
5816296417Sdim          if (S.getLangOpts().ObjCAutoRefCount &&
5817296417Sdim              S.getSourceManager().isInSystemHeader(D->getLocation()))
5818296417Sdim            diag = diag::err_unavailable_in_arc;
5819296417Sdim        };
5820296417Sdim
5821296417Sdim        switch (attr->getImplicitReason()) {
5822296417Sdim        case UnavailableAttr::IR_None: break;
5823296417Sdim
5824296417Sdim        case UnavailableAttr::IR_ARCForbiddenType:
5825296417Sdim          flagARCError();
5826296417Sdim          diag_available_here = diag::note_arc_forbidden_type;
5827296417Sdim          break;
5828296417Sdim
5829296417Sdim        case UnavailableAttr::IR_ForbiddenWeak:
5830296417Sdim          if (S.getLangOpts().ObjCWeakRuntime)
5831296417Sdim            diag_available_here = diag::note_arc_weak_disabled;
5832296417Sdim          else
5833296417Sdim            diag_available_here = diag::note_arc_weak_no_runtime;
5834296417Sdim          break;
5835296417Sdim
5836296417Sdim        case UnavailableAttr::IR_ARCForbiddenConversion:
5837296417Sdim          flagARCError();
5838296417Sdim          diag_available_here = diag::note_performs_forbidden_arc_conversion;
5839296417Sdim          break;
5840296417Sdim
5841296417Sdim        case UnavailableAttr::IR_ARCInitReturnsUnrelated:
5842296417Sdim          flagARCError();
5843296417Sdim          diag_available_here = diag::note_arc_init_returns_unrelated;
5844296417Sdim          break;
5845296417Sdim
5846296417Sdim        case UnavailableAttr::IR_ARCFieldWithOwnership:
5847296417Sdim          flagARCError();
5848296417Sdim          diag_available_here = diag::note_arc_field_with_ownership;
5849296417Sdim          break;
5850296417Sdim        }
5851296417Sdim      }
5852296417Sdim    }
5853296417Sdim
5854280031Sdim    break;
5855280031Sdim
5856288943Sdim  case Sema::AD_Partial:
5857288943Sdim    diag = diag::warn_partial_availability;
5858288943Sdim    diag_message = diag::warn_partial_message;
5859288943Sdim    diag_fwdclass_message = diag::warn_partial_fwdclass_message;
5860288943Sdim    property_note_select = /* partial */ 2;
5861288943Sdim    available_here_select_kind = /* partial */ 3;
5862288943Sdim    break;
5863280031Sdim  }
5864280031Sdim
5865280031Sdim  if (!Message.empty()) {
5866280031Sdim    S.Diag(Loc, diag_message) << D << Message;
5867280031Sdim    if (ObjCProperty)
5868280031Sdim      S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
5869280031Sdim          << ObjCProperty->getDeclName() << property_note_select;
5870280031Sdim  } else if (!UnknownObjCClass) {
5871280031Sdim    S.Diag(Loc, diag) << D;
5872280031Sdim    if (ObjCProperty)
5873280031Sdim      S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
5874280031Sdim          << ObjCProperty->getDeclName() << property_note_select;
5875280031Sdim  } else {
5876280031Sdim    S.Diag(Loc, diag_fwdclass_message) << D;
5877280031Sdim    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
5878280031Sdim  }
5879280031Sdim
5880296417Sdim  S.Diag(D->getLocation(), diag_available_here)
5881280031Sdim      << D << available_here_select_kind;
5882288943Sdim  if (K == Sema::AD_Partial)
5883288943Sdim    S.Diag(Loc, diag::note_partial_availability_silence) << D;
5884280031Sdim}
5885280031Sdim
5886280031Sdimstatic void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD,
5887280031Sdim                                           Decl *Ctx) {
5888288943Sdim  assert(DD.Kind == DelayedDiagnostic::Deprecation ||
5889288943Sdim         DD.Kind == DelayedDiagnostic::Unavailable);
5890288943Sdim  Sema::AvailabilityDiagnostic AD = DD.Kind == DelayedDiagnostic::Deprecation
5891288943Sdim                                        ? Sema::AD_Deprecation
5892288943Sdim                                        : Sema::AD_Unavailable;
5893280031Sdim  DD.Triggered = true;
5894288943Sdim  DoEmitAvailabilityWarning(
5895288943Sdim      S, AD, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc,
5896288943Sdim      DD.getUnknownObjCClass(), DD.getObjCProperty(), false);
5897280031Sdim}
5898280031Sdim
5899239462Sdimvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
5900239462Sdim  assert(DelayedDiagnostics.getCurrentPool());
5901239462Sdim  DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
5902239462Sdim  DelayedDiagnostics.popWithoutEmitting(state);
5903218893Sdim
5904239462Sdim  // When delaying diagnostics to run in the context of a parsed
5905239462Sdim  // declaration, we only want to actually emit anything if parsing
5906239462Sdim  // succeeds.
5907239462Sdim  if (!decl) return;
5908218893Sdim
5909239462Sdim  // We emit all the active diagnostics in this pool or any of its
5910239462Sdim  // parents.  In general, we'll get one pool for the decl spec
5911239462Sdim  // and a child pool for each declarator; in a decl group like:
5912239462Sdim  //   deprecated_typedef foo, *bar, baz();
5913239462Sdim  // only the declarator pops will be passed decls.  This is correct;
5914239462Sdim  // we really do need to consider delayed diagnostics from the decl spec
5915239462Sdim  // for each of the different declarations.
5916239462Sdim  const DelayedDiagnosticPool *pool = &poppedPool;
5917239462Sdim  do {
5918239462Sdim    for (DelayedDiagnosticPool::pool_iterator
5919239462Sdim           i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
5920239462Sdim      // This const_cast is a bit lame.  Really, Triggered should be mutable.
5921239462Sdim      DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
5922218893Sdim      if (diag.Triggered)
5923203955Srdivacky        continue;
5924198893Srdivacky
5925218893Sdim      switch (diag.Kind) {
5926203955Srdivacky      case DelayedDiagnostic::Deprecation:
5927276479Sdim      case DelayedDiagnostic::Unavailable:
5928276479Sdim        // Don't bother giving deprecation/unavailable diagnostics if
5929276479Sdim        // the decl is invalid.
5930234353Sdim        if (!decl->isInvalidDecl())
5931280031Sdim          handleDelayedAvailabilityCheck(*this, diag, decl);
5932203955Srdivacky        break;
5933203955Srdivacky
5934203955Srdivacky      case DelayedDiagnostic::Access:
5935239462Sdim        HandleDelayedAccessCheck(diag, decl);
5936203955Srdivacky        break;
5937224145Sdim
5938224145Sdim      case DelayedDiagnostic::ForbiddenType:
5939239462Sdim        handleDelayedForbiddenType(*this, diag, decl);
5940224145Sdim        break;
5941198893Srdivacky      }
5942198893Srdivacky    }
5943239462Sdim  } while ((pool = pool->getParent()));
5944239462Sdim}
5945198893Srdivacky
5946239462Sdim/// Given a set of delayed diagnostics, re-emit them as if they had
5947239462Sdim/// been delayed in the current context instead of in the given pool.
5948239462Sdim/// Essentially, this just moves them to the current pool.
5949239462Sdimvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
5950239462Sdim  DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
5951239462Sdim  assert(curPool && "re-emitting in undelayed context not supported");
5952239462Sdim  curPool->steal(pool);
5953198893Srdivacky}
5954198893Srdivacky
5955276479Sdimvoid Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
5956276479Sdim                                   NamedDecl *D, StringRef Message,
5957276479Sdim                                   SourceLocation Loc,
5958276479Sdim                                   const ObjCInterfaceDecl *UnknownObjCClass,
5959276479Sdim                                   const ObjCPropertyDecl  *ObjCProperty,
5960276479Sdim                                   bool ObjCPropertyAccess) {
5961198893Srdivacky  // Delay if we're currently parsing a declaration.
5962288943Sdim  if (DelayedDiagnostics.shouldDelayDiagnostics() && AD != AD_Partial) {
5963280031Sdim    DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(
5964280031Sdim        AD, Loc, D, UnknownObjCClass, ObjCProperty, Message,
5965280031Sdim        ObjCPropertyAccess));
5966198893Srdivacky    return;
5967198893Srdivacky  }
5968198893Srdivacky
5969276479Sdim  Decl *Ctx = cast<Decl>(getCurLexicalContext());
5970288943Sdim  DoEmitAvailabilityWarning(*this, AD, Ctx, D, Message, Loc, UnknownObjCClass,
5971288943Sdim                            ObjCProperty, ObjCPropertyAccess);
5972198893Srdivacky}
5973