clang API Documentation
00001 //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements decl-related attribute processing. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Sema/SemaInternal.h" 00015 #include "clang/AST/ASTContext.h" 00016 #include "clang/AST/CXXInheritance.h" 00017 #include "clang/AST/DeclCXX.h" 00018 #include "clang/AST/DeclObjC.h" 00019 #include "clang/AST/DeclTemplate.h" 00020 #include "clang/AST/Expr.h" 00021 #include "clang/AST/ExprCXX.h" 00022 #include "clang/AST/Mangle.h" 00023 #include "clang/Basic/CharInfo.h" 00024 #include "clang/Basic/SourceManager.h" 00025 #include "clang/Basic/TargetInfo.h" 00026 #include "clang/Lex/Preprocessor.h" 00027 #include "clang/Sema/DeclSpec.h" 00028 #include "clang/Sema/DelayedDiagnostic.h" 00029 #include "clang/Sema/Lookup.h" 00030 #include "clang/Sema/Scope.h" 00031 #include "llvm/ADT/StringExtras.h" 00032 #include "llvm/Support/MathExtras.h" 00033 using namespace clang; 00034 using namespace sema; 00035 00036 namespace AttributeLangSupport { 00037 enum LANG { 00038 C, 00039 Cpp, 00040 ObjC 00041 }; 00042 } 00043 00044 //===----------------------------------------------------------------------===// 00045 // Helper functions 00046 //===----------------------------------------------------------------------===// 00047 00048 /// isFunctionOrMethod - Return true if the given decl has function 00049 /// type (function or function-typed variable) or an Objective-C 00050 /// method. 00051 static bool isFunctionOrMethod(const Decl *D) { 00052 return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D); 00053 } 00054 00055 /// Return true if the given decl has a declarator that should have 00056 /// been processed by Sema::GetTypeForDeclarator. 00057 static bool hasDeclarator(const Decl *D) { 00058 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 00059 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 00060 isa<ObjCPropertyDecl>(D); 00061 } 00062 00063 /// hasFunctionProto - Return true if the given decl has a argument 00064 /// information. This decl should have already passed 00065 /// isFunctionOrMethod or isFunctionOrMethodOrBlock. 00066 static bool hasFunctionProto(const Decl *D) { 00067 if (const FunctionType *FnTy = D->getFunctionType()) 00068 return isa<FunctionProtoType>(FnTy); 00069 return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D); 00070 } 00071 00072 /// getFunctionOrMethodNumParams - Return number of function or method 00073 /// parameters. It is an error to call this on a K&R function (use 00074 /// hasFunctionProto first). 00075 static unsigned getFunctionOrMethodNumParams(const Decl *D) { 00076 if (const FunctionType *FnTy = D->getFunctionType()) 00077 return cast<FunctionProtoType>(FnTy)->getNumParams(); 00078 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00079 return BD->getNumParams(); 00080 return cast<ObjCMethodDecl>(D)->param_size(); 00081 } 00082 00083 static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) { 00084 if (const FunctionType *FnTy = D->getFunctionType()) 00085 return cast<FunctionProtoType>(FnTy)->getParamType(Idx); 00086 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00087 return BD->getParamDecl(Idx)->getType(); 00088 00089 return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType(); 00090 } 00091 00092 static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) { 00093 if (const auto *FD = dyn_cast<FunctionDecl>(D)) 00094 return FD->getParamDecl(Idx)->getSourceRange(); 00095 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) 00096 return MD->parameters()[Idx]->getSourceRange(); 00097 if (const auto *BD = dyn_cast<BlockDecl>(D)) 00098 return BD->getParamDecl(Idx)->getSourceRange(); 00099 return SourceRange(); 00100 } 00101 00102 static QualType getFunctionOrMethodResultType(const Decl *D) { 00103 if (const FunctionType *FnTy = D->getFunctionType()) 00104 return cast<FunctionType>(FnTy)->getReturnType(); 00105 return cast<ObjCMethodDecl>(D)->getReturnType(); 00106 } 00107 00108 static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) { 00109 if (const auto *FD = dyn_cast<FunctionDecl>(D)) 00110 return FD->getReturnTypeSourceRange(); 00111 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) 00112 return MD->getReturnTypeSourceRange(); 00113 return SourceRange(); 00114 } 00115 00116 static bool isFunctionOrMethodVariadic(const Decl *D) { 00117 if (const FunctionType *FnTy = D->getFunctionType()) { 00118 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 00119 return proto->isVariadic(); 00120 } 00121 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00122 return BD->isVariadic(); 00123 00124 return cast<ObjCMethodDecl>(D)->isVariadic(); 00125 } 00126 00127 static bool isInstanceMethod(const Decl *D) { 00128 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 00129 return MethodDecl->isInstance(); 00130 return false; 00131 } 00132 00133 static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 00134 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 00135 if (!PT) 00136 return false; 00137 00138 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 00139 if (!Cls) 00140 return false; 00141 00142 IdentifierInfo* ClsName = Cls->getIdentifier(); 00143 00144 // FIXME: Should we walk the chain of classes? 00145 return ClsName == &Ctx.Idents.get("NSString") || 00146 ClsName == &Ctx.Idents.get("NSMutableString"); 00147 } 00148 00149 static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 00150 const PointerType *PT = T->getAs<PointerType>(); 00151 if (!PT) 00152 return false; 00153 00154 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 00155 if (!RT) 00156 return false; 00157 00158 const RecordDecl *RD = RT->getDecl(); 00159 if (RD->getTagKind() != TTK_Struct) 00160 return false; 00161 00162 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 00163 } 00164 00165 static unsigned getNumAttributeArgs(const AttributeList &Attr) { 00166 // FIXME: Include the type in the argument list. 00167 return Attr.getNumArgs() + Attr.hasParsedType(); 00168 } 00169 00170 template <typename Compare> 00171 static bool checkAttributeNumArgsImpl(Sema &S, const AttributeList &Attr, 00172 unsigned Num, unsigned Diag, 00173 Compare Comp) { 00174 if (Comp(getNumAttributeArgs(Attr), Num)) { 00175 S.Diag(Attr.getLoc(), Diag) << Attr.getName() << Num; 00176 return false; 00177 } 00178 00179 return true; 00180 } 00181 00182 /// \brief Check if the attribute has exactly as many args as Num. May 00183 /// output an error. 00184 static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 00185 unsigned Num) { 00186 return checkAttributeNumArgsImpl(S, Attr, Num, 00187 diag::err_attribute_wrong_number_arguments, 00188 std::not_equal_to<unsigned>()); 00189 } 00190 00191 /// \brief Check if the attribute has at least as many args as Num. May 00192 /// output an error. 00193 static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 00194 unsigned Num) { 00195 return checkAttributeNumArgsImpl(S, Attr, Num, 00196 diag::err_attribute_too_few_arguments, 00197 std::less<unsigned>()); 00198 } 00199 00200 /// \brief Check if the attribute has at most as many args as Num. May 00201 /// output an error. 00202 static bool checkAttributeAtMostNumArgs(Sema &S, const AttributeList &Attr, 00203 unsigned Num) { 00204 return checkAttributeNumArgsImpl(S, Attr, Num, 00205 diag::err_attribute_too_many_arguments, 00206 std::greater<unsigned>()); 00207 } 00208 00209 /// \brief If Expr is a valid integer constant, get the value of the integer 00210 /// expression and return success or failure. May output an error. 00211 static bool checkUInt32Argument(Sema &S, const AttributeList &Attr, 00212 const Expr *Expr, uint32_t &Val, 00213 unsigned Idx = UINT_MAX) { 00214 llvm::APSInt I(32); 00215 if (Expr->isTypeDependent() || Expr->isValueDependent() || 00216 !Expr->isIntegerConstantExpr(I, S.Context)) { 00217 if (Idx != UINT_MAX) 00218 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 00219 << Attr.getName() << Idx << AANT_ArgumentIntegerConstant 00220 << Expr->getSourceRange(); 00221 else 00222 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 00223 << Attr.getName() << AANT_ArgumentIntegerConstant 00224 << Expr->getSourceRange(); 00225 return false; 00226 } 00227 00228 if (!I.isIntN(32)) { 00229 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large) 00230 << I.toString(10, false) << 32 << /* Unsigned */ 1; 00231 return false; 00232 } 00233 00234 Val = (uint32_t)I.getZExtValue(); 00235 return true; 00236 } 00237 00238 /// \brief Diagnose mutually exclusive attributes when present on a given 00239 /// declaration. Returns true if diagnosed. 00240 template <typename AttrTy> 00241 static bool checkAttrMutualExclusion(Sema &S, Decl *D, 00242 const AttributeList &Attr) { 00243 if (AttrTy *A = D->getAttr<AttrTy>()) { 00244 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 00245 << Attr.getName() << A; 00246 return true; 00247 } 00248 return false; 00249 } 00250 00251 /// \brief Check if IdxExpr is a valid parameter index for a function or 00252 /// instance method D. May output an error. 00253 /// 00254 /// \returns true if IdxExpr is a valid index. 00255 static bool checkFunctionOrMethodParameterIndex(Sema &S, const Decl *D, 00256 const AttributeList &Attr, 00257 unsigned AttrArgNum, 00258 const Expr *IdxExpr, 00259 uint64_t &Idx) { 00260 assert(isFunctionOrMethod(D)); 00261 00262 // In C++ the implicit 'this' function parameter also counts. 00263 // Parameters are counted from one. 00264 bool HP = hasFunctionProto(D); 00265 bool HasImplicitThisParam = isInstanceMethod(D); 00266 bool IV = HP && isFunctionOrMethodVariadic(D); 00267 unsigned NumParams = 00268 (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam; 00269 00270 llvm::APSInt IdxInt; 00271 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 00272 !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { 00273 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 00274 << Attr.getName() << AttrArgNum << AANT_ArgumentIntegerConstant 00275 << IdxExpr->getSourceRange(); 00276 return false; 00277 } 00278 00279 Idx = IdxInt.getLimitedValue(); 00280 if (Idx < 1 || (!IV && Idx > NumParams)) { 00281 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 00282 << Attr.getName() << AttrArgNum << IdxExpr->getSourceRange(); 00283 return false; 00284 } 00285 Idx--; // Convert to zero-based. 00286 if (HasImplicitThisParam) { 00287 if (Idx == 0) { 00288 S.Diag(Attr.getLoc(), 00289 diag::err_attribute_invalid_implicit_this_argument) 00290 << Attr.getName() << IdxExpr->getSourceRange(); 00291 return false; 00292 } 00293 --Idx; 00294 } 00295 00296 return true; 00297 } 00298 00299 /// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal. 00300 /// If not emit an error and return false. If the argument is an identifier it 00301 /// will emit an error with a fixit hint and treat it as if it was a string 00302 /// literal. 00303 bool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr, 00304 unsigned ArgNum, StringRef &Str, 00305 SourceLocation *ArgLocation) { 00306 // Look for identifiers. If we have one emit a hint to fix it to a literal. 00307 if (Attr.isArgIdent(ArgNum)) { 00308 IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum); 00309 Diag(Loc->Loc, diag::err_attribute_argument_type) 00310 << Attr.getName() << AANT_ArgumentString 00311 << FixItHint::CreateInsertion(Loc->Loc, "\"") 00312 << FixItHint::CreateInsertion(PP.getLocForEndOfToken(Loc->Loc), "\""); 00313 Str = Loc->Ident->getName(); 00314 if (ArgLocation) 00315 *ArgLocation = Loc->Loc; 00316 return true; 00317 } 00318 00319 // Now check for an actual string literal. 00320 Expr *ArgExpr = Attr.getArgAsExpr(ArgNum); 00321 StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts()); 00322 if (ArgLocation) 00323 *ArgLocation = ArgExpr->getLocStart(); 00324 00325 if (!Literal || !Literal->isAscii()) { 00326 Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) 00327 << Attr.getName() << AANT_ArgumentString; 00328 return false; 00329 } 00330 00331 Str = Literal->getString(); 00332 return true; 00333 } 00334 00335 /// \brief Applies the given attribute to the Decl without performing any 00336 /// additional semantic checking. 00337 template <typename AttrType> 00338 static void handleSimpleAttribute(Sema &S, Decl *D, 00339 const AttributeList &Attr) { 00340 D->addAttr(::new (S.Context) AttrType(Attr.getRange(), S.Context, 00341 Attr.getAttributeSpellingListIndex())); 00342 } 00343 00344 /// \brief Check if the passed-in expression is of type int or bool. 00345 static bool isIntOrBool(Expr *Exp) { 00346 QualType QT = Exp->getType(); 00347 return QT->isBooleanType() || QT->isIntegerType(); 00348 } 00349 00350 00351 // Check to see if the type is a smart pointer of some kind. We assume 00352 // it's a smart pointer if it defines both operator-> and operator*. 00353 static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { 00354 DeclContextLookupConstResult Res1 = RT->getDecl()->lookup( 00355 S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); 00356 if (Res1.empty()) 00357 return false; 00358 00359 DeclContextLookupConstResult Res2 = RT->getDecl()->lookup( 00360 S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); 00361 if (Res2.empty()) 00362 return false; 00363 00364 return true; 00365 } 00366 00367 /// \brief Check if passed in Decl is a pointer type. 00368 /// Note that this function may produce an error message. 00369 /// \return true if the Decl is a pointer type; false otherwise 00370 static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 00371 const AttributeList &Attr) { 00372 const ValueDecl *vd = cast<ValueDecl>(D); 00373 QualType QT = vd->getType(); 00374 if (QT->isAnyPointerType()) 00375 return true; 00376 00377 if (const RecordType *RT = QT->getAs<RecordType>()) { 00378 // If it's an incomplete type, it could be a smart pointer; skip it. 00379 // (We don't want to force template instantiation if we can avoid it, 00380 // since that would alter the order in which templates are instantiated.) 00381 if (RT->isIncompleteType()) 00382 return true; 00383 00384 if (threadSafetyCheckIsSmartPointer(S, RT)) 00385 return true; 00386 } 00387 00388 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 00389 << Attr.getName() << QT; 00390 return false; 00391 } 00392 00393 /// \brief Checks that the passed in QualType either is of RecordType or points 00394 /// to RecordType. Returns the relevant RecordType, null if it does not exit. 00395 static const RecordType *getRecordType(QualType QT) { 00396 if (const RecordType *RT = QT->getAs<RecordType>()) 00397 return RT; 00398 00399 // Now check if we point to record type. 00400 if (const PointerType *PT = QT->getAs<PointerType>()) 00401 return PT->getPointeeType()->getAs<RecordType>(); 00402 00403 return nullptr; 00404 } 00405 00406 static bool checkRecordTypeForCapability(Sema &S, QualType Ty) { 00407 const RecordType *RT = getRecordType(Ty); 00408 00409 if (!RT) 00410 return false; 00411 00412 // Don't check for the capability if the class hasn't been defined yet. 00413 if (RT->isIncompleteType()) 00414 return true; 00415 00416 // Allow smart pointers to be used as capability objects. 00417 // FIXME -- Check the type that the smart pointer points to. 00418 if (threadSafetyCheckIsSmartPointer(S, RT)) 00419 return true; 00420 00421 // Check if the record itself has a capability. 00422 RecordDecl *RD = RT->getDecl(); 00423 if (RD->hasAttr<CapabilityAttr>()) 00424 return true; 00425 00426 // Else check if any base classes have a capability. 00427 if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { 00428 CXXBasePaths BPaths(false, false); 00429 if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath &P, 00430 void *) { 00431 return BS->getType()->getAs<RecordType>() 00432 ->getDecl()->hasAttr<CapabilityAttr>(); 00433 }, nullptr, BPaths)) 00434 return true; 00435 } 00436 return false; 00437 } 00438 00439 static bool checkTypedefTypeForCapability(QualType Ty) { 00440 const auto *TD = Ty->getAs<TypedefType>(); 00441 if (!TD) 00442 return false; 00443 00444 TypedefNameDecl *TN = TD->getDecl(); 00445 if (!TN) 00446 return false; 00447 00448 return TN->hasAttr<CapabilityAttr>(); 00449 } 00450 00451 static bool typeHasCapability(Sema &S, QualType Ty) { 00452 if (checkTypedefTypeForCapability(Ty)) 00453 return true; 00454 00455 if (checkRecordTypeForCapability(S, Ty)) 00456 return true; 00457 00458 return false; 00459 } 00460 00461 static bool isCapabilityExpr(Sema &S, const Expr *Ex) { 00462 // Capability expressions are simple expressions involving the boolean logic 00463 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once 00464 // a DeclRefExpr is found, its type should be checked to determine whether it 00465 // is a capability or not. 00466 00467 if (const auto *E = dyn_cast<DeclRefExpr>(Ex)) 00468 return typeHasCapability(S, E->getType()); 00469 else if (const auto *E = dyn_cast<CastExpr>(Ex)) 00470 return isCapabilityExpr(S, E->getSubExpr()); 00471 else if (const auto *E = dyn_cast<ParenExpr>(Ex)) 00472 return isCapabilityExpr(S, E->getSubExpr()); 00473 else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) { 00474 if (E->getOpcode() == UO_LNot) 00475 return isCapabilityExpr(S, E->getSubExpr()); 00476 return false; 00477 } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) { 00478 if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr) 00479 return isCapabilityExpr(S, E->getLHS()) && 00480 isCapabilityExpr(S, E->getRHS()); 00481 return false; 00482 } 00483 00484 return false; 00485 } 00486 00487 /// \brief Checks that all attribute arguments, starting from Sidx, resolve to 00488 /// a capability object. 00489 /// \param Sidx The attribute argument index to start checking with. 00490 /// \param ParamIdxOk Whether an argument can be indexing into a function 00491 /// parameter list. 00492 static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D, 00493 const AttributeList &Attr, 00494 SmallVectorImpl<Expr *> &Args, 00495 int Sidx = 0, 00496 bool ParamIdxOk = false) { 00497 for (unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 00498 Expr *ArgExp = Attr.getArgAsExpr(Idx); 00499 00500 if (ArgExp->isTypeDependent()) { 00501 // FIXME -- need to check this again on template instantiation 00502 Args.push_back(ArgExp); 00503 continue; 00504 } 00505 00506 if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 00507 if (StrLit->getLength() == 0 || 00508 (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) { 00509 // Pass empty strings to the analyzer without warnings. 00510 // Treat "*" as the universal lock. 00511 Args.push_back(ArgExp); 00512 continue; 00513 } 00514 00515 // We allow constant strings to be used as a placeholder for expressions 00516 // that are not valid C++ syntax, but warn that they are ignored. 00517 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 00518 Attr.getName(); 00519 Args.push_back(ArgExp); 00520 continue; 00521 } 00522 00523 QualType ArgTy = ArgExp->getType(); 00524 00525 // A pointer to member expression of the form &MyClass::mu is treated 00526 // specially -- we need to look at the type of the member. 00527 if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 00528 if (UOp->getOpcode() == UO_AddrOf) 00529 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 00530 if (DRE->getDecl()->isCXXInstanceMember()) 00531 ArgTy = DRE->getDecl()->getType(); 00532 00533 // First see if we can just cast to record type, or pointer to record type. 00534 const RecordType *RT = getRecordType(ArgTy); 00535 00536 // Now check if we index into a record type function param. 00537 if(!RT && ParamIdxOk) { 00538 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 00539 IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 00540 if(FD && IL) { 00541 unsigned int NumParams = FD->getNumParams(); 00542 llvm::APInt ArgValue = IL->getValue(); 00543 uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 00544 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 00545 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 00546 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 00547 << Attr.getName() << Idx + 1 << NumParams; 00548 continue; 00549 } 00550 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 00551 } 00552 } 00553 00554 // If the type does not have a capability, see if the components of the 00555 // expression have capabilities. This allows for writing C code where the 00556 // capability may be on the type, and the expression is a capability 00557 // boolean logic expression. Eg) requires_capability(A || B && !C) 00558 if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp)) 00559 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 00560 << Attr.getName() << ArgTy; 00561 00562 Args.push_back(ArgExp); 00563 } 00564 } 00565 00566 //===----------------------------------------------------------------------===// 00567 // Attribute Implementations 00568 //===----------------------------------------------------------------------===// 00569 00570 static void handlePtGuardedVarAttr(Sema &S, Decl *D, 00571 const AttributeList &Attr) { 00572 if (!threadSafetyCheckIsPointer(S, D, Attr)) 00573 return; 00574 00575 D->addAttr(::new (S.Context) 00576 PtGuardedVarAttr(Attr.getRange(), S.Context, 00577 Attr.getAttributeSpellingListIndex())); 00578 } 00579 00580 static bool checkGuardedByAttrCommon(Sema &S, Decl *D, 00581 const AttributeList &Attr, 00582 Expr* &Arg) { 00583 SmallVector<Expr*, 1> Args; 00584 // check that all arguments are lockable objects 00585 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 00586 unsigned Size = Args.size(); 00587 if (Size != 1) 00588 return false; 00589 00590 Arg = Args[0]; 00591 00592 return true; 00593 } 00594 00595 static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00596 Expr *Arg = nullptr; 00597 if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 00598 return; 00599 00600 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg, 00601 Attr.getAttributeSpellingListIndex())); 00602 } 00603 00604 static void handlePtGuardedByAttr(Sema &S, Decl *D, 00605 const AttributeList &Attr) { 00606 Expr *Arg = nullptr; 00607 if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 00608 return; 00609 00610 if (!threadSafetyCheckIsPointer(S, D, Attr)) 00611 return; 00612 00613 D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 00614 S.Context, Arg, 00615 Attr.getAttributeSpellingListIndex())); 00616 } 00617 00618 static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, 00619 const AttributeList &Attr, 00620 SmallVectorImpl<Expr *> &Args) { 00621 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00622 return false; 00623 00624 // Check that this attribute only applies to lockable types. 00625 QualType QT = cast<ValueDecl>(D)->getType(); 00626 if (!QT->isDependentType()) { 00627 const RecordType *RT = getRecordType(QT); 00628 if (!RT || !RT->getDecl()->hasAttr<CapabilityAttr>()) { 00629 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 00630 << Attr.getName(); 00631 return false; 00632 } 00633 } 00634 00635 // Check that all arguments are lockable objects. 00636 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 00637 if (Args.empty()) 00638 return false; 00639 00640 return true; 00641 } 00642 00643 static void handleAcquiredAfterAttr(Sema &S, Decl *D, 00644 const AttributeList &Attr) { 00645 SmallVector<Expr*, 1> Args; 00646 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 00647 return; 00648 00649 Expr **StartArg = &Args[0]; 00650 D->addAttr(::new (S.Context) 00651 AcquiredAfterAttr(Attr.getRange(), S.Context, 00652 StartArg, Args.size(), 00653 Attr.getAttributeSpellingListIndex())); 00654 } 00655 00656 static void handleAcquiredBeforeAttr(Sema &S, Decl *D, 00657 const AttributeList &Attr) { 00658 SmallVector<Expr*, 1> Args; 00659 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 00660 return; 00661 00662 Expr **StartArg = &Args[0]; 00663 D->addAttr(::new (S.Context) 00664 AcquiredBeforeAttr(Attr.getRange(), S.Context, 00665 StartArg, Args.size(), 00666 Attr.getAttributeSpellingListIndex())); 00667 } 00668 00669 static bool checkLockFunAttrCommon(Sema &S, Decl *D, 00670 const AttributeList &Attr, 00671 SmallVectorImpl<Expr *> &Args) { 00672 // zero or more arguments ok 00673 // check that all arguments are lockable objects 00674 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 00675 00676 return true; 00677 } 00678 00679 static void handleAssertSharedLockAttr(Sema &S, Decl *D, 00680 const AttributeList &Attr) { 00681 SmallVector<Expr*, 1> Args; 00682 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 00683 return; 00684 00685 unsigned Size = Args.size(); 00686 Expr **StartArg = Size == 0 ? nullptr : &Args[0]; 00687 D->addAttr(::new (S.Context) 00688 AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size, 00689 Attr.getAttributeSpellingListIndex())); 00690 } 00691 00692 static void handleAssertExclusiveLockAttr(Sema &S, Decl *D, 00693 const AttributeList &Attr) { 00694 SmallVector<Expr*, 1> Args; 00695 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 00696 return; 00697 00698 unsigned Size = Args.size(); 00699 Expr **StartArg = Size == 0 ? nullptr : &Args[0]; 00700 D->addAttr(::new (S.Context) 00701 AssertExclusiveLockAttr(Attr.getRange(), S.Context, 00702 StartArg, Size, 00703 Attr.getAttributeSpellingListIndex())); 00704 } 00705 00706 00707 static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, 00708 const AttributeList &Attr, 00709 SmallVectorImpl<Expr *> &Args) { 00710 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00711 return false; 00712 00713 if (!isIntOrBool(Attr.getArgAsExpr(0))) { 00714 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 00715 << Attr.getName() << 1 << AANT_ArgumentIntOrBool; 00716 return false; 00717 } 00718 00719 // check that all arguments are lockable objects 00720 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 1); 00721 00722 return true; 00723 } 00724 00725 static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, 00726 const AttributeList &Attr) { 00727 SmallVector<Expr*, 2> Args; 00728 if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 00729 return; 00730 00731 D->addAttr(::new (S.Context) 00732 SharedTrylockFunctionAttr(Attr.getRange(), S.Context, 00733 Attr.getArgAsExpr(0), 00734 Args.data(), Args.size(), 00735 Attr.getAttributeSpellingListIndex())); 00736 } 00737 00738 static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, 00739 const AttributeList &Attr) { 00740 SmallVector<Expr*, 2> Args; 00741 if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 00742 return; 00743 00744 D->addAttr(::new (S.Context) 00745 ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context, 00746 Attr.getArgAsExpr(0), 00747 Args.data(), Args.size(), 00748 Attr.getAttributeSpellingListIndex())); 00749 } 00750 00751 static void handleLockReturnedAttr(Sema &S, Decl *D, 00752 const AttributeList &Attr) { 00753 // check that the argument is lockable object 00754 SmallVector<Expr*, 1> Args; 00755 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 00756 unsigned Size = Args.size(); 00757 if (Size == 0) 00758 return; 00759 00760 D->addAttr(::new (S.Context) 00761 LockReturnedAttr(Attr.getRange(), S.Context, Args[0], 00762 Attr.getAttributeSpellingListIndex())); 00763 } 00764 00765 static void handleLocksExcludedAttr(Sema &S, Decl *D, 00766 const AttributeList &Attr) { 00767 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00768 return; 00769 00770 // check that all arguments are lockable objects 00771 SmallVector<Expr*, 1> Args; 00772 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 00773 unsigned Size = Args.size(); 00774 if (Size == 0) 00775 return; 00776 Expr **StartArg = &Args[0]; 00777 00778 D->addAttr(::new (S.Context) 00779 LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size, 00780 Attr.getAttributeSpellingListIndex())); 00781 } 00782 00783 static void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00784 Expr *Cond = Attr.getArgAsExpr(0); 00785 if (!Cond->isTypeDependent()) { 00786 ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); 00787 if (Converted.isInvalid()) 00788 return; 00789 Cond = Converted.get(); 00790 } 00791 00792 StringRef Msg; 00793 if (!S.checkStringLiteralArgumentAttr(Attr, 1, Msg)) 00794 return; 00795 00796 SmallVector<PartialDiagnosticAt, 8> Diags; 00797 if (!Cond->isValueDependent() && 00798 !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D), 00799 Diags)) { 00800 S.Diag(Attr.getLoc(), diag::err_enable_if_never_constant_expr); 00801 for (int I = 0, N = Diags.size(); I != N; ++I) 00802 S.Diag(Diags[I].first, Diags[I].second); 00803 return; 00804 } 00805 00806 D->addAttr(::new (S.Context) 00807 EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg, 00808 Attr.getAttributeSpellingListIndex())); 00809 } 00810 00811 static void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00812 ConsumableAttr::ConsumedState DefaultState; 00813 00814 if (Attr.isArgIdent(0)) { 00815 IdentifierLoc *IL = Attr.getArgAsIdent(0); 00816 if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(), 00817 DefaultState)) { 00818 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) 00819 << Attr.getName() << IL->Ident; 00820 return; 00821 } 00822 } else { 00823 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 00824 << Attr.getName() << AANT_ArgumentIdentifier; 00825 return; 00826 } 00827 00828 D->addAttr(::new (S.Context) 00829 ConsumableAttr(Attr.getRange(), S.Context, DefaultState, 00830 Attr.getAttributeSpellingListIndex())); 00831 } 00832 00833 00834 static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, 00835 const AttributeList &Attr) { 00836 ASTContext &CurrContext = S.getASTContext(); 00837 QualType ThisType = MD->getThisType(CurrContext)->getPointeeType(); 00838 00839 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) { 00840 if (!RD->hasAttr<ConsumableAttr>()) { 00841 S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) << 00842 RD->getNameAsString(); 00843 00844 return false; 00845 } 00846 } 00847 00848 return true; 00849 } 00850 00851 00852 static void handleCallableWhenAttr(Sema &S, Decl *D, 00853 const AttributeList &Attr) { 00854 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00855 return; 00856 00857 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 00858 return; 00859 00860 SmallVector<CallableWhenAttr::ConsumedState, 3> States; 00861 for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) { 00862 CallableWhenAttr::ConsumedState CallableState; 00863 00864 StringRef StateString; 00865 SourceLocation Loc; 00866 if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc)) 00867 return; 00868 00869 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString, 00870 CallableState)) { 00871 S.Diag(Loc, diag::warn_attribute_type_not_supported) 00872 << Attr.getName() << StateString; 00873 return; 00874 } 00875 00876 States.push_back(CallableState); 00877 } 00878 00879 D->addAttr(::new (S.Context) 00880 CallableWhenAttr(Attr.getRange(), S.Context, States.data(), 00881 States.size(), Attr.getAttributeSpellingListIndex())); 00882 } 00883 00884 00885 static void handleParamTypestateAttr(Sema &S, Decl *D, 00886 const AttributeList &Attr) { 00887 ParamTypestateAttr::ConsumedState ParamState; 00888 00889 if (Attr.isArgIdent(0)) { 00890 IdentifierLoc *Ident = Attr.getArgAsIdent(0); 00891 StringRef StateString = Ident->Ident->getName(); 00892 00893 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString, 00894 ParamState)) { 00895 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 00896 << Attr.getName() << StateString; 00897 return; 00898 } 00899 } else { 00900 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 00901 Attr.getName() << AANT_ArgumentIdentifier; 00902 return; 00903 } 00904 00905 // FIXME: This check is currently being done in the analysis. It can be 00906 // enabled here only after the parser propagates attributes at 00907 // template specialization definition, not declaration. 00908 //QualType ReturnType = cast<ParmVarDecl>(D)->getType(); 00909 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); 00910 // 00911 //if (!RD || !RD->hasAttr<ConsumableAttr>()) { 00912 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << 00913 // ReturnType.getAsString(); 00914 // return; 00915 //} 00916 00917 D->addAttr(::new (S.Context) 00918 ParamTypestateAttr(Attr.getRange(), S.Context, ParamState, 00919 Attr.getAttributeSpellingListIndex())); 00920 } 00921 00922 00923 static void handleReturnTypestateAttr(Sema &S, Decl *D, 00924 const AttributeList &Attr) { 00925 ReturnTypestateAttr::ConsumedState ReturnState; 00926 00927 if (Attr.isArgIdent(0)) { 00928 IdentifierLoc *IL = Attr.getArgAsIdent(0); 00929 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(), 00930 ReturnState)) { 00931 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) 00932 << Attr.getName() << IL->Ident; 00933 return; 00934 } 00935 } else { 00936 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 00937 Attr.getName() << AANT_ArgumentIdentifier; 00938 return; 00939 } 00940 00941 // FIXME: This check is currently being done in the analysis. It can be 00942 // enabled here only after the parser propagates attributes at 00943 // template specialization definition, not declaration. 00944 //QualType ReturnType; 00945 // 00946 //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) { 00947 // ReturnType = Param->getType(); 00948 // 00949 //} else if (const CXXConstructorDecl *Constructor = 00950 // dyn_cast<CXXConstructorDecl>(D)) { 00951 // ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType(); 00952 // 00953 //} else { 00954 // 00955 // ReturnType = cast<FunctionDecl>(D)->getCallResultType(); 00956 //} 00957 // 00958 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); 00959 // 00960 //if (!RD || !RD->hasAttr<ConsumableAttr>()) { 00961 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << 00962 // ReturnType.getAsString(); 00963 // return; 00964 //} 00965 00966 D->addAttr(::new (S.Context) 00967 ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState, 00968 Attr.getAttributeSpellingListIndex())); 00969 } 00970 00971 00972 static void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00973 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 00974 return; 00975 00976 SetTypestateAttr::ConsumedState NewState; 00977 if (Attr.isArgIdent(0)) { 00978 IdentifierLoc *Ident = Attr.getArgAsIdent(0); 00979 StringRef Param = Ident->Ident->getName(); 00980 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) { 00981 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 00982 << Attr.getName() << Param; 00983 return; 00984 } 00985 } else { 00986 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 00987 Attr.getName() << AANT_ArgumentIdentifier; 00988 return; 00989 } 00990 00991 D->addAttr(::new (S.Context) 00992 SetTypestateAttr(Attr.getRange(), S.Context, NewState, 00993 Attr.getAttributeSpellingListIndex())); 00994 } 00995 00996 static void handleTestTypestateAttr(Sema &S, Decl *D, 00997 const AttributeList &Attr) { 00998 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 00999 return; 01000 01001 TestTypestateAttr::ConsumedState TestState; 01002 if (Attr.isArgIdent(0)) { 01003 IdentifierLoc *Ident = Attr.getArgAsIdent(0); 01004 StringRef Param = Ident->Ident->getName(); 01005 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) { 01006 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 01007 << Attr.getName() << Param; 01008 return; 01009 } 01010 } else { 01011 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 01012 Attr.getName() << AANT_ArgumentIdentifier; 01013 return; 01014 } 01015 01016 D->addAttr(::new (S.Context) 01017 TestTypestateAttr(Attr.getRange(), S.Context, TestState, 01018 Attr.getAttributeSpellingListIndex())); 01019 } 01020 01021 static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 01022 const AttributeList &Attr) { 01023 // Remember this typedef decl, we will need it later for diagnostics. 01024 S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D)); 01025 } 01026 01027 static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01028 if (TagDecl *TD = dyn_cast<TagDecl>(D)) 01029 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context, 01030 Attr.getAttributeSpellingListIndex())); 01031 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 01032 // If the alignment is less than or equal to 8 bits, the packed attribute 01033 // has no effect. 01034 if (!FD->getType()->isDependentType() && 01035 !FD->getType()->isIncompleteType() && 01036 S.Context.getTypeAlign(FD->getType()) <= 8) 01037 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 01038 << Attr.getName() << FD->getType(); 01039 else 01040 FD->addAttr(::new (S.Context) 01041 PackedAttr(Attr.getRange(), S.Context, 01042 Attr.getAttributeSpellingListIndex())); 01043 } else 01044 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 01045 } 01046 01047 static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 01048 // The IBOutlet/IBOutletCollection attributes only apply to instance 01049 // variables or properties of Objective-C classes. The outlet must also 01050 // have an object reference type. 01051 if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 01052 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 01053 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 01054 << Attr.getName() << VD->getType() << 0; 01055 return false; 01056 } 01057 } 01058 else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 01059 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 01060 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 01061 << Attr.getName() << PD->getType() << 1; 01062 return false; 01063 } 01064 } 01065 else { 01066 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 01067 return false; 01068 } 01069 01070 return true; 01071 } 01072 01073 static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 01074 if (!checkIBOutletCommon(S, D, Attr)) 01075 return; 01076 01077 D->addAttr(::new (S.Context) 01078 IBOutletAttr(Attr.getRange(), S.Context, 01079 Attr.getAttributeSpellingListIndex())); 01080 } 01081 01082 static void handleIBOutletCollection(Sema &S, Decl *D, 01083 const AttributeList &Attr) { 01084 01085 // The iboutletcollection attribute can have zero or one arguments. 01086 if (Attr.getNumArgs() > 1) { 01087 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 01088 << Attr.getName() << 1; 01089 return; 01090 } 01091 01092 if (!checkIBOutletCommon(S, D, Attr)) 01093 return; 01094 01095 ParsedType PT; 01096 01097 if (Attr.hasParsedType()) 01098 PT = Attr.getTypeArg(); 01099 else { 01100 PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(), 01101 S.getScopeForContext(D->getDeclContext()->getParent())); 01102 if (!PT) { 01103 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject"; 01104 return; 01105 } 01106 } 01107 01108 TypeSourceInfo *QTLoc = nullptr; 01109 QualType QT = S.GetTypeFromParser(PT, &QTLoc); 01110 if (!QTLoc) 01111 QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc()); 01112 01113 // Diagnose use of non-object type in iboutletcollection attribute. 01114 // FIXME. Gnu attribute extension ignores use of builtin types in 01115 // attributes. So, __attribute__((iboutletcollection(char))) will be 01116 // treated as __attribute__((iboutletcollection())). 01117 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 01118 S.Diag(Attr.getLoc(), 01119 QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype 01120 : diag::err_iboutletcollection_type) << QT; 01121 return; 01122 } 01123 01124 D->addAttr(::new (S.Context) 01125 IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc, 01126 Attr.getAttributeSpellingListIndex())); 01127 } 01128 01129 bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { 01130 if (RefOkay) { 01131 if (T->isReferenceType()) 01132 return true; 01133 } else { 01134 T = T.getNonReferenceType(); 01135 } 01136 01137 // The nonnull attribute, and other similar attributes, can be applied to a 01138 // transparent union that contains a pointer type. 01139 if (const RecordType *UT = T->getAsUnionType()) { 01140 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 01141 RecordDecl *UD = UT->getDecl(); 01142 for (const auto *I : UD->fields()) { 01143 QualType QT = I->getType(); 01144 if (QT->isAnyPointerType() || QT->isBlockPointerType()) 01145 return true; 01146 } 01147 } 01148 } 01149 01150 return T->isAnyPointerType() || T->isBlockPointerType(); 01151 } 01152 01153 static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr, 01154 SourceRange AttrParmRange, 01155 SourceRange TypeRange, 01156 bool isReturnValue = false) { 01157 if (!S.isValidPointerAttrType(T)) { 01158 S.Diag(Attr.getLoc(), isReturnValue 01159 ? diag::warn_attribute_return_pointers_only 01160 : diag::warn_attribute_pointers_only) 01161 << Attr.getName() << AttrParmRange << TypeRange; 01162 return false; 01163 } 01164 return true; 01165 } 01166 01167 static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01168 SmallVector<unsigned, 8> NonNullArgs; 01169 for (unsigned I = 0; I < Attr.getNumArgs(); ++I) { 01170 Expr *Ex = Attr.getArgAsExpr(I); 01171 uint64_t Idx; 01172 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, I + 1, Ex, Idx)) 01173 return; 01174 01175 // Is the function argument a pointer type? 01176 if (Idx < getFunctionOrMethodNumParams(D) && 01177 !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr, 01178 Ex->getSourceRange(), 01179 getFunctionOrMethodParamRange(D, Idx))) 01180 continue; 01181 01182 NonNullArgs.push_back(Idx); 01183 } 01184 01185 // If no arguments were specified to __attribute__((nonnull)) then all pointer 01186 // arguments have a nonnull attribute; warn if there aren't any. Skip this 01187 // check if the attribute came from a macro expansion or a template 01188 // instantiation. 01189 if (NonNullArgs.empty() && Attr.getLoc().isFileID() && 01190 S.ActiveTemplateInstantiations.empty()) { 01191 bool AnyPointers = isFunctionOrMethodVariadic(D); 01192 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); 01193 I != E && !AnyPointers; ++I) { 01194 QualType T = getFunctionOrMethodParamType(D, I); 01195 if (T->isDependentType() || S.isValidPointerAttrType(T)) 01196 AnyPointers = true; 01197 } 01198 01199 if (!AnyPointers) 01200 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 01201 } 01202 01203 unsigned *Start = NonNullArgs.data(); 01204 unsigned Size = NonNullArgs.size(); 01205 llvm::array_pod_sort(Start, Start + Size); 01206 D->addAttr(::new (S.Context) 01207 NonNullAttr(Attr.getRange(), S.Context, Start, Size, 01208 Attr.getAttributeSpellingListIndex())); 01209 } 01210 01211 static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, 01212 const AttributeList &Attr) { 01213 if (Attr.getNumArgs() > 0) { 01214 if (D->getFunctionType()) { 01215 handleNonNullAttr(S, D, Attr); 01216 } else { 01217 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_parm_no_args) 01218 << D->getSourceRange(); 01219 } 01220 return; 01221 } 01222 01223 // Is the argument a pointer type? 01224 if (!attrNonNullArgCheck(S, D->getType(), Attr, SourceRange(), 01225 D->getSourceRange())) 01226 return; 01227 01228 D->addAttr(::new (S.Context) 01229 NonNullAttr(Attr.getRange(), S.Context, nullptr, 0, 01230 Attr.getAttributeSpellingListIndex())); 01231 } 01232 01233 static void handleReturnsNonNullAttr(Sema &S, Decl *D, 01234 const AttributeList &Attr) { 01235 QualType ResultType = getFunctionOrMethodResultType(D); 01236 SourceRange SR = getFunctionOrMethodResultSourceRange(D); 01237 if (!attrNonNullArgCheck(S, ResultType, Attr, SourceRange(), SR, 01238 /* isReturnValue */ true)) 01239 return; 01240 01241 D->addAttr(::new (S.Context) 01242 ReturnsNonNullAttr(Attr.getRange(), S.Context, 01243 Attr.getAttributeSpellingListIndex())); 01244 } 01245 01246 static void handleAssumeAlignedAttr(Sema &S, Decl *D, 01247 const AttributeList &Attr) { 01248 Expr *E = Attr.getArgAsExpr(0), 01249 *OE = Attr.getNumArgs() > 1 ? Attr.getArgAsExpr(1) : nullptr; 01250 S.AddAssumeAlignedAttr(Attr.getRange(), D, E, OE, 01251 Attr.getAttributeSpellingListIndex()); 01252 } 01253 01254 void Sema::AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 01255 Expr *OE, unsigned SpellingListIndex) { 01256 QualType ResultType = getFunctionOrMethodResultType(D); 01257 SourceRange SR = getFunctionOrMethodResultSourceRange(D); 01258 01259 AssumeAlignedAttr TmpAttr(AttrRange, Context, E, OE, SpellingListIndex); 01260 SourceLocation AttrLoc = AttrRange.getBegin(); 01261 01262 if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) { 01263 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only) 01264 << &TmpAttr << AttrRange << SR; 01265 return; 01266 } 01267 01268 if (!E->isValueDependent()) { 01269 llvm::APSInt I(64); 01270 if (!E->isIntegerConstantExpr(I, Context)) { 01271 if (OE) 01272 Diag(AttrLoc, diag::err_attribute_argument_n_type) 01273 << &TmpAttr << 1 << AANT_ArgumentIntegerConstant 01274 << E->getSourceRange(); 01275 else 01276 Diag(AttrLoc, diag::err_attribute_argument_type) 01277 << &TmpAttr << AANT_ArgumentIntegerConstant 01278 << E->getSourceRange(); 01279 return; 01280 } 01281 01282 if (!I.isPowerOf2()) { 01283 Diag(AttrLoc, diag::err_alignment_not_power_of_two) 01284 << E->getSourceRange(); 01285 return; 01286 } 01287 } 01288 01289 if (OE) { 01290 if (!OE->isValueDependent()) { 01291 llvm::APSInt I(64); 01292 if (!OE->isIntegerConstantExpr(I, Context)) { 01293 Diag(AttrLoc, diag::err_attribute_argument_n_type) 01294 << &TmpAttr << 2 << AANT_ArgumentIntegerConstant 01295 << OE->getSourceRange(); 01296 return; 01297 } 01298 } 01299 } 01300 01301 D->addAttr(::new (Context) 01302 AssumeAlignedAttr(AttrRange, Context, E, OE, SpellingListIndex)); 01303 } 01304 01305 static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 01306 // This attribute must be applied to a function declaration. The first 01307 // argument to the attribute must be an identifier, the name of the resource, 01308 // for example: malloc. The following arguments must be argument indexes, the 01309 // arguments must be of integer type for Returns, otherwise of pointer type. 01310 // The difference between Holds and Takes is that a pointer may still be used 01311 // after being held. free() should be __attribute((ownership_takes)), whereas 01312 // a list append function may well be __attribute((ownership_holds)). 01313 01314 if (!AL.isArgIdent(0)) { 01315 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) 01316 << AL.getName() << 1 << AANT_ArgumentIdentifier; 01317 return; 01318 } 01319 01320 // Figure out our Kind. 01321 OwnershipAttr::OwnershipKind K = 01322 OwnershipAttr(AL.getLoc(), S.Context, nullptr, nullptr, 0, 01323 AL.getAttributeSpellingListIndex()).getOwnKind(); 01324 01325 // Check arguments. 01326 switch (K) { 01327 case OwnershipAttr::Takes: 01328 case OwnershipAttr::Holds: 01329 if (AL.getNumArgs() < 2) { 01330 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) 01331 << AL.getName() << 2; 01332 return; 01333 } 01334 break; 01335 case OwnershipAttr::Returns: 01336 if (AL.getNumArgs() > 2) { 01337 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) 01338 << AL.getName() << 1; 01339 return; 01340 } 01341 break; 01342 } 01343 01344 IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident; 01345 01346 // Normalize the argument, __foo__ becomes foo. 01347 StringRef ModuleName = Module->getName(); 01348 if (ModuleName.startswith("__") && ModuleName.endswith("__") && 01349 ModuleName.size() > 4) { 01350 ModuleName = ModuleName.drop_front(2).drop_back(2); 01351 Module = &S.PP.getIdentifierTable().get(ModuleName); 01352 } 01353 01354 SmallVector<unsigned, 8> OwnershipArgs; 01355 for (unsigned i = 1; i < AL.getNumArgs(); ++i) { 01356 Expr *Ex = AL.getArgAsExpr(i); 01357 uint64_t Idx; 01358 if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx)) 01359 return; 01360 01361 // Is the function argument a pointer type? 01362 QualType T = getFunctionOrMethodParamType(D, Idx); 01363 int Err = -1; // No error 01364 switch (K) { 01365 case OwnershipAttr::Takes: 01366 case OwnershipAttr::Holds: 01367 if (!T->isAnyPointerType() && !T->isBlockPointerType()) 01368 Err = 0; 01369 break; 01370 case OwnershipAttr::Returns: 01371 if (!T->isIntegerType()) 01372 Err = 1; 01373 break; 01374 } 01375 if (-1 != Err) { 01376 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err 01377 << Ex->getSourceRange(); 01378 return; 01379 } 01380 01381 // Check we don't have a conflict with another ownership attribute. 01382 for (const auto *I : D->specific_attrs<OwnershipAttr>()) { 01383 // Cannot have two ownership attributes of different kinds for the same 01384 // index. 01385 if (I->getOwnKind() != K && I->args_end() != 01386 std::find(I->args_begin(), I->args_end(), Idx)) { 01387 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 01388 << AL.getName() << I; 01389 return; 01390 } else if (K == OwnershipAttr::Returns && 01391 I->getOwnKind() == OwnershipAttr::Returns) { 01392 // A returns attribute conflicts with any other returns attribute using 01393 // a different index. Note, diagnostic reporting is 1-based, but stored 01394 // argument indexes are 0-based. 01395 if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) { 01396 S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch) 01397 << *(I->args_begin()) + 1; 01398 if (I->args_size()) 01399 S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch) 01400 << (unsigned)Idx + 1 << Ex->getSourceRange(); 01401 return; 01402 } 01403 } 01404 } 01405 OwnershipArgs.push_back(Idx); 01406 } 01407 01408 unsigned* start = OwnershipArgs.data(); 01409 unsigned size = OwnershipArgs.size(); 01410 llvm::array_pod_sort(start, start + size); 01411 01412 D->addAttr(::new (S.Context) 01413 OwnershipAttr(AL.getLoc(), S.Context, Module, start, size, 01414 AL.getAttributeSpellingListIndex())); 01415 } 01416 01417 static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01418 // Check the attribute arguments. 01419 if (Attr.getNumArgs() > 1) { 01420 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 01421 << Attr.getName() << 1; 01422 return; 01423 } 01424 01425 NamedDecl *nd = cast<NamedDecl>(D); 01426 01427 // gcc rejects 01428 // class c { 01429 // static int a __attribute__((weakref ("v2"))); 01430 // static int b() __attribute__((weakref ("f3"))); 01431 // }; 01432 // and ignores the attributes of 01433 // void f(void) { 01434 // static int a __attribute__((weakref ("v2"))); 01435 // } 01436 // we reject them 01437 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 01438 if (!Ctx->isFileContext()) { 01439 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) 01440 << nd; 01441 return; 01442 } 01443 01444 // The GCC manual says 01445 // 01446 // At present, a declaration to which `weakref' is attached can only 01447 // be `static'. 01448 // 01449 // It also says 01450 // 01451 // Without a TARGET, 01452 // given as an argument to `weakref' or to `alias', `weakref' is 01453 // equivalent to `weak'. 01454 // 01455 // gcc 4.4.1 will accept 01456 // int a7 __attribute__((weakref)); 01457 // as 01458 // int a7 __attribute__((weak)); 01459 // This looks like a bug in gcc. We reject that for now. We should revisit 01460 // it if this behaviour is actually used. 01461 01462 // GCC rejects 01463 // static ((alias ("y"), weakref)). 01464 // Should we? How to check that weakref is before or after alias? 01465 01466 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead 01467 // of transforming it into an AliasAttr. The WeakRefAttr never uses the 01468 // StringRef parameter it was given anyway. 01469 StringRef Str; 01470 if (Attr.getNumArgs() && S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 01471 // GCC will accept anything as the argument of weakref. Should we 01472 // check for an existing decl? 01473 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, 01474 Attr.getAttributeSpellingListIndex())); 01475 01476 D->addAttr(::new (S.Context) 01477 WeakRefAttr(Attr.getRange(), S.Context, 01478 Attr.getAttributeSpellingListIndex())); 01479 } 01480 01481 static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01482 StringRef Str; 01483 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 01484 return; 01485 01486 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 01487 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 01488 return; 01489 } 01490 01491 // FIXME: check if target symbol exists in current file 01492 01493 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, 01494 Attr.getAttributeSpellingListIndex())); 01495 } 01496 01497 static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01498 if (checkAttrMutualExclusion<HotAttr>(S, D, Attr)) 01499 return; 01500 01501 D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context, 01502 Attr.getAttributeSpellingListIndex())); 01503 } 01504 01505 static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01506 if (checkAttrMutualExclusion<ColdAttr>(S, D, Attr)) 01507 return; 01508 01509 D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context, 01510 Attr.getAttributeSpellingListIndex())); 01511 } 01512 01513 static void handleTLSModelAttr(Sema &S, Decl *D, 01514 const AttributeList &Attr) { 01515 StringRef Model; 01516 SourceLocation LiteralLoc; 01517 // Check that it is a string. 01518 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc)) 01519 return; 01520 01521 // Check that the value. 01522 if (Model != "global-dynamic" && Model != "local-dynamic" 01523 && Model != "initial-exec" && Model != "local-exec") { 01524 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg); 01525 return; 01526 } 01527 01528 D->addAttr(::new (S.Context) 01529 TLSModelAttr(Attr.getRange(), S.Context, Model, 01530 Attr.getAttributeSpellingListIndex())); 01531 } 01532 01533 static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01534 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 01535 QualType RetTy = FD->getReturnType(); 01536 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 01537 D->addAttr(::new (S.Context) 01538 MallocAttr(Attr.getRange(), S.Context, 01539 Attr.getAttributeSpellingListIndex())); 01540 return; 01541 } 01542 } 01543 01544 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 01545 } 01546 01547 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01548 if (S.LangOpts.CPlusPlus) { 01549 S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) 01550 << Attr.getName() << AttributeLangSupport::Cpp; 01551 return; 01552 } 01553 01554 D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context, 01555 Attr.getAttributeSpellingListIndex())); 01556 } 01557 01558 static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 01559 if (hasDeclarator(D)) return; 01560 01561 if (S.CheckNoReturnAttr(attr)) return; 01562 01563 if (!isa<ObjCMethodDecl>(D)) { 01564 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01565 << attr.getName() << ExpectedFunctionOrMethod; 01566 return; 01567 } 01568 01569 D->addAttr(::new (S.Context) 01570 NoReturnAttr(attr.getRange(), S.Context, 01571 attr.getAttributeSpellingListIndex())); 01572 } 01573 01574 bool Sema::CheckNoReturnAttr(const AttributeList &attr) { 01575 if (!checkAttributeNumArgs(*this, attr, 0)) { 01576 attr.setInvalid(); 01577 return true; 01578 } 01579 01580 return false; 01581 } 01582 01583 static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 01584 const AttributeList &Attr) { 01585 01586 // The checking path for 'noreturn' and 'analyzer_noreturn' are different 01587 // because 'analyzer_noreturn' does not impact the type. 01588 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 01589 ValueDecl *VD = dyn_cast<ValueDecl>(D); 01590 if (!VD || (!VD->getType()->isBlockPointerType() && 01591 !VD->getType()->isFunctionPointerType())) { 01592 S.Diag(Attr.getLoc(), 01593 Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type 01594 : diag::warn_attribute_wrong_decl_type) 01595 << Attr.getName() << ExpectedFunctionMethodOrBlock; 01596 return; 01597 } 01598 } 01599 01600 D->addAttr(::new (S.Context) 01601 AnalyzerNoReturnAttr(Attr.getRange(), S.Context, 01602 Attr.getAttributeSpellingListIndex())); 01603 } 01604 01605 // PS3 PPU-specific. 01606 static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01607 /* 01608 Returning a Vector Class in Registers 01609 01610 According to the PPU ABI specifications, a class with a single member of 01611 vector type is returned in memory when used as the return value of a function. 01612 This results in inefficient code when implementing vector classes. To return 01613 the value in a single vector register, add the vecreturn attribute to the 01614 class definition. This attribute is also applicable to struct types. 01615 01616 Example: 01617 01618 struct Vector 01619 { 01620 __vector float xyzw; 01621 } __attribute__((vecreturn)); 01622 01623 Vector Add(Vector lhs, Vector rhs) 01624 { 01625 Vector result; 01626 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 01627 return result; // This will be returned in a register 01628 } 01629 */ 01630 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) { 01631 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << A; 01632 return; 01633 } 01634 01635 RecordDecl *record = cast<RecordDecl>(D); 01636 int count = 0; 01637 01638 if (!isa<CXXRecordDecl>(record)) { 01639 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 01640 return; 01641 } 01642 01643 if (!cast<CXXRecordDecl>(record)->isPOD()) { 01644 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 01645 return; 01646 } 01647 01648 for (const auto *I : record->fields()) { 01649 if ((count == 1) || !I->getType()->isVectorType()) { 01650 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 01651 return; 01652 } 01653 count++; 01654 } 01655 01656 D->addAttr(::new (S.Context) 01657 VecReturnAttr(Attr.getRange(), S.Context, 01658 Attr.getAttributeSpellingListIndex())); 01659 } 01660 01661 static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, 01662 const AttributeList &Attr) { 01663 if (isa<ParmVarDecl>(D)) { 01664 // [[carries_dependency]] can only be applied to a parameter if it is a 01665 // parameter of a function declaration or lambda. 01666 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) { 01667 S.Diag(Attr.getLoc(), 01668 diag::err_carries_dependency_param_not_function_decl); 01669 return; 01670 } 01671 } 01672 01673 D->addAttr(::new (S.Context) CarriesDependencyAttr( 01674 Attr.getRange(), S.Context, 01675 Attr.getAttributeSpellingListIndex())); 01676 } 01677 01678 static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01679 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 01680 if (VD->hasLocalStorage()) { 01681 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 01682 return; 01683 } 01684 } else if (!isFunctionOrMethod(D)) { 01685 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01686 << Attr.getName() << ExpectedVariableOrFunction; 01687 return; 01688 } 01689 01690 D->addAttr(::new (S.Context) 01691 UsedAttr(Attr.getRange(), S.Context, 01692 Attr.getAttributeSpellingListIndex())); 01693 } 01694 01695 static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01696 uint32_t priority = ConstructorAttr::DefaultPriority; 01697 if (Attr.getNumArgs() && 01698 !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority)) 01699 return; 01700 01701 D->addAttr(::new (S.Context) 01702 ConstructorAttr(Attr.getRange(), S.Context, priority, 01703 Attr.getAttributeSpellingListIndex())); 01704 } 01705 01706 static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01707 uint32_t priority = DestructorAttr::DefaultPriority; 01708 if (Attr.getNumArgs() && 01709 !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority)) 01710 return; 01711 01712 D->addAttr(::new (S.Context) 01713 DestructorAttr(Attr.getRange(), S.Context, priority, 01714 Attr.getAttributeSpellingListIndex())); 01715 } 01716 01717 template <typename AttrTy> 01718 static void handleAttrWithMessage(Sema &S, Decl *D, 01719 const AttributeList &Attr) { 01720 // Handle the case where the attribute has a text message. 01721 StringRef Str; 01722 if (Attr.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 01723 return; 01724 01725 D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str, 01726 Attr.getAttributeSpellingListIndex())); 01727 } 01728 01729 static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D, 01730 const AttributeList &Attr) { 01731 if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) { 01732 S.Diag(Attr.getLoc(), diag::err_objc_attr_protocol_requires_definition) 01733 << Attr.getName() << Attr.getRange(); 01734 return; 01735 } 01736 01737 D->addAttr(::new (S.Context) 01738 ObjCExplicitProtocolImplAttr(Attr.getRange(), S.Context, 01739 Attr.getAttributeSpellingListIndex())); 01740 } 01741 01742 static bool checkAvailabilityAttr(Sema &S, SourceRange Range, 01743 IdentifierInfo *Platform, 01744 VersionTuple Introduced, 01745 VersionTuple Deprecated, 01746 VersionTuple Obsoleted) { 01747 StringRef PlatformName 01748 = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 01749 if (PlatformName.empty()) 01750 PlatformName = Platform->getName(); 01751 01752 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 01753 // of these steps are needed). 01754 if (!Introduced.empty() && !Deprecated.empty() && 01755 !(Introduced <= Deprecated)) { 01756 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 01757 << 1 << PlatformName << Deprecated.getAsString() 01758 << 0 << Introduced.getAsString(); 01759 return true; 01760 } 01761 01762 if (!Introduced.empty() && !Obsoleted.empty() && 01763 !(Introduced <= Obsoleted)) { 01764 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 01765 << 2 << PlatformName << Obsoleted.getAsString() 01766 << 0 << Introduced.getAsString(); 01767 return true; 01768 } 01769 01770 if (!Deprecated.empty() && !Obsoleted.empty() && 01771 !(Deprecated <= Obsoleted)) { 01772 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 01773 << 2 << PlatformName << Obsoleted.getAsString() 01774 << 1 << Deprecated.getAsString(); 01775 return true; 01776 } 01777 01778 return false; 01779 } 01780 01781 /// \brief Check whether the two versions match. 01782 /// 01783 /// If either version tuple is empty, then they are assumed to match. If 01784 /// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y. 01785 static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y, 01786 bool BeforeIsOkay) { 01787 if (X.empty() || Y.empty()) 01788 return true; 01789 01790 if (X == Y) 01791 return true; 01792 01793 if (BeforeIsOkay && X < Y) 01794 return true; 01795 01796 return false; 01797 } 01798 01799 AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, 01800 IdentifierInfo *Platform, 01801 VersionTuple Introduced, 01802 VersionTuple Deprecated, 01803 VersionTuple Obsoleted, 01804 bool IsUnavailable, 01805 StringRef Message, 01806 bool Override, 01807 unsigned AttrSpellingListIndex) { 01808 VersionTuple MergedIntroduced = Introduced; 01809 VersionTuple MergedDeprecated = Deprecated; 01810 VersionTuple MergedObsoleted = Obsoleted; 01811 bool FoundAny = false; 01812 01813 if (D->hasAttrs()) { 01814 AttrVec &Attrs = D->getAttrs(); 01815 for (unsigned i = 0, e = Attrs.size(); i != e;) { 01816 const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); 01817 if (!OldAA) { 01818 ++i; 01819 continue; 01820 } 01821 01822 IdentifierInfo *OldPlatform = OldAA->getPlatform(); 01823 if (OldPlatform != Platform) { 01824 ++i; 01825 continue; 01826 } 01827 01828 FoundAny = true; 01829 VersionTuple OldIntroduced = OldAA->getIntroduced(); 01830 VersionTuple OldDeprecated = OldAA->getDeprecated(); 01831 VersionTuple OldObsoleted = OldAA->getObsoleted(); 01832 bool OldIsUnavailable = OldAA->getUnavailable(); 01833 01834 if (!versionsMatch(OldIntroduced, Introduced, Override) || 01835 !versionsMatch(Deprecated, OldDeprecated, Override) || 01836 !versionsMatch(Obsoleted, OldObsoleted, Override) || 01837 !(OldIsUnavailable == IsUnavailable || 01838 (Override && !OldIsUnavailable && IsUnavailable))) { 01839 if (Override) { 01840 int Which = -1; 01841 VersionTuple FirstVersion; 01842 VersionTuple SecondVersion; 01843 if (!versionsMatch(OldIntroduced, Introduced, Override)) { 01844 Which = 0; 01845 FirstVersion = OldIntroduced; 01846 SecondVersion = Introduced; 01847 } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) { 01848 Which = 1; 01849 FirstVersion = Deprecated; 01850 SecondVersion = OldDeprecated; 01851 } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) { 01852 Which = 2; 01853 FirstVersion = Obsoleted; 01854 SecondVersion = OldObsoleted; 01855 } 01856 01857 if (Which == -1) { 01858 Diag(OldAA->getLocation(), 01859 diag::warn_mismatched_availability_override_unavail) 01860 << AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 01861 } else { 01862 Diag(OldAA->getLocation(), 01863 diag::warn_mismatched_availability_override) 01864 << Which 01865 << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) 01866 << FirstVersion.getAsString() << SecondVersion.getAsString(); 01867 } 01868 Diag(Range.getBegin(), diag::note_overridden_method); 01869 } else { 01870 Diag(OldAA->getLocation(), diag::warn_mismatched_availability); 01871 Diag(Range.getBegin(), diag::note_previous_attribute); 01872 } 01873 01874 Attrs.erase(Attrs.begin() + i); 01875 --e; 01876 continue; 01877 } 01878 01879 VersionTuple MergedIntroduced2 = MergedIntroduced; 01880 VersionTuple MergedDeprecated2 = MergedDeprecated; 01881 VersionTuple MergedObsoleted2 = MergedObsoleted; 01882 01883 if (MergedIntroduced2.empty()) 01884 MergedIntroduced2 = OldIntroduced; 01885 if (MergedDeprecated2.empty()) 01886 MergedDeprecated2 = OldDeprecated; 01887 if (MergedObsoleted2.empty()) 01888 MergedObsoleted2 = OldObsoleted; 01889 01890 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, 01891 MergedIntroduced2, MergedDeprecated2, 01892 MergedObsoleted2)) { 01893 Attrs.erase(Attrs.begin() + i); 01894 --e; 01895 continue; 01896 } 01897 01898 MergedIntroduced = MergedIntroduced2; 01899 MergedDeprecated = MergedDeprecated2; 01900 MergedObsoleted = MergedObsoleted2; 01901 ++i; 01902 } 01903 } 01904 01905 if (FoundAny && 01906 MergedIntroduced == Introduced && 01907 MergedDeprecated == Deprecated && 01908 MergedObsoleted == Obsoleted) 01909 return nullptr; 01910 01911 // Only create a new attribute if !Override, but we want to do 01912 // the checking. 01913 if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, 01914 MergedDeprecated, MergedObsoleted) && 01915 !Override) { 01916 return ::new (Context) AvailabilityAttr(Range, Context, Platform, 01917 Introduced, Deprecated, 01918 Obsoleted, IsUnavailable, Message, 01919 AttrSpellingListIndex); 01920 } 01921 return nullptr; 01922 } 01923 01924 static void handleAvailabilityAttr(Sema &S, Decl *D, 01925 const AttributeList &Attr) { 01926 if (!checkAttributeNumArgs(S, Attr, 1)) 01927 return; 01928 IdentifierLoc *Platform = Attr.getArgAsIdent(0); 01929 unsigned Index = Attr.getAttributeSpellingListIndex(); 01930 01931 IdentifierInfo *II = Platform->Ident; 01932 if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty()) 01933 S.Diag(Platform->Loc, diag::warn_availability_unknown_platform) 01934 << Platform->Ident; 01935 01936 NamedDecl *ND = dyn_cast<NamedDecl>(D); 01937 if (!ND) { 01938 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 01939 return; 01940 } 01941 01942 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 01943 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 01944 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 01945 bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 01946 StringRef Str; 01947 if (const StringLiteral *SE = 01948 dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr())) 01949 Str = SE->getString(); 01950 01951 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II, 01952 Introduced.Version, 01953 Deprecated.Version, 01954 Obsoleted.Version, 01955 IsUnavailable, Str, 01956 /*Override=*/false, 01957 Index); 01958 if (NewAttr) 01959 D->addAttr(NewAttr); 01960 } 01961 01962 template <class T> 01963 static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range, 01964 typename T::VisibilityType value, 01965 unsigned attrSpellingListIndex) { 01966 T *existingAttr = D->getAttr<T>(); 01967 if (existingAttr) { 01968 typename T::VisibilityType existingValue = existingAttr->getVisibility(); 01969 if (existingValue == value) 01970 return nullptr; 01971 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility); 01972 S.Diag(range.getBegin(), diag::note_previous_attribute); 01973 D->dropAttr<T>(); 01974 } 01975 return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex); 01976 } 01977 01978 VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, 01979 VisibilityAttr::VisibilityType Vis, 01980 unsigned AttrSpellingListIndex) { 01981 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis, 01982 AttrSpellingListIndex); 01983 } 01984 01985 TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range, 01986 TypeVisibilityAttr::VisibilityType Vis, 01987 unsigned AttrSpellingListIndex) { 01988 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis, 01989 AttrSpellingListIndex); 01990 } 01991 01992 static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr, 01993 bool isTypeVisibility) { 01994 // Visibility attributes don't mean anything on a typedef. 01995 if (isa<TypedefNameDecl>(D)) { 01996 S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored) 01997 << Attr.getName(); 01998 return; 01999 } 02000 02001 // 'type_visibility' can only go on a type or namespace. 02002 if (isTypeVisibility && 02003 !(isa<TagDecl>(D) || 02004 isa<ObjCInterfaceDecl>(D) || 02005 isa<NamespaceDecl>(D))) { 02006 S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type) 02007 << Attr.getName() << ExpectedTypeOrNamespace; 02008 return; 02009 } 02010 02011 // Check that the argument is a string literal. 02012 StringRef TypeStr; 02013 SourceLocation LiteralLoc; 02014 if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc)) 02015 return; 02016 02017 VisibilityAttr::VisibilityType type; 02018 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) { 02019 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) 02020 << Attr.getName() << TypeStr; 02021 return; 02022 } 02023 02024 // Complain about attempts to use protected visibility on targets 02025 // (like Darwin) that don't support it. 02026 if (type == VisibilityAttr::Protected && 02027 !S.Context.getTargetInfo().hasProtectedVisibility()) { 02028 S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 02029 type = VisibilityAttr::Default; 02030 } 02031 02032 unsigned Index = Attr.getAttributeSpellingListIndex(); 02033 clang::Attr *newAttr; 02034 if (isTypeVisibility) { 02035 newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(), 02036 (TypeVisibilityAttr::VisibilityType) type, 02037 Index); 02038 } else { 02039 newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index); 02040 } 02041 if (newAttr) 02042 D->addAttr(newAttr); 02043 } 02044 02045 static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 02046 const AttributeList &Attr) { 02047 ObjCMethodDecl *method = cast<ObjCMethodDecl>(decl); 02048 if (!Attr.isArgIdent(0)) { 02049 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 02050 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 02051 return; 02052 } 02053 02054 IdentifierLoc *IL = Attr.getArgAsIdent(0); 02055 ObjCMethodFamilyAttr::FamilyKind F; 02056 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) { 02057 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName() 02058 << IL->Ident; 02059 return; 02060 } 02061 02062 if (F == ObjCMethodFamilyAttr::OMF_init && 02063 !method->getReturnType()->isObjCObjectPointerType()) { 02064 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 02065 << method->getReturnType(); 02066 // Ignore the attribute. 02067 return; 02068 } 02069 02070 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 02071 S.Context, F, 02072 Attr.getAttributeSpellingListIndex())); 02073 } 02074 02075 static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 02076 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 02077 QualType T = TD->getUnderlyingType(); 02078 if (!T->isCARCBridgableType()) { 02079 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 02080 return; 02081 } 02082 } 02083 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 02084 QualType T = PD->getType(); 02085 if (!T->isCARCBridgableType()) { 02086 S.Diag(PD->getLocation(), diag::err_nsobject_attribute); 02087 return; 02088 } 02089 } 02090 else { 02091 // It is okay to include this attribute on properties, e.g.: 02092 // 02093 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 02094 // 02095 // In this case it follows tradition and suppresses an error in the above 02096 // case. 02097 S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 02098 } 02099 D->addAttr(::new (S.Context) 02100 ObjCNSObjectAttr(Attr.getRange(), S.Context, 02101 Attr.getAttributeSpellingListIndex())); 02102 } 02103 02104 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02105 if (!Attr.isArgIdent(0)) { 02106 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 02107 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 02108 return; 02109 } 02110 02111 IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; 02112 BlocksAttr::BlockType type; 02113 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) { 02114 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 02115 << Attr.getName() << II; 02116 return; 02117 } 02118 02119 D->addAttr(::new (S.Context) 02120 BlocksAttr(Attr.getRange(), S.Context, type, 02121 Attr.getAttributeSpellingListIndex())); 02122 } 02123 02124 static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02125 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel; 02126 if (Attr.getNumArgs() > 0) { 02127 Expr *E = Attr.getArgAsExpr(0); 02128 llvm::APSInt Idx(32); 02129 if (E->isTypeDependent() || E->isValueDependent() || 02130 !E->isIntegerConstantExpr(Idx, S.Context)) { 02131 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 02132 << Attr.getName() << 1 << AANT_ArgumentIntegerConstant 02133 << E->getSourceRange(); 02134 return; 02135 } 02136 02137 if (Idx.isSigned() && Idx.isNegative()) { 02138 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 02139 << E->getSourceRange(); 02140 return; 02141 } 02142 02143 sentinel = Idx.getZExtValue(); 02144 } 02145 02146 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos; 02147 if (Attr.getNumArgs() > 1) { 02148 Expr *E = Attr.getArgAsExpr(1); 02149 llvm::APSInt Idx(32); 02150 if (E->isTypeDependent() || E->isValueDependent() || 02151 !E->isIntegerConstantExpr(Idx, S.Context)) { 02152 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 02153 << Attr.getName() << 2 << AANT_ArgumentIntegerConstant 02154 << E->getSourceRange(); 02155 return; 02156 } 02157 nullPos = Idx.getZExtValue(); 02158 02159 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 02160 // FIXME: This error message could be improved, it would be nice 02161 // to say what the bounds actually are. 02162 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 02163 << E->getSourceRange(); 02164 return; 02165 } 02166 } 02167 02168 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 02169 const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 02170 if (isa<FunctionNoProtoType>(FT)) { 02171 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 02172 return; 02173 } 02174 02175 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 02176 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 02177 return; 02178 } 02179 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 02180 if (!MD->isVariadic()) { 02181 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 02182 return; 02183 } 02184 } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 02185 if (!BD->isVariadic()) { 02186 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 02187 return; 02188 } 02189 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 02190 QualType Ty = V->getType(); 02191 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 02192 const FunctionType *FT = Ty->isFunctionPointerType() 02193 ? D->getFunctionType() 02194 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 02195 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 02196 int m = Ty->isFunctionPointerType() ? 0 : 1; 02197 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 02198 return; 02199 } 02200 } else { 02201 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02202 << Attr.getName() << ExpectedFunctionMethodOrBlock; 02203 return; 02204 } 02205 } else { 02206 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02207 << Attr.getName() << ExpectedFunctionMethodOrBlock; 02208 return; 02209 } 02210 D->addAttr(::new (S.Context) 02211 SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos, 02212 Attr.getAttributeSpellingListIndex())); 02213 } 02214 02215 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 02216 if (D->getFunctionType() && 02217 D->getFunctionType()->getReturnType()->isVoidType()) { 02218 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 02219 << Attr.getName() << 0; 02220 return; 02221 } 02222 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 02223 if (MD->getReturnType()->isVoidType()) { 02224 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 02225 << Attr.getName() << 1; 02226 return; 02227 } 02228 02229 D->addAttr(::new (S.Context) 02230 WarnUnusedResultAttr(Attr.getRange(), S.Context, 02231 Attr.getAttributeSpellingListIndex())); 02232 } 02233 02234 static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02235 // weak_import only applies to variable & function declarations. 02236 bool isDef = false; 02237 if (!D->canBeWeakImported(isDef)) { 02238 if (isDef) 02239 S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition) 02240 << "weak_import"; 02241 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 02242 (S.Context.getTargetInfo().getTriple().isOSDarwin() && 02243 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 02244 // Nothing to warn about here. 02245 } else 02246 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02247 << Attr.getName() << ExpectedVariableOrFunction; 02248 02249 return; 02250 } 02251 02252 D->addAttr(::new (S.Context) 02253 WeakImportAttr(Attr.getRange(), S.Context, 02254 Attr.getAttributeSpellingListIndex())); 02255 } 02256 02257 // Handles reqd_work_group_size and work_group_size_hint. 02258 template <typename WorkGroupAttr> 02259 static void handleWorkGroupSize(Sema &S, Decl *D, 02260 const AttributeList &Attr) { 02261 uint32_t WGSize[3]; 02262 for (unsigned i = 0; i < 3; ++i) { 02263 const Expr *E = Attr.getArgAsExpr(i); 02264 if (!checkUInt32Argument(S, Attr, E, WGSize[i], i)) 02265 return; 02266 if (WGSize[i] == 0) { 02267 S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) 02268 << Attr.getName() << E->getSourceRange(); 02269 return; 02270 } 02271 } 02272 02273 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>(); 02274 if (Existing && !(Existing->getXDim() == WGSize[0] && 02275 Existing->getYDim() == WGSize[1] && 02276 Existing->getZDim() == WGSize[2])) 02277 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName(); 02278 02279 D->addAttr(::new (S.Context) WorkGroupAttr(Attr.getRange(), S.Context, 02280 WGSize[0], WGSize[1], WGSize[2], 02281 Attr.getAttributeSpellingListIndex())); 02282 } 02283 02284 static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { 02285 if (!Attr.hasParsedType()) { 02286 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 02287 << Attr.getName() << 1; 02288 return; 02289 } 02290 02291 TypeSourceInfo *ParmTSI = nullptr; 02292 QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI); 02293 assert(ParmTSI && "no type source info for attribute argument"); 02294 02295 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() && 02296 (ParmType->isBooleanType() || 02297 !ParmType->isIntegralType(S.getASTContext()))) { 02298 S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint) 02299 << ParmType; 02300 return; 02301 } 02302 02303 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) { 02304 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) { 02305 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName(); 02306 return; 02307 } 02308 } 02309 02310 D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context, 02311 ParmTSI, 02312 Attr.getAttributeSpellingListIndex())); 02313 } 02314 02315 SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, 02316 StringRef Name, 02317 unsigned AttrSpellingListIndex) { 02318 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { 02319 if (ExistingAttr->getName() == Name) 02320 return nullptr; 02321 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); 02322 Diag(Range.getBegin(), diag::note_previous_attribute); 02323 return nullptr; 02324 } 02325 return ::new (Context) SectionAttr(Range, Context, Name, 02326 AttrSpellingListIndex); 02327 } 02328 02329 static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02330 // Make sure that there is a string literal as the sections's single 02331 // argument. 02332 StringRef Str; 02333 SourceLocation LiteralLoc; 02334 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc)) 02335 return; 02336 02337 // If the target wants to validate the section specifier, make it happen. 02338 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str); 02339 if (!Error.empty()) { 02340 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) 02341 << Error; 02342 return; 02343 } 02344 02345 unsigned Index = Attr.getAttributeSpellingListIndex(); 02346 SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index); 02347 if (NewAttr) 02348 D->addAttr(NewAttr); 02349 } 02350 02351 02352 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02353 VarDecl *VD = cast<VarDecl>(D); 02354 if (!VD->hasLocalStorage()) { 02355 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 02356 return; 02357 } 02358 02359 Expr *E = Attr.getArgAsExpr(0); 02360 SourceLocation Loc = E->getExprLoc(); 02361 FunctionDecl *FD = nullptr; 02362 DeclarationNameInfo NI; 02363 02364 // gcc only allows for simple identifiers. Since we support more than gcc, we 02365 // will warn the user. 02366 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 02367 if (DRE->hasQualifier()) 02368 S.Diag(Loc, diag::warn_cleanup_ext); 02369 FD = dyn_cast<FunctionDecl>(DRE->getDecl()); 02370 NI = DRE->getNameInfo(); 02371 if (!FD) { 02372 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1 02373 << NI.getName(); 02374 return; 02375 } 02376 } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { 02377 if (ULE->hasExplicitTemplateArgs()) 02378 S.Diag(Loc, diag::warn_cleanup_ext); 02379 FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true); 02380 NI = ULE->getNameInfo(); 02381 if (!FD) { 02382 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2 02383 << NI.getName(); 02384 if (ULE->getType() == S.Context.OverloadTy) 02385 S.NoteAllOverloadCandidates(ULE); 02386 return; 02387 } 02388 } else { 02389 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0; 02390 return; 02391 } 02392 02393 if (FD->getNumParams() != 1) { 02394 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg) 02395 << NI.getName(); 02396 return; 02397 } 02398 02399 // We're currently more strict than GCC about what function types we accept. 02400 // If this ever proves to be a problem it should be easy to fix. 02401 QualType Ty = S.Context.getPointerType(VD->getType()); 02402 QualType ParamTy = FD->getParamDecl(0)->getType(); 02403 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 02404 ParamTy, Ty) != Sema::Compatible) { 02405 S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) 02406 << NI.getName() << ParamTy << Ty; 02407 return; 02408 } 02409 02410 D->addAttr(::new (S.Context) 02411 CleanupAttr(Attr.getRange(), S.Context, FD, 02412 Attr.getAttributeSpellingListIndex())); 02413 } 02414 02415 /// Handle __attribute__((format_arg((idx)))) attribute based on 02416 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 02417 static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02418 Expr *IdxExpr = Attr.getArgAsExpr(0); 02419 uint64_t Idx; 02420 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, IdxExpr, Idx)) 02421 return; 02422 02423 // make sure the format string is really a string 02424 QualType Ty = getFunctionOrMethodParamType(D, Idx); 02425 02426 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 02427 if (not_nsstring_type && 02428 !isCFStringType(Ty, S.Context) && 02429 (!Ty->isPointerType() || 02430 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 02431 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02432 << (not_nsstring_type ? "a string type" : "an NSString") 02433 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0); 02434 return; 02435 } 02436 Ty = getFunctionOrMethodResultType(D); 02437 if (!isNSStringType(Ty, S.Context) && 02438 !isCFStringType(Ty, S.Context) && 02439 (!Ty->isPointerType() || 02440 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 02441 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 02442 << (not_nsstring_type ? "string type" : "NSString") 02443 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0); 02444 return; 02445 } 02446 02447 // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex 02448 // because that has corrected for the implicit this parameter, and is zero- 02449 // based. The attribute expects what the user wrote explicitly. 02450 llvm::APSInt Val; 02451 IdxExpr->EvaluateAsInt(Val, S.Context); 02452 02453 D->addAttr(::new (S.Context) 02454 FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(), 02455 Attr.getAttributeSpellingListIndex())); 02456 } 02457 02458 enum FormatAttrKind { 02459 CFStringFormat, 02460 NSStringFormat, 02461 StrftimeFormat, 02462 SupportedFormat, 02463 IgnoredFormat, 02464 InvalidFormat 02465 }; 02466 02467 /// getFormatAttrKind - Map from format attribute names to supported format 02468 /// types. 02469 static FormatAttrKind getFormatAttrKind(StringRef Format) { 02470 return llvm::StringSwitch<FormatAttrKind>(Format) 02471 // Check for formats that get handled specially. 02472 .Case("NSString", NSStringFormat) 02473 .Case("CFString", CFStringFormat) 02474 .Case("strftime", StrftimeFormat) 02475 02476 // Otherwise, check for supported formats. 02477 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) 02478 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) 02479 .Case("kprintf", SupportedFormat) // OpenBSD. 02480 02481 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) 02482 .Default(InvalidFormat); 02483 } 02484 02485 /// Handle __attribute__((init_priority(priority))) attributes based on 02486 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 02487 static void handleInitPriorityAttr(Sema &S, Decl *D, 02488 const AttributeList &Attr) { 02489 if (!S.getLangOpts().CPlusPlus) { 02490 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 02491 return; 02492 } 02493 02494 if (S.getCurFunctionOrMethodDecl()) { 02495 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 02496 Attr.setInvalid(); 02497 return; 02498 } 02499 QualType T = cast<VarDecl>(D)->getType(); 02500 if (S.Context.getAsArrayType(T)) 02501 T = S.Context.getBaseElementType(T); 02502 if (!T->getAs<RecordType>()) { 02503 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 02504 Attr.setInvalid(); 02505 return; 02506 } 02507 02508 Expr *E = Attr.getArgAsExpr(0); 02509 uint32_t prioritynum; 02510 if (!checkUInt32Argument(S, Attr, E, prioritynum)) { 02511 Attr.setInvalid(); 02512 return; 02513 } 02514 02515 if (prioritynum < 101 || prioritynum > 65535) { 02516 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 02517 << E->getSourceRange(); 02518 Attr.setInvalid(); 02519 return; 02520 } 02521 D->addAttr(::new (S.Context) 02522 InitPriorityAttr(Attr.getRange(), S.Context, prioritynum, 02523 Attr.getAttributeSpellingListIndex())); 02524 } 02525 02526 FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, 02527 IdentifierInfo *Format, int FormatIdx, 02528 int FirstArg, 02529 unsigned AttrSpellingListIndex) { 02530 // Check whether we already have an equivalent format attribute. 02531 for (auto *F : D->specific_attrs<FormatAttr>()) { 02532 if (F->getType() == Format && 02533 F->getFormatIdx() == FormatIdx && 02534 F->getFirstArg() == FirstArg) { 02535 // If we don't have a valid location for this attribute, adopt the 02536 // location. 02537 if (F->getLocation().isInvalid()) 02538 F->setRange(Range); 02539 return nullptr; 02540 } 02541 } 02542 02543 return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, 02544 FirstArg, AttrSpellingListIndex); 02545 } 02546 02547 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on 02548 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 02549 static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02550 if (!Attr.isArgIdent(0)) { 02551 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 02552 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 02553 return; 02554 } 02555 02556 // In C++ the implicit 'this' function parameter also counts, and they are 02557 // counted from one. 02558 bool HasImplicitThisParam = isInstanceMethod(D); 02559 unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam; 02560 02561 IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; 02562 StringRef Format = II->getName(); 02563 02564 // Normalize the argument, __foo__ becomes foo. 02565 if (Format.startswith("__") && Format.endswith("__")) { 02566 Format = Format.substr(2, Format.size() - 4); 02567 // If we've modified the string name, we need a new identifier for it. 02568 II = &S.Context.Idents.get(Format); 02569 } 02570 02571 // Check for supported formats. 02572 FormatAttrKind Kind = getFormatAttrKind(Format); 02573 02574 if (Kind == IgnoredFormat) 02575 return; 02576 02577 if (Kind == InvalidFormat) { 02578 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 02579 << Attr.getName() << II->getName(); 02580 return; 02581 } 02582 02583 // checks for the 2nd argument 02584 Expr *IdxExpr = Attr.getArgAsExpr(1); 02585 uint32_t Idx; 02586 if (!checkUInt32Argument(S, Attr, IdxExpr, Idx, 2)) 02587 return; 02588 02589 if (Idx < 1 || Idx > NumArgs) { 02590 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 02591 << Attr.getName() << 2 << IdxExpr->getSourceRange(); 02592 return; 02593 } 02594 02595 // FIXME: Do we need to bounds check? 02596 unsigned ArgIdx = Idx - 1; 02597 02598 if (HasImplicitThisParam) { 02599 if (ArgIdx == 0) { 02600 S.Diag(Attr.getLoc(), 02601 diag::err_format_attribute_implicit_this_format_string) 02602 << IdxExpr->getSourceRange(); 02603 return; 02604 } 02605 ArgIdx--; 02606 } 02607 02608 // make sure the format string is really a string 02609 QualType Ty = getFunctionOrMethodParamType(D, ArgIdx); 02610 02611 if (Kind == CFStringFormat) { 02612 if (!isCFStringType(Ty, S.Context)) { 02613 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02614 << "a CFString" << IdxExpr->getSourceRange() 02615 << getFunctionOrMethodParamRange(D, ArgIdx); 02616 return; 02617 } 02618 } else if (Kind == NSStringFormat) { 02619 // FIXME: do we need to check if the type is NSString*? What are the 02620 // semantics? 02621 if (!isNSStringType(Ty, S.Context)) { 02622 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02623 << "an NSString" << IdxExpr->getSourceRange() 02624 << getFunctionOrMethodParamRange(D, ArgIdx); 02625 return; 02626 } 02627 } else if (!Ty->isPointerType() || 02628 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 02629 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02630 << "a string type" << IdxExpr->getSourceRange() 02631 << getFunctionOrMethodParamRange(D, ArgIdx); 02632 return; 02633 } 02634 02635 // check the 3rd argument 02636 Expr *FirstArgExpr = Attr.getArgAsExpr(2); 02637 uint32_t FirstArg; 02638 if (!checkUInt32Argument(S, Attr, FirstArgExpr, FirstArg, 3)) 02639 return; 02640 02641 // check if the function is variadic if the 3rd argument non-zero 02642 if (FirstArg != 0) { 02643 if (isFunctionOrMethodVariadic(D)) { 02644 ++NumArgs; // +1 for ... 02645 } else { 02646 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 02647 return; 02648 } 02649 } 02650 02651 // strftime requires FirstArg to be 0 because it doesn't read from any 02652 // variable the input is just the current time + the format string. 02653 if (Kind == StrftimeFormat) { 02654 if (FirstArg != 0) { 02655 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 02656 << FirstArgExpr->getSourceRange(); 02657 return; 02658 } 02659 // if 0 it disables parameter checking (to use with e.g. va_list) 02660 } else if (FirstArg != 0 && FirstArg != NumArgs) { 02661 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 02662 << Attr.getName() << 3 << FirstArgExpr->getSourceRange(); 02663 return; 02664 } 02665 02666 FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II, 02667 Idx, FirstArg, 02668 Attr.getAttributeSpellingListIndex()); 02669 if (NewAttr) 02670 D->addAttr(NewAttr); 02671 } 02672 02673 static void handleTransparentUnionAttr(Sema &S, Decl *D, 02674 const AttributeList &Attr) { 02675 // Try to find the underlying union declaration. 02676 RecordDecl *RD = nullptr; 02677 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 02678 if (TD && TD->getUnderlyingType()->isUnionType()) 02679 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 02680 else 02681 RD = dyn_cast<RecordDecl>(D); 02682 02683 if (!RD || !RD->isUnion()) { 02684 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02685 << Attr.getName() << ExpectedUnion; 02686 return; 02687 } 02688 02689 if (!RD->isCompleteDefinition()) { 02690 S.Diag(Attr.getLoc(), 02691 diag::warn_transparent_union_attribute_not_definition); 02692 return; 02693 } 02694 02695 RecordDecl::field_iterator Field = RD->field_begin(), 02696 FieldEnd = RD->field_end(); 02697 if (Field == FieldEnd) { 02698 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 02699 return; 02700 } 02701 02702 FieldDecl *FirstField = *Field; 02703 QualType FirstType = FirstField->getType(); 02704 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 02705 S.Diag(FirstField->getLocation(), 02706 diag::warn_transparent_union_attribute_floating) 02707 << FirstType->isVectorType() << FirstType; 02708 return; 02709 } 02710 02711 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 02712 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 02713 for (; Field != FieldEnd; ++Field) { 02714 QualType FieldType = Field->getType(); 02715 // FIXME: this isn't fully correct; we also need to test whether the 02716 // members of the union would all have the same calling convention as the 02717 // first member of the union. Checking just the size and alignment isn't 02718 // sufficient (consider structs passed on the stack instead of in registers 02719 // as an example). 02720 if (S.Context.getTypeSize(FieldType) != FirstSize || 02721 S.Context.getTypeAlign(FieldType) > FirstAlign) { 02722 // Warn if we drop the attribute. 02723 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 02724 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 02725 : S.Context.getTypeAlign(FieldType); 02726 S.Diag(Field->getLocation(), 02727 diag::warn_transparent_union_attribute_field_size_align) 02728 << isSize << Field->getDeclName() << FieldBits; 02729 unsigned FirstBits = isSize? FirstSize : FirstAlign; 02730 S.Diag(FirstField->getLocation(), 02731 diag::note_transparent_union_first_field_size_align) 02732 << isSize << FirstBits; 02733 return; 02734 } 02735 } 02736 02737 RD->addAttr(::new (S.Context) 02738 TransparentUnionAttr(Attr.getRange(), S.Context, 02739 Attr.getAttributeSpellingListIndex())); 02740 } 02741 02742 static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02743 // Make sure that there is a string literal as the annotation's single 02744 // argument. 02745 StringRef Str; 02746 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 02747 return; 02748 02749 // Don't duplicate annotations that are already set. 02750 for (const auto *I : D->specific_attrs<AnnotateAttr>()) { 02751 if (I->getAnnotation() == Str) 02752 return; 02753 } 02754 02755 D->addAttr(::new (S.Context) 02756 AnnotateAttr(Attr.getRange(), S.Context, Str, 02757 Attr.getAttributeSpellingListIndex())); 02758 } 02759 02760 static void handleAlignValueAttr(Sema &S, Decl *D, 02761 const AttributeList &Attr) { 02762 S.AddAlignValueAttr(Attr.getRange(), D, Attr.getArgAsExpr(0), 02763 Attr.getAttributeSpellingListIndex()); 02764 } 02765 02766 void Sema::AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, 02767 unsigned SpellingListIndex) { 02768 AlignValueAttr TmpAttr(AttrRange, Context, E, SpellingListIndex); 02769 SourceLocation AttrLoc = AttrRange.getBegin(); 02770 02771 QualType T; 02772 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 02773 T = TD->getUnderlyingType(); 02774 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 02775 T = VD->getType(); 02776 else 02777 llvm_unreachable("Unknown decl type for align_value"); 02778 02779 if (!T->isDependentType() && !T->isAnyPointerType() && 02780 !T->isReferenceType() && !T->isMemberPointerType()) { 02781 Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only) 02782 << &TmpAttr /*TmpAttr.getName()*/ << T << D->getSourceRange(); 02783 return; 02784 } 02785 02786 if (!E->isValueDependent()) { 02787 llvm::APSInt Alignment(32); 02788 ExprResult ICE 02789 = VerifyIntegerConstantExpression(E, &Alignment, 02790 diag::err_align_value_attribute_argument_not_int, 02791 /*AllowFold*/ false); 02792 if (ICE.isInvalid()) 02793 return; 02794 02795 if (!Alignment.isPowerOf2()) { 02796 Diag(AttrLoc, diag::err_alignment_not_power_of_two) 02797 << E->getSourceRange(); 02798 return; 02799 } 02800 02801 D->addAttr(::new (Context) 02802 AlignValueAttr(AttrRange, Context, ICE.get(), 02803 SpellingListIndex)); 02804 return; 02805 } 02806 02807 // Save dependent expressions in the AST to be instantiated. 02808 D->addAttr(::new (Context) AlignValueAttr(TmpAttr)); 02809 return; 02810 } 02811 02812 static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02813 // check the attribute arguments. 02814 if (Attr.getNumArgs() > 1) { 02815 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 02816 << Attr.getName() << 1; 02817 return; 02818 } 02819 02820 if (Attr.getNumArgs() == 0) { 02821 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, 02822 true, nullptr, Attr.getAttributeSpellingListIndex())); 02823 return; 02824 } 02825 02826 Expr *E = Attr.getArgAsExpr(0); 02827 if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) { 02828 S.Diag(Attr.getEllipsisLoc(), 02829 diag::err_pack_expansion_without_parameter_packs); 02830 return; 02831 } 02832 02833 if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E)) 02834 return; 02835 02836 S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(), 02837 Attr.isPackExpansion()); 02838 } 02839 02840 void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 02841 unsigned SpellingListIndex, bool IsPackExpansion) { 02842 AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex); 02843 SourceLocation AttrLoc = AttrRange.getBegin(); 02844 02845 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements. 02846 if (TmpAttr.isAlignas()) { 02847 // C++11 [dcl.align]p1: 02848 // An alignment-specifier may be applied to a variable or to a class 02849 // data member, but it shall not be applied to a bit-field, a function 02850 // parameter, the formal parameter of a catch clause, or a variable 02851 // declared with the register storage class specifier. An 02852 // alignment-specifier may also be applied to the declaration of a class 02853 // or enumeration type. 02854 // C11 6.7.5/2: 02855 // An alignment attribute shall not be specified in a declaration of 02856 // a typedef, or a bit-field, or a function, or a parameter, or an 02857 // object declared with the register storage-class specifier. 02858 int DiagKind = -1; 02859 if (isa<ParmVarDecl>(D)) { 02860 DiagKind = 0; 02861 } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 02862 if (VD->getStorageClass() == SC_Register) 02863 DiagKind = 1; 02864 if (VD->isExceptionVariable()) 02865 DiagKind = 2; 02866 } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 02867 if (FD->isBitField()) 02868 DiagKind = 3; 02869 } else if (!isa<TagDecl>(D)) { 02870 Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr 02871 << (TmpAttr.isC11() ? ExpectedVariableOrField 02872 : ExpectedVariableFieldOrTag); 02873 return; 02874 } 02875 if (DiagKind != -1) { 02876 Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type) 02877 << &TmpAttr << DiagKind; 02878 return; 02879 } 02880 } 02881 02882 if (E->isTypeDependent() || E->isValueDependent()) { 02883 // Save dependent expressions in the AST to be instantiated. 02884 AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr); 02885 AA->setPackExpansion(IsPackExpansion); 02886 D->addAttr(AA); 02887 return; 02888 } 02889 02890 // FIXME: Cache the number on the Attr object? 02891 llvm::APSInt Alignment(32); 02892 ExprResult ICE 02893 = VerifyIntegerConstantExpression(E, &Alignment, 02894 diag::err_aligned_attribute_argument_not_int, 02895 /*AllowFold*/ false); 02896 if (ICE.isInvalid()) 02897 return; 02898 02899 // C++11 [dcl.align]p2: 02900 // -- if the constant expression evaluates to zero, the alignment 02901 // specifier shall have no effect 02902 // C11 6.7.5p6: 02903 // An alignment specification of zero has no effect. 02904 if (!(TmpAttr.isAlignas() && !Alignment) && 02905 !llvm::isPowerOf2_64(Alignment.getZExtValue())) { 02906 Diag(AttrLoc, diag::err_alignment_not_power_of_two) 02907 << E->getSourceRange(); 02908 return; 02909 } 02910 02911 // Alignment calculations can wrap around if it's greater than 2**28. 02912 unsigned MaxValidAlignment = TmpAttr.isDeclspec() ? 8192 : 268435456; 02913 if (Alignment.getZExtValue() > MaxValidAlignment) { 02914 Diag(AttrLoc, diag::err_attribute_aligned_too_great) << MaxValidAlignment 02915 << E->getSourceRange(); 02916 return; 02917 } 02918 02919 AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true, 02920 ICE.get(), SpellingListIndex); 02921 AA->setPackExpansion(IsPackExpansion); 02922 D->addAttr(AA); 02923 } 02924 02925 void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, 02926 unsigned SpellingListIndex, bool IsPackExpansion) { 02927 // FIXME: Cache the number on the Attr object if non-dependent? 02928 // FIXME: Perform checking of type validity 02929 AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS, 02930 SpellingListIndex); 02931 AA->setPackExpansion(IsPackExpansion); 02932 D->addAttr(AA); 02933 } 02934 02935 void Sema::CheckAlignasUnderalignment(Decl *D) { 02936 assert(D->hasAttrs() && "no attributes on decl"); 02937 02938 QualType Ty; 02939 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 02940 Ty = VD->getType(); 02941 else 02942 Ty = Context.getTagDeclType(cast<TagDecl>(D)); 02943 if (Ty->isDependentType() || Ty->isIncompleteType()) 02944 return; 02945 02946 // C++11 [dcl.align]p5, C11 6.7.5/4: 02947 // The combined effect of all alignment attributes in a declaration shall 02948 // not specify an alignment that is less strict than the alignment that 02949 // would otherwise be required for the entity being declared. 02950 AlignedAttr *AlignasAttr = nullptr; 02951 unsigned Align = 0; 02952 for (auto *I : D->specific_attrs<AlignedAttr>()) { 02953 if (I->isAlignmentDependent()) 02954 return; 02955 if (I->isAlignas()) 02956 AlignasAttr = I; 02957 Align = std::max(Align, I->getAlignment(Context)); 02958 } 02959 02960 if (AlignasAttr && Align) { 02961 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align); 02962 CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty); 02963 if (NaturalAlign > RequestedAlign) 02964 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned) 02965 << Ty << (unsigned)NaturalAlign.getQuantity(); 02966 } 02967 } 02968 02969 bool Sema::checkMSInheritanceAttrOnDefinition( 02970 CXXRecordDecl *RD, SourceRange Range, bool BestCase, 02971 MSInheritanceAttr::Spelling SemanticSpelling) { 02972 assert(RD->hasDefinition() && "RD has no definition!"); 02973 02974 // We may not have seen base specifiers or any virtual methods yet. We will 02975 // have to wait until the record is defined to catch any mismatches. 02976 if (!RD->getDefinition()->isCompleteDefinition()) 02977 return false; 02978 02979 // The unspecified model never matches what a definition could need. 02980 if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) 02981 return false; 02982 02983 if (BestCase) { 02984 if (RD->calculateInheritanceModel() == SemanticSpelling) 02985 return false; 02986 } else { 02987 if (RD->calculateInheritanceModel() <= SemanticSpelling) 02988 return false; 02989 } 02990 02991 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) 02992 << 0 /*definition*/; 02993 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) 02994 << RD->getNameAsString(); 02995 return true; 02996 } 02997 02998 /// handleModeAttr - This attribute modifies the width of a decl with primitive 02999 /// type. 03000 /// 03001 /// Despite what would be logical, the mode attribute is a decl attribute, not a 03002 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 03003 /// HImode, not an intermediate pointer. 03004 static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03005 // This attribute isn't documented, but glibc uses it. It changes 03006 // the width of an int or unsigned int to the specified size. 03007 if (!Attr.isArgIdent(0)) { 03008 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() 03009 << AANT_ArgumentIdentifier; 03010 return; 03011 } 03012 03013 IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident; 03014 StringRef Str = Name->getName(); 03015 03016 // Normalize the attribute name, __foo__ becomes foo. 03017 if (Str.startswith("__") && Str.endswith("__")) 03018 Str = Str.substr(2, Str.size() - 4); 03019 03020 unsigned DestWidth = 0; 03021 bool IntegerMode = true; 03022 bool ComplexMode = false; 03023 switch (Str.size()) { 03024 case 2: 03025 switch (Str[0]) { 03026 case 'Q': DestWidth = 8; break; 03027 case 'H': DestWidth = 16; break; 03028 case 'S': DestWidth = 32; break; 03029 case 'D': DestWidth = 64; break; 03030 case 'X': DestWidth = 96; break; 03031 case 'T': DestWidth = 128; break; 03032 } 03033 if (Str[1] == 'F') { 03034 IntegerMode = false; 03035 } else if (Str[1] == 'C') { 03036 IntegerMode = false; 03037 ComplexMode = true; 03038 } else if (Str[1] != 'I') { 03039 DestWidth = 0; 03040 } 03041 break; 03042 case 4: 03043 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 03044 // pointer on PIC16 and other embedded platforms. 03045 if (Str == "word") 03046 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 03047 else if (Str == "byte") 03048 DestWidth = S.Context.getTargetInfo().getCharWidth(); 03049 break; 03050 case 7: 03051 if (Str == "pointer") 03052 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 03053 break; 03054 case 11: 03055 if (Str == "unwind_word") 03056 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth(); 03057 break; 03058 } 03059 03060 QualType OldTy; 03061 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 03062 OldTy = TD->getUnderlyingType(); 03063 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 03064 OldTy = VD->getType(); 03065 else { 03066 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 03067 << Attr.getName() << Attr.getRange(); 03068 return; 03069 } 03070 03071 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 03072 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 03073 else if (IntegerMode) { 03074 if (!OldTy->isIntegralOrEnumerationType()) 03075 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 03076 } else if (ComplexMode) { 03077 if (!OldTy->isComplexType()) 03078 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 03079 } else { 03080 if (!OldTy->isFloatingType()) 03081 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 03082 } 03083 03084 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 03085 // and friends, at least with glibc. 03086 // FIXME: Make sure floating-point mappings are accurate 03087 // FIXME: Support XF and TF types 03088 if (!DestWidth) { 03089 S.Diag(Attr.getLoc(), diag::err_machine_mode) << 0 /*Unknown*/ << Name; 03090 return; 03091 } 03092 03093 QualType NewTy; 03094 03095 if (IntegerMode) 03096 NewTy = S.Context.getIntTypeForBitwidth(DestWidth, 03097 OldTy->isSignedIntegerType()); 03098 else 03099 NewTy = S.Context.getRealTypeForBitwidth(DestWidth); 03100 03101 if (NewTy.isNull()) { 03102 S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name; 03103 return; 03104 } 03105 03106 if (ComplexMode) { 03107 NewTy = S.Context.getComplexType(NewTy); 03108 } 03109 03110 // Install the new type. 03111 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 03112 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy); 03113 else 03114 cast<ValueDecl>(D)->setType(NewTy); 03115 03116 D->addAttr(::new (S.Context) 03117 ModeAttr(Attr.getRange(), S.Context, Name, 03118 Attr.getAttributeSpellingListIndex())); 03119 } 03120 03121 static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03122 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 03123 if (!VD->hasGlobalStorage()) 03124 S.Diag(Attr.getLoc(), 03125 diag::warn_attribute_requires_functions_or_static_globals) 03126 << Attr.getName(); 03127 } else if (!isFunctionOrMethod(D)) { 03128 S.Diag(Attr.getLoc(), 03129 diag::warn_attribute_requires_functions_or_static_globals) 03130 << Attr.getName(); 03131 return; 03132 } 03133 03134 D->addAttr(::new (S.Context) 03135 NoDebugAttr(Attr.getRange(), S.Context, 03136 Attr.getAttributeSpellingListIndex())); 03137 } 03138 03139 static void handleAlwaysInlineAttr(Sema &S, Decl *D, 03140 const AttributeList &Attr) { 03141 if (checkAttrMutualExclusion<OptimizeNoneAttr>(S, D, Attr)) 03142 return; 03143 03144 D->addAttr(::new (S.Context) 03145 AlwaysInlineAttr(Attr.getRange(), S.Context, 03146 Attr.getAttributeSpellingListIndex())); 03147 } 03148 03149 static void handleOptimizeNoneAttr(Sema &S, Decl *D, 03150 const AttributeList &Attr) { 03151 if (checkAttrMutualExclusion<AlwaysInlineAttr>(S, D, Attr)) 03152 return; 03153 03154 D->addAttr(::new (S.Context) 03155 OptimizeNoneAttr(Attr.getRange(), S.Context, 03156 Attr.getAttributeSpellingListIndex())); 03157 } 03158 03159 static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03160 FunctionDecl *FD = cast<FunctionDecl>(D); 03161 if (!FD->getReturnType()->isVoidType()) { 03162 SourceRange RTRange = FD->getReturnTypeSourceRange(); 03163 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 03164 << FD->getType() 03165 << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void") 03166 : FixItHint()); 03167 return; 03168 } 03169 03170 D->addAttr(::new (S.Context) 03171 CUDAGlobalAttr(Attr.getRange(), S.Context, 03172 Attr.getAttributeSpellingListIndex())); 03173 } 03174 03175 static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03176 FunctionDecl *Fn = cast<FunctionDecl>(D); 03177 if (!Fn->isInlineSpecified()) { 03178 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 03179 return; 03180 } 03181 03182 D->addAttr(::new (S.Context) 03183 GNUInlineAttr(Attr.getRange(), S.Context, 03184 Attr.getAttributeSpellingListIndex())); 03185 } 03186 03187 static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03188 if (hasDeclarator(D)) return; 03189 03190 const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 03191 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 03192 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 03193 CallingConv CC; 03194 if (S.CheckCallingConvAttr(Attr, CC, FD)) 03195 return; 03196 03197 if (!isa<ObjCMethodDecl>(D)) { 03198 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03199 << Attr.getName() << ExpectedFunctionOrMethod; 03200 return; 03201 } 03202 03203 switch (Attr.getKind()) { 03204 case AttributeList::AT_FastCall: 03205 D->addAttr(::new (S.Context) 03206 FastCallAttr(Attr.getRange(), S.Context, 03207 Attr.getAttributeSpellingListIndex())); 03208 return; 03209 case AttributeList::AT_StdCall: 03210 D->addAttr(::new (S.Context) 03211 StdCallAttr(Attr.getRange(), S.Context, 03212 Attr.getAttributeSpellingListIndex())); 03213 return; 03214 case AttributeList::AT_ThisCall: 03215 D->addAttr(::new (S.Context) 03216 ThisCallAttr(Attr.getRange(), S.Context, 03217 Attr.getAttributeSpellingListIndex())); 03218 return; 03219 case AttributeList::AT_CDecl: 03220 D->addAttr(::new (S.Context) 03221 CDeclAttr(Attr.getRange(), S.Context, 03222 Attr.getAttributeSpellingListIndex())); 03223 return; 03224 case AttributeList::AT_Pascal: 03225 D->addAttr(::new (S.Context) 03226 PascalAttr(Attr.getRange(), S.Context, 03227 Attr.getAttributeSpellingListIndex())); 03228 return; 03229 case AttributeList::AT_VectorCall: 03230 D->addAttr(::new (S.Context) 03231 VectorCallAttr(Attr.getRange(), S.Context, 03232 Attr.getAttributeSpellingListIndex())); 03233 return; 03234 case AttributeList::AT_MSABI: 03235 D->addAttr(::new (S.Context) 03236 MSABIAttr(Attr.getRange(), S.Context, 03237 Attr.getAttributeSpellingListIndex())); 03238 return; 03239 case AttributeList::AT_SysVABI: 03240 D->addAttr(::new (S.Context) 03241 SysVABIAttr(Attr.getRange(), S.Context, 03242 Attr.getAttributeSpellingListIndex())); 03243 return; 03244 case AttributeList::AT_Pcs: { 03245 PcsAttr::PCSType PCS; 03246 switch (CC) { 03247 case CC_AAPCS: 03248 PCS = PcsAttr::AAPCS; 03249 break; 03250 case CC_AAPCS_VFP: 03251 PCS = PcsAttr::AAPCS_VFP; 03252 break; 03253 default: 03254 llvm_unreachable("unexpected calling convention in pcs attribute"); 03255 } 03256 03257 D->addAttr(::new (S.Context) 03258 PcsAttr(Attr.getRange(), S.Context, PCS, 03259 Attr.getAttributeSpellingListIndex())); 03260 return; 03261 } 03262 case AttributeList::AT_PnaclCall: 03263 D->addAttr(::new (S.Context) 03264 PnaclCallAttr(Attr.getRange(), S.Context, 03265 Attr.getAttributeSpellingListIndex())); 03266 return; 03267 case AttributeList::AT_IntelOclBicc: 03268 D->addAttr(::new (S.Context) 03269 IntelOclBiccAttr(Attr.getRange(), S.Context, 03270 Attr.getAttributeSpellingListIndex())); 03271 return; 03272 03273 default: 03274 llvm_unreachable("unexpected attribute kind"); 03275 } 03276 } 03277 03278 bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 03279 const FunctionDecl *FD) { 03280 if (attr.isInvalid()) 03281 return true; 03282 03283 unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0; 03284 if (!checkAttributeNumArgs(*this, attr, ReqArgs)) { 03285 attr.setInvalid(); 03286 return true; 03287 } 03288 03289 // TODO: diagnose uses of these conventions on the wrong target. 03290 switch (attr.getKind()) { 03291 case AttributeList::AT_CDecl: CC = CC_C; break; 03292 case AttributeList::AT_FastCall: CC = CC_X86FastCall; break; 03293 case AttributeList::AT_StdCall: CC = CC_X86StdCall; break; 03294 case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break; 03295 case AttributeList::AT_Pascal: CC = CC_X86Pascal; break; 03296 case AttributeList::AT_VectorCall: CC = CC_X86VectorCall; break; 03297 case AttributeList::AT_MSABI: 03298 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C : 03299 CC_X86_64Win64; 03300 break; 03301 case AttributeList::AT_SysVABI: 03302 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV : 03303 CC_C; 03304 break; 03305 case AttributeList::AT_Pcs: { 03306 StringRef StrRef; 03307 if (!checkStringLiteralArgumentAttr(attr, 0, StrRef)) { 03308 attr.setInvalid(); 03309 return true; 03310 } 03311 if (StrRef == "aapcs") { 03312 CC = CC_AAPCS; 03313 break; 03314 } else if (StrRef == "aapcs-vfp") { 03315 CC = CC_AAPCS_VFP; 03316 break; 03317 } 03318 03319 attr.setInvalid(); 03320 Diag(attr.getLoc(), diag::err_invalid_pcs); 03321 return true; 03322 } 03323 case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break; 03324 case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break; 03325 default: llvm_unreachable("unexpected attribute kind"); 03326 } 03327 03328 const TargetInfo &TI = Context.getTargetInfo(); 03329 TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); 03330 if (A == TargetInfo::CCCR_Warning) { 03331 Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); 03332 03333 TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown; 03334 if (FD) 03335 MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member : 03336 TargetInfo::CCMT_NonMember; 03337 CC = TI.getDefaultCallingConv(MT); 03338 } 03339 03340 return false; 03341 } 03342 03343 /// Checks a regparm attribute, returning true if it is ill-formed and 03344 /// otherwise setting numParams to the appropriate value. 03345 bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 03346 if (Attr.isInvalid()) 03347 return true; 03348 03349 if (!checkAttributeNumArgs(*this, Attr, 1)) { 03350 Attr.setInvalid(); 03351 return true; 03352 } 03353 03354 uint32_t NP; 03355 Expr *NumParamsExpr = Attr.getArgAsExpr(0); 03356 if (!checkUInt32Argument(*this, Attr, NumParamsExpr, NP)) { 03357 Attr.setInvalid(); 03358 return true; 03359 } 03360 03361 if (Context.getTargetInfo().getRegParmMax() == 0) { 03362 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 03363 << NumParamsExpr->getSourceRange(); 03364 Attr.setInvalid(); 03365 return true; 03366 } 03367 03368 numParams = NP; 03369 if (numParams > Context.getTargetInfo().getRegParmMax()) { 03370 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 03371 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 03372 Attr.setInvalid(); 03373 return true; 03374 } 03375 03376 return false; 03377 } 03378 03379 static void handleLaunchBoundsAttr(Sema &S, Decl *D, 03380 const AttributeList &Attr) { 03381 uint32_t MaxThreads, MinBlocks = 0; 03382 if (!checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), MaxThreads, 1)) 03383 return; 03384 if (Attr.getNumArgs() > 1 && !checkUInt32Argument(S, Attr, 03385 Attr.getArgAsExpr(1), 03386 MinBlocks, 2)) 03387 return; 03388 03389 D->addAttr(::new (S.Context) 03390 CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 03391 MaxThreads, MinBlocks, 03392 Attr.getAttributeSpellingListIndex())); 03393 } 03394 03395 static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, 03396 const AttributeList &Attr) { 03397 if (!Attr.isArgIdent(0)) { 03398 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 03399 << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier; 03400 return; 03401 } 03402 03403 if (!checkAttributeNumArgs(S, Attr, 3)) 03404 return; 03405 03406 IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident; 03407 03408 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 03409 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 03410 << Attr.getName() << ExpectedFunctionOrMethod; 03411 return; 03412 } 03413 03414 uint64_t ArgumentIdx; 03415 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 2, Attr.getArgAsExpr(1), 03416 ArgumentIdx)) 03417 return; 03418 03419 uint64_t TypeTagIdx; 03420 if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 3, Attr.getArgAsExpr(2), 03421 TypeTagIdx)) 03422 return; 03423 03424 bool IsPointer = (Attr.getName()->getName() == "pointer_with_type_tag"); 03425 if (IsPointer) { 03426 // Ensure that buffer has a pointer type. 03427 QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx); 03428 if (!BufferTy->isPointerType()) { 03429 S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only) 03430 << Attr.getName(); 03431 } 03432 } 03433 03434 D->addAttr(::new (S.Context) 03435 ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind, 03436 ArgumentIdx, TypeTagIdx, IsPointer, 03437 Attr.getAttributeSpellingListIndex())); 03438 } 03439 03440 static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, 03441 const AttributeList &Attr) { 03442 if (!Attr.isArgIdent(0)) { 03443 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 03444 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 03445 return; 03446 } 03447 03448 if (!checkAttributeNumArgs(S, Attr, 1)) 03449 return; 03450 03451 if (!isa<VarDecl>(D)) { 03452 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 03453 << Attr.getName() << ExpectedVariable; 03454 return; 03455 } 03456 03457 IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident; 03458 TypeSourceInfo *MatchingCTypeLoc = nullptr; 03459 S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc); 03460 assert(MatchingCTypeLoc && "no type source info for attribute argument"); 03461 03462 D->addAttr(::new (S.Context) 03463 TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind, 03464 MatchingCTypeLoc, 03465 Attr.getLayoutCompatible(), 03466 Attr.getMustBeNull(), 03467 Attr.getAttributeSpellingListIndex())); 03468 } 03469 03470 //===----------------------------------------------------------------------===// 03471 // Checker-specific attribute handlers. 03472 //===----------------------------------------------------------------------===// 03473 03474 static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType type) { 03475 return type->isDependentType() || 03476 type->isObjCRetainableType(); 03477 } 03478 03479 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 03480 return type->isDependentType() || 03481 type->isObjCObjectPointerType() || 03482 S.Context.isObjCNSObjectType(type); 03483 } 03484 static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 03485 return type->isDependentType() || 03486 type->isPointerType() || 03487 isValidSubjectOfNSAttribute(S, type); 03488 } 03489 03490 static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03491 ParmVarDecl *param = cast<ParmVarDecl>(D); 03492 bool typeOK, cf; 03493 03494 if (Attr.getKind() == AttributeList::AT_NSConsumed) { 03495 typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 03496 cf = false; 03497 } else { 03498 typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 03499 cf = true; 03500 } 03501 03502 if (!typeOK) { 03503 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 03504 << Attr.getRange() << Attr.getName() << cf; 03505 return; 03506 } 03507 03508 if (cf) 03509 param->addAttr(::new (S.Context) 03510 CFConsumedAttr(Attr.getRange(), S.Context, 03511 Attr.getAttributeSpellingListIndex())); 03512 else 03513 param->addAttr(::new (S.Context) 03514 NSConsumedAttr(Attr.getRange(), S.Context, 03515 Attr.getAttributeSpellingListIndex())); 03516 } 03517 03518 static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 03519 const AttributeList &Attr) { 03520 03521 QualType returnType; 03522 03523 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 03524 returnType = MD->getReturnType(); 03525 else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 03526 (Attr.getKind() == AttributeList::AT_NSReturnsRetained)) 03527 return; // ignore: was handled as a type attribute 03528 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 03529 returnType = PD->getType(); 03530 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 03531 returnType = FD->getReturnType(); 03532 else { 03533 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 03534 << Attr.getRange() << Attr.getName() 03535 << ExpectedFunctionOrMethod; 03536 return; 03537 } 03538 03539 bool typeOK; 03540 bool cf; 03541 switch (Attr.getKind()) { 03542 default: llvm_unreachable("invalid ownership attribute"); 03543 case AttributeList::AT_NSReturnsRetained: 03544 typeOK = isValidSubjectOfNSReturnsRetainedAttribute(returnType); 03545 cf = false; 03546 break; 03547 03548 case AttributeList::AT_NSReturnsAutoreleased: 03549 case AttributeList::AT_NSReturnsNotRetained: 03550 typeOK = isValidSubjectOfNSAttribute(S, returnType); 03551 cf = false; 03552 break; 03553 03554 case AttributeList::AT_CFReturnsRetained: 03555 case AttributeList::AT_CFReturnsNotRetained: 03556 typeOK = isValidSubjectOfCFAttribute(S, returnType); 03557 cf = true; 03558 break; 03559 } 03560 03561 if (!typeOK) { 03562 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 03563 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 03564 return; 03565 } 03566 03567 switch (Attr.getKind()) { 03568 default: 03569 llvm_unreachable("invalid ownership attribute"); 03570 case AttributeList::AT_NSReturnsAutoreleased: 03571 D->addAttr(::new (S.Context) 03572 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context, 03573 Attr.getAttributeSpellingListIndex())); 03574 return; 03575 case AttributeList::AT_CFReturnsNotRetained: 03576 D->addAttr(::new (S.Context) 03577 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context, 03578 Attr.getAttributeSpellingListIndex())); 03579 return; 03580 case AttributeList::AT_NSReturnsNotRetained: 03581 D->addAttr(::new (S.Context) 03582 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context, 03583 Attr.getAttributeSpellingListIndex())); 03584 return; 03585 case AttributeList::AT_CFReturnsRetained: 03586 D->addAttr(::new (S.Context) 03587 CFReturnsRetainedAttr(Attr.getRange(), S.Context, 03588 Attr.getAttributeSpellingListIndex())); 03589 return; 03590 case AttributeList::AT_NSReturnsRetained: 03591 D->addAttr(::new (S.Context) 03592 NSReturnsRetainedAttr(Attr.getRange(), S.Context, 03593 Attr.getAttributeSpellingListIndex())); 03594 return; 03595 }; 03596 } 03597 03598 static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 03599 const AttributeList &attr) { 03600 const int EP_ObjCMethod = 1; 03601 const int EP_ObjCProperty = 2; 03602 03603 SourceLocation loc = attr.getLoc(); 03604 QualType resultType; 03605 if (isa<ObjCMethodDecl>(D)) 03606 resultType = cast<ObjCMethodDecl>(D)->getReturnType(); 03607 else 03608 resultType = cast<ObjCPropertyDecl>(D)->getType(); 03609 03610 if (!resultType->isReferenceType() && 03611 (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 03612 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 03613 << SourceRange(loc) 03614 << attr.getName() 03615 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty) 03616 << /*non-retainable pointer*/ 2; 03617 03618 // Drop the attribute. 03619 return; 03620 } 03621 03622 D->addAttr(::new (S.Context) 03623 ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context, 03624 attr.getAttributeSpellingListIndex())); 03625 } 03626 03627 static void handleObjCRequiresSuperAttr(Sema &S, Decl *D, 03628 const AttributeList &attr) { 03629 ObjCMethodDecl *method = cast<ObjCMethodDecl>(D); 03630 03631 DeclContext *DC = method->getDeclContext(); 03632 if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) { 03633 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 03634 << attr.getName() << 0; 03635 S.Diag(PDecl->getLocation(), diag::note_protocol_decl); 03636 return; 03637 } 03638 if (method->getMethodFamily() == OMF_dealloc) { 03639 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 03640 << attr.getName() << 1; 03641 return; 03642 } 03643 03644 method->addAttr(::new (S.Context) 03645 ObjCRequiresSuperAttr(attr.getRange(), S.Context, 03646 attr.getAttributeSpellingListIndex())); 03647 } 03648 03649 static void handleCFAuditedTransferAttr(Sema &S, Decl *D, 03650 const AttributeList &Attr) { 03651 if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr)) 03652 return; 03653 03654 D->addAttr(::new (S.Context) 03655 CFAuditedTransferAttr(Attr.getRange(), S.Context, 03656 Attr.getAttributeSpellingListIndex())); 03657 } 03658 03659 static void handleCFUnknownTransferAttr(Sema &S, Decl *D, 03660 const AttributeList &Attr) { 03661 if (checkAttrMutualExclusion<CFAuditedTransferAttr>(S, D, Attr)) 03662 return; 03663 03664 D->addAttr(::new (S.Context) 03665 CFUnknownTransferAttr(Attr.getRange(), S.Context, 03666 Attr.getAttributeSpellingListIndex())); 03667 } 03668 03669 static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D, 03670 const AttributeList &Attr) { 03671 IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr; 03672 03673 if (!Parm) { 03674 S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; 03675 return; 03676 } 03677 03678 D->addAttr(::new (S.Context) 03679 ObjCBridgeAttr(Attr.getRange(), S.Context, Parm->Ident, 03680 Attr.getAttributeSpellingListIndex())); 03681 } 03682 03683 static void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D, 03684 const AttributeList &Attr) { 03685 IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr; 03686 03687 if (!Parm) { 03688 S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; 03689 return; 03690 } 03691 03692 D->addAttr(::new (S.Context) 03693 ObjCBridgeMutableAttr(Attr.getRange(), S.Context, Parm->Ident, 03694 Attr.getAttributeSpellingListIndex())); 03695 } 03696 03697 static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D, 03698 const AttributeList &Attr) { 03699 IdentifierInfo *RelatedClass = 03700 Attr.isArgIdent(0) ? Attr.getArgAsIdent(0)->Ident : nullptr; 03701 if (!RelatedClass) { 03702 S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; 03703 return; 03704 } 03705 IdentifierInfo *ClassMethod = 03706 Attr.getArgAsIdent(1) ? Attr.getArgAsIdent(1)->Ident : nullptr; 03707 IdentifierInfo *InstanceMethod = 03708 Attr.getArgAsIdent(2) ? Attr.getArgAsIdent(2)->Ident : nullptr; 03709 D->addAttr(::new (S.Context) 03710 ObjCBridgeRelatedAttr(Attr.getRange(), S.Context, RelatedClass, 03711 ClassMethod, InstanceMethod, 03712 Attr.getAttributeSpellingListIndex())); 03713 } 03714 03715 static void handleObjCDesignatedInitializer(Sema &S, Decl *D, 03716 const AttributeList &Attr) { 03717 ObjCInterfaceDecl *IFace; 03718 if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) 03719 IFace = CatDecl->getClassInterface(); 03720 else 03721 IFace = cast<ObjCInterfaceDecl>(D->getDeclContext()); 03722 IFace->setHasDesignatedInitializers(); 03723 D->addAttr(::new (S.Context) 03724 ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context, 03725 Attr.getAttributeSpellingListIndex())); 03726 } 03727 03728 static void handleObjCRuntimeName(Sema &S, Decl *D, 03729 const AttributeList &Attr) { 03730 StringRef MetaDataName; 03731 if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName)) 03732 return; 03733 D->addAttr(::new (S.Context) 03734 ObjCRuntimeNameAttr(Attr.getRange(), S.Context, 03735 MetaDataName, 03736 Attr.getAttributeSpellingListIndex())); 03737 } 03738 03739 static void handleObjCOwnershipAttr(Sema &S, Decl *D, 03740 const AttributeList &Attr) { 03741 if (hasDeclarator(D)) return; 03742 03743 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 03744 << Attr.getRange() << Attr.getName() << ExpectedVariable; 03745 } 03746 03747 static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 03748 const AttributeList &Attr) { 03749 ValueDecl *vd = cast<ValueDecl>(D); 03750 QualType type = vd->getType(); 03751 03752 if (!type->isDependentType() && 03753 !type->isObjCLifetimeType()) { 03754 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 03755 << type; 03756 return; 03757 } 03758 03759 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 03760 03761 // If we have no lifetime yet, check the lifetime we're presumably 03762 // going to infer. 03763 if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 03764 lifetime = type->getObjCARCImplicitLifetime(); 03765 03766 switch (lifetime) { 03767 case Qualifiers::OCL_None: 03768 assert(type->isDependentType() && 03769 "didn't infer lifetime for non-dependent type?"); 03770 break; 03771 03772 case Qualifiers::OCL_Weak: // meaningful 03773 case Qualifiers::OCL_Strong: // meaningful 03774 break; 03775 03776 case Qualifiers::OCL_ExplicitNone: 03777 case Qualifiers::OCL_Autoreleasing: 03778 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 03779 << (lifetime == Qualifiers::OCL_Autoreleasing); 03780 break; 03781 } 03782 03783 D->addAttr(::new (S.Context) 03784 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context, 03785 Attr.getAttributeSpellingListIndex())); 03786 } 03787 03788 //===----------------------------------------------------------------------===// 03789 // Microsoft specific attribute handlers. 03790 //===----------------------------------------------------------------------===// 03791 03792 static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03793 if (!S.LangOpts.CPlusPlus) { 03794 S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) 03795 << Attr.getName() << AttributeLangSupport::C; 03796 return; 03797 } 03798 03799 if (!isa<CXXRecordDecl>(D)) { 03800 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03801 << Attr.getName() << ExpectedClass; 03802 return; 03803 } 03804 03805 StringRef StrRef; 03806 SourceLocation LiteralLoc; 03807 if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc)) 03808 return; 03809 03810 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 03811 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former. 03812 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}') 03813 StrRef = StrRef.drop_front().drop_back(); 03814 03815 // Validate GUID length. 03816 if (StrRef.size() != 36) { 03817 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 03818 return; 03819 } 03820 03821 for (unsigned i = 0; i < 36; ++i) { 03822 if (i == 8 || i == 13 || i == 18 || i == 23) { 03823 if (StrRef[i] != '-') { 03824 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 03825 return; 03826 } 03827 } else if (!isHexDigit(StrRef[i])) { 03828 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 03829 return; 03830 } 03831 } 03832 03833 D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef, 03834 Attr.getAttributeSpellingListIndex())); 03835 } 03836 03837 static void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03838 if (!S.LangOpts.CPlusPlus) { 03839 S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) 03840 << Attr.getName() << AttributeLangSupport::C; 03841 return; 03842 } 03843 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr( 03844 D, Attr.getRange(), /*BestCase=*/true, 03845 Attr.getAttributeSpellingListIndex(), 03846 (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling()); 03847 if (IA) 03848 D->addAttr(IA); 03849 } 03850 03851 static void handleDeclspecThreadAttr(Sema &S, Decl *D, 03852 const AttributeList &Attr) { 03853 VarDecl *VD = cast<VarDecl>(D); 03854 if (!S.Context.getTargetInfo().isTLSSupported()) { 03855 S.Diag(Attr.getLoc(), diag::err_thread_unsupported); 03856 return; 03857 } 03858 if (VD->getTSCSpec() != TSCS_unspecified) { 03859 S.Diag(Attr.getLoc(), diag::err_declspec_thread_on_thread_variable); 03860 return; 03861 } 03862 if (VD->hasLocalStorage()) { 03863 S.Diag(Attr.getLoc(), diag::err_thread_non_global) << "__declspec(thread)"; 03864 return; 03865 } 03866 VD->addAttr(::new (S.Context) ThreadAttr( 03867 Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 03868 } 03869 03870 static void handleARMInterruptAttr(Sema &S, Decl *D, 03871 const AttributeList &Attr) { 03872 // Check the attribute arguments. 03873 if (Attr.getNumArgs() > 1) { 03874 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) 03875 << Attr.getName() << 1; 03876 return; 03877 } 03878 03879 StringRef Str; 03880 SourceLocation ArgLoc; 03881 03882 if (Attr.getNumArgs() == 0) 03883 Str = ""; 03884 else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc)) 03885 return; 03886 03887 ARMInterruptAttr::InterruptType Kind; 03888 if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { 03889 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 03890 << Attr.getName() << Str << ArgLoc; 03891 return; 03892 } 03893 03894 unsigned Index = Attr.getAttributeSpellingListIndex(); 03895 D->addAttr(::new (S.Context) 03896 ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index)); 03897 } 03898 03899 static void handleMSP430InterruptAttr(Sema &S, Decl *D, 03900 const AttributeList &Attr) { 03901 if (!checkAttributeNumArgs(S, Attr, 1)) 03902 return; 03903 03904 if (!Attr.isArgExpr(0)) { 03905 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() 03906 << AANT_ArgumentIntegerConstant; 03907 return; 03908 } 03909 03910 // FIXME: Check for decl - it should be void ()(void). 03911 03912 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); 03913 llvm::APSInt NumParams(32); 03914 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 03915 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 03916 << Attr.getName() << AANT_ArgumentIntegerConstant 03917 << NumParamsExpr->getSourceRange(); 03918 return; 03919 } 03920 03921 unsigned Num = NumParams.getLimitedValue(255); 03922 if ((Num & 1) || Num > 30) { 03923 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 03924 << Attr.getName() << (int)NumParams.getSExtValue() 03925 << NumParamsExpr->getSourceRange(); 03926 return; 03927 } 03928 03929 D->addAttr(::new (S.Context) 03930 MSP430InterruptAttr(Attr.getLoc(), S.Context, Num, 03931 Attr.getAttributeSpellingListIndex())); 03932 D->addAttr(UsedAttr::CreateImplicit(S.Context)); 03933 } 03934 03935 static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03936 // Dispatch the interrupt attribute based on the current target. 03937 if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430) 03938 handleMSP430InterruptAttr(S, D, Attr); 03939 else 03940 handleARMInterruptAttr(S, D, Attr); 03941 } 03942 03943 static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, 03944 const AttributeList& Attr) { 03945 // If we try to apply it to a function pointer, don't warn, but don't 03946 // do anything, either. It doesn't matter anyway, because there's nothing 03947 // special about calling a force_align_arg_pointer function. 03948 ValueDecl *VD = dyn_cast<ValueDecl>(D); 03949 if (VD && VD->getType()->isFunctionPointerType()) 03950 return; 03951 // Also don't warn on function pointer typedefs. 03952 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 03953 if (TD && (TD->getUnderlyingType()->isFunctionPointerType() || 03954 TD->getUnderlyingType()->isFunctionType())) 03955 return; 03956 // Attribute can only be applied to function types. 03957 if (!isa<FunctionDecl>(D)) { 03958 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03959 << Attr.getName() << /* function */0; 03960 return; 03961 } 03962 03963 D->addAttr(::new (S.Context) 03964 X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context, 03965 Attr.getAttributeSpellingListIndex())); 03966 } 03967 03968 DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range, 03969 unsigned AttrSpellingListIndex) { 03970 if (D->hasAttr<DLLExportAttr>()) { 03971 Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'"; 03972 return nullptr; 03973 } 03974 03975 if (D->hasAttr<DLLImportAttr>()) 03976 return nullptr; 03977 03978 return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex); 03979 } 03980 03981 DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range, 03982 unsigned AttrSpellingListIndex) { 03983 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) { 03984 Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import; 03985 D->dropAttr<DLLImportAttr>(); 03986 } 03987 03988 if (D->hasAttr<DLLExportAttr>()) 03989 return nullptr; 03990 03991 return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex); 03992 } 03993 03994 static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) { 03995 if (isa<ClassTemplatePartialSpecializationDecl>(D) && 03996 S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { 03997 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) 03998 << A.getName(); 03999 return; 04000 } 04001 04002 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 04003 if (FD->isInlined() && A.getKind() == AttributeList::AT_DLLImport && 04004 !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { 04005 // MinGW doesn't allow dllimport on inline functions. 04006 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline) 04007 << A.getName(); 04008 return; 04009 } 04010 } 04011 04012 unsigned Index = A.getAttributeSpellingListIndex(); 04013 Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport 04014 ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index) 04015 : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index); 04016 if (NewAttr) 04017 D->addAttr(NewAttr); 04018 } 04019 04020 MSInheritanceAttr * 04021 Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, 04022 unsigned AttrSpellingListIndex, 04023 MSInheritanceAttr::Spelling SemanticSpelling) { 04024 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) { 04025 if (IA->getSemanticSpelling() == SemanticSpelling) 04026 return nullptr; 04027 Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance) 04028 << 1 /*previous declaration*/; 04029 Diag(Range.getBegin(), diag::note_previous_ms_inheritance); 04030 D->dropAttr<MSInheritanceAttr>(); 04031 } 04032 04033 CXXRecordDecl *RD = cast<CXXRecordDecl>(D); 04034 if (RD->hasDefinition()) { 04035 if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase, 04036 SemanticSpelling)) { 04037 return nullptr; 04038 } 04039 } else { 04040 if (isa<ClassTemplatePartialSpecializationDecl>(RD)) { 04041 Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance) 04042 << 1 /*partial specialization*/; 04043 return nullptr; 04044 } 04045 if (RD->getDescribedClassTemplate()) { 04046 Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance) 04047 << 0 /*primary template*/; 04048 return nullptr; 04049 } 04050 } 04051 04052 return ::new (Context) 04053 MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex); 04054 } 04055 04056 static void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 04057 // The capability attributes take a single string parameter for the name of 04058 // the capability they represent. The lockable attribute does not take any 04059 // parameters. However, semantically, both attributes represent the same 04060 // concept, and so they use the same semantic attribute. Eventually, the 04061 // lockable attribute will be removed. 04062 // 04063 // For backward compatibility, any capability which has no specified string 04064 // literal will be considered a "mutex." 04065 StringRef N("mutex"); 04066 SourceLocation LiteralLoc; 04067 if (Attr.getKind() == AttributeList::AT_Capability && 04068 !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc)) 04069 return; 04070 04071 // Currently, there are only two names allowed for a capability: role and 04072 // mutex (case insensitive). Diagnose other capability names. 04073 if (!N.equals_lower("mutex") && !N.equals_lower("role")) 04074 S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N; 04075 04076 D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N, 04077 Attr.getAttributeSpellingListIndex())); 04078 } 04079 04080 static void handleAssertCapabilityAttr(Sema &S, Decl *D, 04081 const AttributeList &Attr) { 04082 D->addAttr(::new (S.Context) AssertCapabilityAttr(Attr.getRange(), S.Context, 04083 Attr.getArgAsExpr(0), 04084 Attr.getAttributeSpellingListIndex())); 04085 } 04086 04087 static void handleAcquireCapabilityAttr(Sema &S, Decl *D, 04088 const AttributeList &Attr) { 04089 SmallVector<Expr*, 1> Args; 04090 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 04091 return; 04092 04093 D->addAttr(::new (S.Context) AcquireCapabilityAttr(Attr.getRange(), 04094 S.Context, 04095 Args.data(), Args.size(), 04096 Attr.getAttributeSpellingListIndex())); 04097 } 04098 04099 static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D, 04100 const AttributeList &Attr) { 04101 SmallVector<Expr*, 2> Args; 04102 if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 04103 return; 04104 04105 D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(Attr.getRange(), 04106 S.Context, 04107 Attr.getArgAsExpr(0), 04108 Args.data(), 04109 Args.size(), 04110 Attr.getAttributeSpellingListIndex())); 04111 } 04112 04113 static void handleReleaseCapabilityAttr(Sema &S, Decl *D, 04114 const AttributeList &Attr) { 04115 // Check that all arguments are lockable objects. 04116 SmallVector<Expr *, 1> Args; 04117 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, true); 04118 04119 D->addAttr(::new (S.Context) ReleaseCapabilityAttr( 04120 Attr.getRange(), S.Context, Args.data(), Args.size(), 04121 Attr.getAttributeSpellingListIndex())); 04122 } 04123 04124 static void handleRequiresCapabilityAttr(Sema &S, Decl *D, 04125 const AttributeList &Attr) { 04126 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 04127 return; 04128 04129 // check that all arguments are lockable objects 04130 SmallVector<Expr*, 1> Args; 04131 checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 04132 if (Args.empty()) 04133 return; 04134 04135 RequiresCapabilityAttr *RCA = ::new (S.Context) 04136 RequiresCapabilityAttr(Attr.getRange(), S.Context, Args.data(), 04137 Args.size(), Attr.getAttributeSpellingListIndex()); 04138 04139 D->addAttr(RCA); 04140 } 04141 04142 static void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 04143 if (auto *NSD = dyn_cast<NamespaceDecl>(D)) { 04144 if (NSD->isAnonymousNamespace()) { 04145 S.Diag(Attr.getLoc(), diag::warn_deprecated_anonymous_namespace); 04146 // Do not want to attach the attribute to the namespace because that will 04147 // cause confusing diagnostic reports for uses of declarations within the 04148 // namespace. 04149 return; 04150 } 04151 } 04152 handleAttrWithMessage<DeprecatedAttr>(S, D, Attr); 04153 } 04154 04155 /// Handles semantic checking for features that are common to all attributes, 04156 /// such as checking whether a parameter was properly specified, or the correct 04157 /// number of arguments were passed, etc. 04158 static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D, 04159 const AttributeList &Attr) { 04160 // Several attributes carry different semantics than the parsing requires, so 04161 // those are opted out of the common handling. 04162 // 04163 // We also bail on unknown and ignored attributes because those are handled 04164 // as part of the target-specific handling logic. 04165 if (Attr.hasCustomParsing() || 04166 Attr.getKind() == AttributeList::UnknownAttribute) 04167 return false; 04168 04169 // Check whether the attribute requires specific language extensions to be 04170 // enabled. 04171 if (!Attr.diagnoseLangOpts(S)) 04172 return true; 04173 04174 if (Attr.getMinArgs() == Attr.getMaxArgs()) { 04175 // If there are no optional arguments, then checking for the argument count 04176 // is trivial. 04177 if (!checkAttributeNumArgs(S, Attr, Attr.getMinArgs())) 04178 return true; 04179 } else { 04180 // There are optional arguments, so checking is slightly more involved. 04181 if (Attr.getMinArgs() && 04182 !checkAttributeAtLeastNumArgs(S, Attr, Attr.getMinArgs())) 04183 return true; 04184 else if (!Attr.hasVariadicArg() && Attr.getMaxArgs() && 04185 !checkAttributeAtMostNumArgs(S, Attr, Attr.getMaxArgs())) 04186 return true; 04187 } 04188 04189 // Check whether the attribute appertains to the given subject. 04190 if (!Attr.diagnoseAppertainsTo(S, D)) 04191 return true; 04192 04193 return false; 04194 } 04195 04196 //===----------------------------------------------------------------------===// 04197 // Top Level Sema Entry Points 04198 //===----------------------------------------------------------------------===// 04199 04200 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 04201 /// the attribute applies to decls. If the attribute is a type attribute, just 04202 /// silently ignore it if a GNU attribute. 04203 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 04204 const AttributeList &Attr, 04205 bool IncludeCXX11Attributes) { 04206 if (Attr.isInvalid() || Attr.getKind() == AttributeList::IgnoredAttribute) 04207 return; 04208 04209 // Ignore C++11 attributes on declarator chunks: they appertain to the type 04210 // instead. 04211 if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes) 04212 return; 04213 04214 // Unknown attributes are automatically warned on. Target-specific attributes 04215 // which do not apply to the current target architecture are treated as 04216 // though they were unknown attributes. 04217 if (Attr.getKind() == AttributeList::UnknownAttribute || 04218 !Attr.existsInTarget(S.Context.getTargetInfo().getTriple())) { 04219 S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() 04220 ? diag::warn_unhandled_ms_attribute_ignored 04221 : diag::warn_unknown_attribute_ignored) 04222 << Attr.getName(); 04223 return; 04224 } 04225 04226 if (handleCommonAttributeFeatures(S, scope, D, Attr)) 04227 return; 04228 04229 switch (Attr.getKind()) { 04230 default: 04231 // Type attributes are handled elsewhere; silently move on. 04232 assert(Attr.isTypeAttr() && "Non-type attribute not handled"); 04233 break; 04234 case AttributeList::AT_Interrupt: 04235 handleInterruptAttr(S, D, Attr); 04236 break; 04237 case AttributeList::AT_X86ForceAlignArgPointer: 04238 handleX86ForceAlignArgPointerAttr(S, D, Attr); 04239 break; 04240 case AttributeList::AT_DLLExport: 04241 case AttributeList::AT_DLLImport: 04242 handleDLLAttr(S, D, Attr); 04243 break; 04244 case AttributeList::AT_Mips16: 04245 handleSimpleAttribute<Mips16Attr>(S, D, Attr); 04246 break; 04247 case AttributeList::AT_NoMips16: 04248 handleSimpleAttribute<NoMips16Attr>(S, D, Attr); 04249 break; 04250 case AttributeList::AT_IBAction: 04251 handleSimpleAttribute<IBActionAttr>(S, D, Attr); 04252 break; 04253 case AttributeList::AT_IBOutlet: 04254 handleIBOutlet(S, D, Attr); 04255 break; 04256 case AttributeList::AT_IBOutletCollection: 04257 handleIBOutletCollection(S, D, Attr); 04258 break; 04259 case AttributeList::AT_Alias: 04260 handleAliasAttr(S, D, Attr); 04261 break; 04262 case AttributeList::AT_Aligned: 04263 handleAlignedAttr(S, D, Attr); 04264 break; 04265 case AttributeList::AT_AlignValue: 04266 handleAlignValueAttr(S, D, Attr); 04267 break; 04268 case AttributeList::AT_AlwaysInline: 04269 handleAlwaysInlineAttr(S, D, Attr); 04270 break; 04271 case AttributeList::AT_AnalyzerNoReturn: 04272 handleAnalyzerNoReturnAttr(S, D, Attr); 04273 break; 04274 case AttributeList::AT_TLSModel: 04275 handleTLSModelAttr(S, D, Attr); 04276 break; 04277 case AttributeList::AT_Annotate: 04278 handleAnnotateAttr(S, D, Attr); 04279 break; 04280 case AttributeList::AT_Availability: 04281 handleAvailabilityAttr(S, D, Attr); 04282 break; 04283 case AttributeList::AT_CarriesDependency: 04284 handleDependencyAttr(S, scope, D, Attr); 04285 break; 04286 case AttributeList::AT_Common: 04287 handleCommonAttr(S, D, Attr); 04288 break; 04289 case AttributeList::AT_CUDAConstant: 04290 handleSimpleAttribute<CUDAConstantAttr>(S, D, Attr); 04291 break; 04292 case AttributeList::AT_Constructor: 04293 handleConstructorAttr(S, D, Attr); 04294 break; 04295 case AttributeList::AT_CXX11NoReturn: 04296 handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr); 04297 break; 04298 case AttributeList::AT_Deprecated: 04299 handleDeprecatedAttr(S, D, Attr); 04300 break; 04301 case AttributeList::AT_Destructor: 04302 handleDestructorAttr(S, D, Attr); 04303 break; 04304 case AttributeList::AT_EnableIf: 04305 handleEnableIfAttr(S, D, Attr); 04306 break; 04307 case AttributeList::AT_ExtVectorType: 04308 handleExtVectorTypeAttr(S, scope, D, Attr); 04309 break; 04310 case AttributeList::AT_MinSize: 04311 handleSimpleAttribute<MinSizeAttr>(S, D, Attr); 04312 break; 04313 case AttributeList::AT_OptimizeNone: 04314 handleOptimizeNoneAttr(S, D, Attr); 04315 break; 04316 case AttributeList::AT_Flatten: 04317 handleSimpleAttribute<FlattenAttr>(S, D, Attr); 04318 break; 04319 case AttributeList::AT_Format: 04320 handleFormatAttr(S, D, Attr); 04321 break; 04322 case AttributeList::AT_FormatArg: 04323 handleFormatArgAttr(S, D, Attr); 04324 break; 04325 case AttributeList::AT_CUDAGlobal: 04326 handleGlobalAttr(S, D, Attr); 04327 break; 04328 case AttributeList::AT_CUDADevice: 04329 handleSimpleAttribute<CUDADeviceAttr>(S, D, Attr); 04330 break; 04331 case AttributeList::AT_CUDAHost: 04332 handleSimpleAttribute<CUDAHostAttr>(S, D, Attr); 04333 break; 04334 case AttributeList::AT_GNUInline: 04335 handleGNUInlineAttr(S, D, Attr); 04336 break; 04337 case AttributeList::AT_CUDALaunchBounds: 04338 handleLaunchBoundsAttr(S, D, Attr); 04339 break; 04340 case AttributeList::AT_Malloc: 04341 handleMallocAttr(S, D, Attr); 04342 break; 04343 case AttributeList::AT_MayAlias: 04344 handleSimpleAttribute<MayAliasAttr>(S, D, Attr); 04345 break; 04346 case AttributeList::AT_Mode: 04347 handleModeAttr(S, D, Attr); 04348 break; 04349 case AttributeList::AT_NoCommon: 04350 handleSimpleAttribute<NoCommonAttr>(S, D, Attr); 04351 break; 04352 case AttributeList::AT_NoSplitStack: 04353 handleSimpleAttribute<NoSplitStackAttr>(S, D, Attr); 04354 break; 04355 case AttributeList::AT_NonNull: 04356 if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(D)) 04357 handleNonNullAttrParameter(S, PVD, Attr); 04358 else 04359 handleNonNullAttr(S, D, Attr); 04360 break; 04361 case AttributeList::AT_ReturnsNonNull: 04362 handleReturnsNonNullAttr(S, D, Attr); 04363 break; 04364 case AttributeList::AT_AssumeAligned: 04365 handleAssumeAlignedAttr(S, D, Attr); 04366 break; 04367 case AttributeList::AT_Overloadable: 04368 handleSimpleAttribute<OverloadableAttr>(S, D, Attr); 04369 break; 04370 case AttributeList::AT_Ownership: 04371 handleOwnershipAttr(S, D, Attr); 04372 break; 04373 case AttributeList::AT_Cold: 04374 handleColdAttr(S, D, Attr); 04375 break; 04376 case AttributeList::AT_Hot: 04377 handleHotAttr(S, D, Attr); 04378 break; 04379 case AttributeList::AT_Naked: 04380 handleSimpleAttribute<NakedAttr>(S, D, Attr); 04381 break; 04382 case AttributeList::AT_NoReturn: 04383 handleNoReturnAttr(S, D, Attr); 04384 break; 04385 case AttributeList::AT_NoThrow: 04386 handleSimpleAttribute<NoThrowAttr>(S, D, Attr); 04387 break; 04388 case AttributeList::AT_CUDAShared: 04389 handleSimpleAttribute<CUDASharedAttr>(S, D, Attr); 04390 break; 04391 case AttributeList::AT_VecReturn: 04392 handleVecReturnAttr(S, D, Attr); 04393 break; 04394 04395 case AttributeList::AT_ObjCOwnership: 04396 handleObjCOwnershipAttr(S, D, Attr); 04397 break; 04398 case AttributeList::AT_ObjCPreciseLifetime: 04399 handleObjCPreciseLifetimeAttr(S, D, Attr); 04400 break; 04401 04402 case AttributeList::AT_ObjCReturnsInnerPointer: 04403 handleObjCReturnsInnerPointerAttr(S, D, Attr); 04404 break; 04405 04406 case AttributeList::AT_ObjCRequiresSuper: 04407 handleObjCRequiresSuperAttr(S, D, Attr); 04408 break; 04409 04410 case AttributeList::AT_ObjCBridge: 04411 handleObjCBridgeAttr(S, scope, D, Attr); 04412 break; 04413 04414 case AttributeList::AT_ObjCBridgeMutable: 04415 handleObjCBridgeMutableAttr(S, scope, D, Attr); 04416 break; 04417 04418 case AttributeList::AT_ObjCBridgeRelated: 04419 handleObjCBridgeRelatedAttr(S, scope, D, Attr); 04420 break; 04421 04422 case AttributeList::AT_ObjCDesignatedInitializer: 04423 handleObjCDesignatedInitializer(S, D, Attr); 04424 break; 04425 04426 case AttributeList::AT_ObjCRuntimeName: 04427 handleObjCRuntimeName(S, D, Attr); 04428 break; 04429 04430 case AttributeList::AT_CFAuditedTransfer: 04431 handleCFAuditedTransferAttr(S, D, Attr); 04432 break; 04433 case AttributeList::AT_CFUnknownTransfer: 04434 handleCFUnknownTransferAttr(S, D, Attr); 04435 break; 04436 04437 case AttributeList::AT_CFConsumed: 04438 case AttributeList::AT_NSConsumed: 04439 handleNSConsumedAttr(S, D, Attr); 04440 break; 04441 case AttributeList::AT_NSConsumesSelf: 04442 handleSimpleAttribute<NSConsumesSelfAttr>(S, D, Attr); 04443 break; 04444 04445 case AttributeList::AT_NSReturnsAutoreleased: 04446 case AttributeList::AT_NSReturnsNotRetained: 04447 case AttributeList::AT_CFReturnsNotRetained: 04448 case AttributeList::AT_NSReturnsRetained: 04449 case AttributeList::AT_CFReturnsRetained: 04450 handleNSReturnsRetainedAttr(S, D, Attr); 04451 break; 04452 case AttributeList::AT_WorkGroupSizeHint: 04453 handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, Attr); 04454 break; 04455 case AttributeList::AT_ReqdWorkGroupSize: 04456 handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, Attr); 04457 break; 04458 case AttributeList::AT_VecTypeHint: 04459 handleVecTypeHint(S, D, Attr); 04460 break; 04461 04462 case AttributeList::AT_InitPriority: 04463 handleInitPriorityAttr(S, D, Attr); 04464 break; 04465 04466 case AttributeList::AT_Packed: 04467 handlePackedAttr(S, D, Attr); 04468 break; 04469 case AttributeList::AT_Section: 04470 handleSectionAttr(S, D, Attr); 04471 break; 04472 case AttributeList::AT_Unavailable: 04473 handleAttrWithMessage<UnavailableAttr>(S, D, Attr); 04474 break; 04475 case AttributeList::AT_ArcWeakrefUnavailable: 04476 handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, Attr); 04477 break; 04478 case AttributeList::AT_ObjCRootClass: 04479 handleSimpleAttribute<ObjCRootClassAttr>(S, D, Attr); 04480 break; 04481 case AttributeList::AT_ObjCExplicitProtocolImpl: 04482 handleObjCSuppresProtocolAttr(S, D, Attr); 04483 break; 04484 case AttributeList::AT_ObjCRequiresPropertyDefs: 04485 handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, Attr); 04486 break; 04487 case AttributeList::AT_Unused: 04488 handleSimpleAttribute<UnusedAttr>(S, D, Attr); 04489 break; 04490 case AttributeList::AT_ReturnsTwice: 04491 handleSimpleAttribute<ReturnsTwiceAttr>(S, D, Attr); 04492 break; 04493 case AttributeList::AT_Used: 04494 handleUsedAttr(S, D, Attr); 04495 break; 04496 case AttributeList::AT_Visibility: 04497 handleVisibilityAttr(S, D, Attr, false); 04498 break; 04499 case AttributeList::AT_TypeVisibility: 04500 handleVisibilityAttr(S, D, Attr, true); 04501 break; 04502 case AttributeList::AT_WarnUnused: 04503 handleSimpleAttribute<WarnUnusedAttr>(S, D, Attr); 04504 break; 04505 case AttributeList::AT_WarnUnusedResult: 04506 handleWarnUnusedResult(S, D, Attr); 04507 break; 04508 case AttributeList::AT_Weak: 04509 handleSimpleAttribute<WeakAttr>(S, D, Attr); 04510 break; 04511 case AttributeList::AT_WeakRef: 04512 handleWeakRefAttr(S, D, Attr); 04513 break; 04514 case AttributeList::AT_WeakImport: 04515 handleWeakImportAttr(S, D, Attr); 04516 break; 04517 case AttributeList::AT_TransparentUnion: 04518 handleTransparentUnionAttr(S, D, Attr); 04519 break; 04520 case AttributeList::AT_ObjCException: 04521 handleSimpleAttribute<ObjCExceptionAttr>(S, D, Attr); 04522 break; 04523 case AttributeList::AT_ObjCMethodFamily: 04524 handleObjCMethodFamilyAttr(S, D, Attr); 04525 break; 04526 case AttributeList::AT_ObjCNSObject: 04527 handleObjCNSObject(S, D, Attr); 04528 break; 04529 case AttributeList::AT_Blocks: 04530 handleBlocksAttr(S, D, Attr); 04531 break; 04532 case AttributeList::AT_Sentinel: 04533 handleSentinelAttr(S, D, Attr); 04534 break; 04535 case AttributeList::AT_Const: 04536 handleSimpleAttribute<ConstAttr>(S, D, Attr); 04537 break; 04538 case AttributeList::AT_Pure: 04539 handleSimpleAttribute<PureAttr>(S, D, Attr); 04540 break; 04541 case AttributeList::AT_Cleanup: 04542 handleCleanupAttr(S, D, Attr); 04543 break; 04544 case AttributeList::AT_NoDebug: 04545 handleNoDebugAttr(S, D, Attr); 04546 break; 04547 case AttributeList::AT_NoDuplicate: 04548 handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr); 04549 break; 04550 case AttributeList::AT_NoInline: 04551 handleSimpleAttribute<NoInlineAttr>(S, D, Attr); 04552 break; 04553 case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg. 04554 handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, Attr); 04555 break; 04556 case AttributeList::AT_StdCall: 04557 case AttributeList::AT_CDecl: 04558 case AttributeList::AT_FastCall: 04559 case AttributeList::AT_ThisCall: 04560 case AttributeList::AT_Pascal: 04561 case AttributeList::AT_VectorCall: 04562 case AttributeList::AT_MSABI: 04563 case AttributeList::AT_SysVABI: 04564 case AttributeList::AT_Pcs: 04565 case AttributeList::AT_PnaclCall: 04566 case AttributeList::AT_IntelOclBicc: 04567 handleCallConvAttr(S, D, Attr); 04568 break; 04569 case AttributeList::AT_OpenCLKernel: 04570 handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr); 04571 break; 04572 case AttributeList::AT_OpenCLImageAccess: 04573 handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr); 04574 break; 04575 04576 // Microsoft attributes: 04577 case AttributeList::AT_MsStruct: 04578 handleSimpleAttribute<MsStructAttr>(S, D, Attr); 04579 break; 04580 case AttributeList::AT_Uuid: 04581 handleUuidAttr(S, D, Attr); 04582 break; 04583 case AttributeList::AT_MSInheritance: 04584 handleMSInheritanceAttr(S, D, Attr); 04585 break; 04586 case AttributeList::AT_SelectAny: 04587 handleSimpleAttribute<SelectAnyAttr>(S, D, Attr); 04588 break; 04589 case AttributeList::AT_Thread: 04590 handleDeclspecThreadAttr(S, D, Attr); 04591 break; 04592 04593 // Thread safety attributes: 04594 case AttributeList::AT_AssertExclusiveLock: 04595 handleAssertExclusiveLockAttr(S, D, Attr); 04596 break; 04597 case AttributeList::AT_AssertSharedLock: 04598 handleAssertSharedLockAttr(S, D, Attr); 04599 break; 04600 case AttributeList::AT_GuardedVar: 04601 handleSimpleAttribute<GuardedVarAttr>(S, D, Attr); 04602 break; 04603 case AttributeList::AT_PtGuardedVar: 04604 handlePtGuardedVarAttr(S, D, Attr); 04605 break; 04606 case AttributeList::AT_ScopedLockable: 04607 handleSimpleAttribute<ScopedLockableAttr>(S, D, Attr); 04608 break; 04609 case AttributeList::AT_NoSanitizeAddress: 04610 handleSimpleAttribute<NoSanitizeAddressAttr>(S, D, Attr); 04611 break; 04612 case AttributeList::AT_NoThreadSafetyAnalysis: 04613 handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, Attr); 04614 break; 04615 case AttributeList::AT_NoSanitizeThread: 04616 handleSimpleAttribute<NoSanitizeThreadAttr>(S, D, Attr); 04617 break; 04618 case AttributeList::AT_NoSanitizeMemory: 04619 handleSimpleAttribute<NoSanitizeMemoryAttr>(S, D, Attr); 04620 break; 04621 case AttributeList::AT_GuardedBy: 04622 handleGuardedByAttr(S, D, Attr); 04623 break; 04624 case AttributeList::AT_PtGuardedBy: 04625 handlePtGuardedByAttr(S, D, Attr); 04626 break; 04627 case AttributeList::AT_ExclusiveTrylockFunction: 04628 handleExclusiveTrylockFunctionAttr(S, D, Attr); 04629 break; 04630 case AttributeList::AT_LockReturned: 04631 handleLockReturnedAttr(S, D, Attr); 04632 break; 04633 case AttributeList::AT_LocksExcluded: 04634 handleLocksExcludedAttr(S, D, Attr); 04635 break; 04636 case AttributeList::AT_SharedTrylockFunction: 04637 handleSharedTrylockFunctionAttr(S, D, Attr); 04638 break; 04639 case AttributeList::AT_AcquiredBefore: 04640 handleAcquiredBeforeAttr(S, D, Attr); 04641 break; 04642 case AttributeList::AT_AcquiredAfter: 04643 handleAcquiredAfterAttr(S, D, Attr); 04644 break; 04645 04646 // Capability analysis attributes. 04647 case AttributeList::AT_Capability: 04648 case AttributeList::AT_Lockable: 04649 handleCapabilityAttr(S, D, Attr); 04650 break; 04651 case AttributeList::AT_RequiresCapability: 04652 handleRequiresCapabilityAttr(S, D, Attr); 04653 break; 04654 04655 case AttributeList::AT_AssertCapability: 04656 handleAssertCapabilityAttr(S, D, Attr); 04657 break; 04658 case AttributeList::AT_AcquireCapability: 04659 handleAcquireCapabilityAttr(S, D, Attr); 04660 break; 04661 case AttributeList::AT_ReleaseCapability: 04662 handleReleaseCapabilityAttr(S, D, Attr); 04663 break; 04664 case AttributeList::AT_TryAcquireCapability: 04665 handleTryAcquireCapabilityAttr(S, D, Attr); 04666 break; 04667 04668 // Consumed analysis attributes. 04669 case AttributeList::AT_Consumable: 04670 handleConsumableAttr(S, D, Attr); 04671 break; 04672 case AttributeList::AT_ConsumableAutoCast: 04673 handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, Attr); 04674 break; 04675 case AttributeList::AT_ConsumableSetOnRead: 04676 handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, Attr); 04677 break; 04678 case AttributeList::AT_CallableWhen: 04679 handleCallableWhenAttr(S, D, Attr); 04680 break; 04681 case AttributeList::AT_ParamTypestate: 04682 handleParamTypestateAttr(S, D, Attr); 04683 break; 04684 case AttributeList::AT_ReturnTypestate: 04685 handleReturnTypestateAttr(S, D, Attr); 04686 break; 04687 case AttributeList::AT_SetTypestate: 04688 handleSetTypestateAttr(S, D, Attr); 04689 break; 04690 case AttributeList::AT_TestTypestate: 04691 handleTestTypestateAttr(S, D, Attr); 04692 break; 04693 04694 // Type safety attributes. 04695 case AttributeList::AT_ArgumentWithTypeTag: 04696 handleArgumentWithTypeTagAttr(S, D, Attr); 04697 break; 04698 case AttributeList::AT_TypeTagForDatatype: 04699 handleTypeTagForDatatypeAttr(S, D, Attr); 04700 break; 04701 } 04702 } 04703 04704 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified 04705 /// attribute list to the specified decl, ignoring any type attributes. 04706 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 04707 const AttributeList *AttrList, 04708 bool IncludeCXX11Attributes) { 04709 for (const AttributeList* l = AttrList; l; l = l->getNext()) 04710 ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes); 04711 04712 // FIXME: We should be able to handle these cases in TableGen. 04713 // GCC accepts 04714 // static int a9 __attribute__((weakref)); 04715 // but that looks really pointless. We reject it. 04716 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 04717 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) 04718 << cast<NamedDecl>(D); 04719 D->dropAttr<WeakRefAttr>(); 04720 return; 04721 } 04722 04723 if (!D->hasAttr<OpenCLKernelAttr>()) { 04724 // These attributes cannot be applied to a non-kernel function. 04725 if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) { 04726 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; 04727 D->setInvalidDecl(); 04728 } 04729 if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) { 04730 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; 04731 D->setInvalidDecl(); 04732 } 04733 if (Attr *A = D->getAttr<VecTypeHintAttr>()) { 04734 Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; 04735 D->setInvalidDecl(); 04736 } 04737 } 04738 } 04739 04740 // Annotation attributes are the only attributes allowed after an access 04741 // specifier. 04742 bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 04743 const AttributeList *AttrList) { 04744 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 04745 if (l->getKind() == AttributeList::AT_Annotate) { 04746 handleAnnotateAttr(*this, ASDecl, *l); 04747 } else { 04748 Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 04749 return true; 04750 } 04751 } 04752 04753 return false; 04754 } 04755 04756 /// checkUnusedDeclAttributes - Check a list of attributes to see if it 04757 /// contains any decl attributes that we should warn about. 04758 static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 04759 for ( ; A; A = A->getNext()) { 04760 // Only warn if the attribute is an unignored, non-type attribute. 04761 if (A->isUsedAsTypeAttr() || A->isInvalid()) continue; 04762 if (A->getKind() == AttributeList::IgnoredAttribute) continue; 04763 04764 if (A->getKind() == AttributeList::UnknownAttribute) { 04765 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 04766 << A->getName() << A->getRange(); 04767 } else { 04768 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 04769 << A->getName() << A->getRange(); 04770 } 04771 } 04772 } 04773 04774 /// checkUnusedDeclAttributes - Given a declarator which is not being 04775 /// used to build a declaration, complain about any decl attributes 04776 /// which might be lying around on it. 04777 void Sema::checkUnusedDeclAttributes(Declarator &D) { 04778 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 04779 ::checkUnusedDeclAttributes(*this, D.getAttributes()); 04780 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 04781 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 04782 } 04783 04784 /// DeclClonePragmaWeak - clone existing decl (maybe definition), 04785 /// \#pragma weak needs a non-definition decl and source may not have one. 04786 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 04787 SourceLocation Loc) { 04788 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 04789 NamedDecl *NewD = nullptr; 04790 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 04791 FunctionDecl *NewFD; 04792 // FIXME: Missing call to CheckFunctionDeclaration(). 04793 // FIXME: Mangling? 04794 // FIXME: Is the qualifier info correct? 04795 // FIXME: Is the DeclContext correct? 04796 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 04797 Loc, Loc, DeclarationName(II), 04798 FD->getType(), FD->getTypeSourceInfo(), 04799 SC_None, false/*isInlineSpecified*/, 04800 FD->hasPrototype(), 04801 false/*isConstexprSpecified*/); 04802 NewD = NewFD; 04803 04804 if (FD->getQualifier()) 04805 NewFD->setQualifierInfo(FD->getQualifierLoc()); 04806 04807 // Fake up parameter variables; they are declared as if this were 04808 // a typedef. 04809 QualType FDTy = FD->getType(); 04810 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 04811 SmallVector<ParmVarDecl*, 16> Params; 04812 for (const auto &AI : FT->param_types()) { 04813 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI); 04814 Param->setScopeInfo(0, Params.size()); 04815 Params.push_back(Param); 04816 } 04817 NewFD->setParams(Params); 04818 } 04819 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 04820 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 04821 VD->getInnerLocStart(), VD->getLocation(), II, 04822 VD->getType(), VD->getTypeSourceInfo(), 04823 VD->getStorageClass()); 04824 if (VD->getQualifier()) { 04825 VarDecl *NewVD = cast<VarDecl>(NewD); 04826 NewVD->setQualifierInfo(VD->getQualifierLoc()); 04827 } 04828 } 04829 return NewD; 04830 } 04831 04832 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak 04833 /// applied to it, possibly with an alias. 04834 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 04835 if (W.getUsed()) return; // only do this once 04836 W.setUsed(true); 04837 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 04838 IdentifierInfo *NDId = ND->getIdentifier(); 04839 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 04840 NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(), 04841 W.getLocation())); 04842 NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation())); 04843 WeakTopLevelDecl.push_back(NewD); 04844 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 04845 // to insert Decl at TU scope, sorry. 04846 DeclContext *SavedContext = CurContext; 04847 CurContext = Context.getTranslationUnitDecl(); 04848 NewD->setDeclContext(CurContext); 04849 NewD->setLexicalDeclContext(CurContext); 04850 PushOnScopeChains(NewD, S); 04851 CurContext = SavedContext; 04852 } else { // just add weak to existing 04853 ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation())); 04854 } 04855 } 04856 04857 void Sema::ProcessPragmaWeak(Scope *S, Decl *D) { 04858 // It's valid to "forward-declare" #pragma weak, in which case we 04859 // have to do this. 04860 LoadExternalWeakUndeclaredIdentifiers(); 04861 if (!WeakUndeclaredIdentifiers.empty()) { 04862 NamedDecl *ND = nullptr; 04863 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 04864 if (VD->isExternC()) 04865 ND = VD; 04866 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 04867 if (FD->isExternC()) 04868 ND = FD; 04869 if (ND) { 04870 if (IdentifierInfo *Id = ND->getIdentifier()) { 04871 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 04872 = WeakUndeclaredIdentifiers.find(Id); 04873 if (I != WeakUndeclaredIdentifiers.end()) { 04874 WeakInfo W = I->second; 04875 DeclApplyPragmaWeak(S, ND, W); 04876 WeakUndeclaredIdentifiers[Id] = W; 04877 } 04878 } 04879 } 04880 } 04881 } 04882 04883 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 04884 /// it, apply them to D. This is a bit tricky because PD can have attributes 04885 /// specified in many different places, and we need to find and apply them all. 04886 void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 04887 // Apply decl attributes from the DeclSpec if present. 04888 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 04889 ProcessDeclAttributeList(S, D, Attrs); 04890 04891 // Walk the declarator structure, applying decl attributes that were in a type 04892 // position to the decl itself. This handles cases like: 04893 // int *__attr__(x)** D; 04894 // when X is a decl attribute. 04895 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 04896 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 04897 ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false); 04898 04899 // Finally, apply any attributes on the decl itself. 04900 if (const AttributeList *Attrs = PD.getAttributes()) 04901 ProcessDeclAttributeList(S, D, Attrs); 04902 } 04903 04904 /// Is the given declaration allowed to use a forbidden type? 04905 static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 04906 // Private ivars are always okay. Unfortunately, people don't 04907 // always properly make their ivars private, even in system headers. 04908 // Plus we need to make fields okay, too. 04909 // Function declarations in sys headers will be marked unavailable. 04910 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 04911 !isa<FunctionDecl>(decl)) 04912 return false; 04913 04914 // Require it to be declared in a system header. 04915 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 04916 } 04917 04918 /// Handle a delayed forbidden-type diagnostic. 04919 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 04920 Decl *decl) { 04921 if (decl && isForbiddenTypeAllowed(S, decl)) { 04922 decl->addAttr(UnavailableAttr::CreateImplicit(S.Context, 04923 "this system declaration uses an unsupported type", 04924 diag.Loc)); 04925 return; 04926 } 04927 if (S.getLangOpts().ObjCAutoRefCount) 04928 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 04929 // FIXME: we may want to suppress diagnostics for all 04930 // kind of forbidden type messages on unavailable functions. 04931 if (FD->hasAttr<UnavailableAttr>() && 04932 diag.getForbiddenTypeDiagnostic() == 04933 diag::err_arc_array_param_no_ownership) { 04934 diag.Triggered = true; 04935 return; 04936 } 04937 } 04938 04939 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 04940 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 04941 diag.Triggered = true; 04942 } 04943 04944 04945 static bool isDeclDeprecated(Decl *D) { 04946 do { 04947 if (D->isDeprecated()) 04948 return true; 04949 // A category implicitly has the availability of the interface. 04950 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 04951 return CatD->getClassInterface()->isDeprecated(); 04952 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 04953 return false; 04954 } 04955 04956 static bool isDeclUnavailable(Decl *D) { 04957 do { 04958 if (D->isUnavailable()) 04959 return true; 04960 // A category implicitly has the availability of the interface. 04961 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 04962 return CatD->getClassInterface()->isUnavailable(); 04963 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 04964 return false; 04965 } 04966 04967 static void DoEmitAvailabilityWarning(Sema &S, DelayedDiagnostic::DDKind K, 04968 Decl *Ctx, const NamedDecl *D, 04969 StringRef Message, SourceLocation Loc, 04970 const ObjCInterfaceDecl *UnknownObjCClass, 04971 const ObjCPropertyDecl *ObjCProperty, 04972 bool ObjCPropertyAccess) { 04973 // Diagnostics for deprecated or unavailable. 04974 unsigned diag, diag_message, diag_fwdclass_message; 04975 04976 // Matches 'diag::note_property_attribute' options. 04977 unsigned property_note_select; 04978 04979 // Matches diag::note_availability_specified_here. 04980 unsigned available_here_select_kind; 04981 04982 // Don't warn if our current context is deprecated or unavailable. 04983 switch (K) { 04984 case DelayedDiagnostic::Deprecation: 04985 if (isDeclDeprecated(Ctx)) 04986 return; 04987 diag = !ObjCPropertyAccess ? diag::warn_deprecated 04988 : diag::warn_property_method_deprecated; 04989 diag_message = diag::warn_deprecated_message; 04990 diag_fwdclass_message = diag::warn_deprecated_fwdclass_message; 04991 property_note_select = /* deprecated */ 0; 04992 available_here_select_kind = /* deprecated */ 2; 04993 break; 04994 04995 case DelayedDiagnostic::Unavailable: 04996 if (isDeclUnavailable(Ctx)) 04997 return; 04998 diag = !ObjCPropertyAccess ? diag::err_unavailable 04999 : diag::err_property_method_unavailable; 05000 diag_message = diag::err_unavailable_message; 05001 diag_fwdclass_message = diag::warn_unavailable_fwdclass_message; 05002 property_note_select = /* unavailable */ 1; 05003 available_here_select_kind = /* unavailable */ 0; 05004 break; 05005 05006 default: 05007 llvm_unreachable("Neither a deprecation or unavailable kind"); 05008 } 05009 05010 if (!Message.empty()) { 05011 S.Diag(Loc, diag_message) << D << Message; 05012 if (ObjCProperty) 05013 S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) 05014 << ObjCProperty->getDeclName() << property_note_select; 05015 } else if (!UnknownObjCClass) { 05016 S.Diag(Loc, diag) << D; 05017 if (ObjCProperty) 05018 S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) 05019 << ObjCProperty->getDeclName() << property_note_select; 05020 } else { 05021 S.Diag(Loc, diag_fwdclass_message) << D; 05022 S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 05023 } 05024 05025 S.Diag(D->getLocation(), diag::note_availability_specified_here) 05026 << D << available_here_select_kind; 05027 } 05028 05029 static void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD, 05030 Decl *Ctx) { 05031 DD.Triggered = true; 05032 DoEmitAvailabilityWarning(S, (DelayedDiagnostic::DDKind)DD.Kind, Ctx, 05033 DD.getDeprecationDecl(), DD.getDeprecationMessage(), 05034 DD.Loc, DD.getUnknownObjCClass(), 05035 DD.getObjCProperty(), false); 05036 } 05037 05038 void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { 05039 assert(DelayedDiagnostics.getCurrentPool()); 05040 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); 05041 DelayedDiagnostics.popWithoutEmitting(state); 05042 05043 // When delaying diagnostics to run in the context of a parsed 05044 // declaration, we only want to actually emit anything if parsing 05045 // succeeds. 05046 if (!decl) return; 05047 05048 // We emit all the active diagnostics in this pool or any of its 05049 // parents. In general, we'll get one pool for the decl spec 05050 // and a child pool for each declarator; in a decl group like: 05051 // deprecated_typedef foo, *bar, baz(); 05052 // only the declarator pops will be passed decls. This is correct; 05053 // we really do need to consider delayed diagnostics from the decl spec 05054 // for each of the different declarations. 05055 const DelayedDiagnosticPool *pool = &poppedPool; 05056 do { 05057 for (DelayedDiagnosticPool::pool_iterator 05058 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { 05059 // This const_cast is a bit lame. Really, Triggered should be mutable. 05060 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); 05061 if (diag.Triggered) 05062 continue; 05063 05064 switch (diag.Kind) { 05065 case DelayedDiagnostic::Deprecation: 05066 case DelayedDiagnostic::Unavailable: 05067 // Don't bother giving deprecation/unavailable diagnostics if 05068 // the decl is invalid. 05069 if (!decl->isInvalidDecl()) 05070 handleDelayedAvailabilityCheck(*this, diag, decl); 05071 break; 05072 05073 case DelayedDiagnostic::Access: 05074 HandleDelayedAccessCheck(diag, decl); 05075 break; 05076 05077 case DelayedDiagnostic::ForbiddenType: 05078 handleDelayedForbiddenType(*this, diag, decl); 05079 break; 05080 } 05081 } 05082 } while ((pool = pool->getParent())); 05083 } 05084 05085 /// Given a set of delayed diagnostics, re-emit them as if they had 05086 /// been delayed in the current context instead of in the given pool. 05087 /// Essentially, this just moves them to the current pool. 05088 void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { 05089 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); 05090 assert(curPool && "re-emitting in undelayed context not supported"); 05091 curPool->steal(pool); 05092 } 05093 05094 void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD, 05095 NamedDecl *D, StringRef Message, 05096 SourceLocation Loc, 05097 const ObjCInterfaceDecl *UnknownObjCClass, 05098 const ObjCPropertyDecl *ObjCProperty, 05099 bool ObjCPropertyAccess) { 05100 // Delay if we're currently parsing a declaration. 05101 if (DelayedDiagnostics.shouldDelayDiagnostics()) { 05102 DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D, 05103 UnknownObjCClass, 05104 ObjCProperty, 05105 Message, 05106 ObjCPropertyAccess)); 05107 return; 05108 } 05109 05110 Decl *Ctx = cast<Decl>(getCurLexicalContext()); 05111 DelayedDiagnostic::DDKind K; 05112 switch (AD) { 05113 case AD_Deprecation: 05114 K = DelayedDiagnostic::Deprecation; 05115 break; 05116 case AD_Unavailable: 05117 K = DelayedDiagnostic::Unavailable; 05118 break; 05119 } 05120 05121 DoEmitAvailabilityWarning(*this, K, Ctx, D, Message, Loc, 05122 UnknownObjCClass, ObjCProperty, ObjCPropertyAccess); 05123 }