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 "TargetAttributesSema.h" 00016 #include "clang/AST/ASTContext.h" 00017 #include "clang/AST/CXXInheritance.h" 00018 #include "clang/AST/DeclCXX.h" 00019 #include "clang/AST/DeclTemplate.h" 00020 #include "clang/AST/DeclObjC.h" 00021 #include "clang/AST/Expr.h" 00022 #include "clang/Basic/SourceManager.h" 00023 #include "clang/Basic/TargetInfo.h" 00024 #include "clang/Sema/DeclSpec.h" 00025 #include "clang/Sema/DelayedDiagnostic.h" 00026 #include "clang/Sema/Lookup.h" 00027 #include "llvm/ADT/StringExtras.h" 00028 using namespace clang; 00029 using namespace sema; 00030 00031 /// These constants match the enumerated choices of 00032 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 00033 enum AttributeDeclKind { 00034 ExpectedFunction, 00035 ExpectedUnion, 00036 ExpectedVariableOrFunction, 00037 ExpectedFunctionOrMethod, 00038 ExpectedParameter, 00039 ExpectedFunctionMethodOrBlock, 00040 ExpectedFunctionMethodOrParameter, 00041 ExpectedClass, 00042 ExpectedVariable, 00043 ExpectedMethod, 00044 ExpectedVariableFunctionOrLabel, 00045 ExpectedFieldOrGlobalVar, 00046 ExpectedStruct 00047 }; 00048 00049 //===----------------------------------------------------------------------===// 00050 // Helper functions 00051 //===----------------------------------------------------------------------===// 00052 00053 static const FunctionType *getFunctionType(const Decl *D, 00054 bool blocksToo = true) { 00055 QualType Ty; 00056 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 00057 Ty = decl->getType(); 00058 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 00059 Ty = decl->getType(); 00060 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 00061 Ty = decl->getUnderlyingType(); 00062 else 00063 return 0; 00064 00065 if (Ty->isFunctionPointerType()) 00066 Ty = Ty->getAs<PointerType>()->getPointeeType(); 00067 else if (blocksToo && Ty->isBlockPointerType()) 00068 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 00069 00070 return Ty->getAs<FunctionType>(); 00071 } 00072 00073 // FIXME: We should provide an abstraction around a method or function 00074 // to provide the following bits of information. 00075 00076 /// isFunction - Return true if the given decl has function 00077 /// type (function or function-typed variable). 00078 static bool isFunction(const Decl *D) { 00079 return getFunctionType(D, false) != NULL; 00080 } 00081 00082 /// isFunctionOrMethod - Return true if the given decl has function 00083 /// type (function or function-typed variable) or an Objective-C 00084 /// method. 00085 static bool isFunctionOrMethod(const Decl *D) { 00086 return isFunction(D)|| isa<ObjCMethodDecl>(D); 00087 } 00088 00089 /// isFunctionOrMethodOrBlock - Return true if the given decl has function 00090 /// type (function or function-typed variable) or an Objective-C 00091 /// method or a block. 00092 static bool isFunctionOrMethodOrBlock(const Decl *D) { 00093 if (isFunctionOrMethod(D)) 00094 return true; 00095 // check for block is more involved. 00096 if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 00097 QualType Ty = V->getType(); 00098 return Ty->isBlockPointerType(); 00099 } 00100 return isa<BlockDecl>(D); 00101 } 00102 00103 /// Return true if the given decl has a declarator that should have 00104 /// been processed by Sema::GetTypeForDeclarator. 00105 static bool hasDeclarator(const Decl *D) { 00106 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 00107 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 00108 isa<ObjCPropertyDecl>(D); 00109 } 00110 00111 /// hasFunctionProto - Return true if the given decl has a argument 00112 /// information. This decl should have already passed 00113 /// isFunctionOrMethod or isFunctionOrMethodOrBlock. 00114 static bool hasFunctionProto(const Decl *D) { 00115 if (const FunctionType *FnTy = getFunctionType(D)) 00116 return isa<FunctionProtoType>(FnTy); 00117 else { 00118 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 00119 return true; 00120 } 00121 } 00122 00123 /// getFunctionOrMethodNumArgs - Return number of function or method 00124 /// arguments. It is an error to call this on a K&R function (use 00125 /// hasFunctionProto first). 00126 static unsigned getFunctionOrMethodNumArgs(const Decl *D) { 00127 if (const FunctionType *FnTy = getFunctionType(D)) 00128 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 00129 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00130 return BD->getNumParams(); 00131 return cast<ObjCMethodDecl>(D)->param_size(); 00132 } 00133 00134 static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 00135 if (const FunctionType *FnTy = getFunctionType(D)) 00136 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 00137 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00138 return BD->getParamDecl(Idx)->getType(); 00139 00140 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 00141 } 00142 00143 static QualType getFunctionOrMethodResultType(const Decl *D) { 00144 if (const FunctionType *FnTy = getFunctionType(D)) 00145 return cast<FunctionProtoType>(FnTy)->getResultType(); 00146 return cast<ObjCMethodDecl>(D)->getResultType(); 00147 } 00148 00149 static bool isFunctionOrMethodVariadic(const Decl *D) { 00150 if (const FunctionType *FnTy = getFunctionType(D)) { 00151 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 00152 return proto->isVariadic(); 00153 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00154 return BD->isVariadic(); 00155 else { 00156 return cast<ObjCMethodDecl>(D)->isVariadic(); 00157 } 00158 } 00159 00160 static bool isInstanceMethod(const Decl *D) { 00161 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 00162 return MethodDecl->isInstance(); 00163 return false; 00164 } 00165 00166 static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 00167 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 00168 if (!PT) 00169 return false; 00170 00171 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 00172 if (!Cls) 00173 return false; 00174 00175 IdentifierInfo* ClsName = Cls->getIdentifier(); 00176 00177 // FIXME: Should we walk the chain of classes? 00178 return ClsName == &Ctx.Idents.get("NSString") || 00179 ClsName == &Ctx.Idents.get("NSMutableString"); 00180 } 00181 00182 static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 00183 const PointerType *PT = T->getAs<PointerType>(); 00184 if (!PT) 00185 return false; 00186 00187 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 00188 if (!RT) 00189 return false; 00190 00191 const RecordDecl *RD = RT->getDecl(); 00192 if (RD->getTagKind() != TTK_Struct) 00193 return false; 00194 00195 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 00196 } 00197 00198 /// \brief Check if the attribute has exactly as many args as Num. May 00199 /// output an error. 00200 static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 00201 unsigned int Num) { 00202 if (Attr.getNumArgs() != Num) { 00203 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num; 00204 return false; 00205 } 00206 00207 return true; 00208 } 00209 00210 00211 /// \brief Check if the attribute has at least as many args as Num. May 00212 /// output an error. 00213 static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 00214 unsigned int Num) { 00215 if (Attr.getNumArgs() < Num) { 00216 S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 00217 return false; 00218 } 00219 00220 return true; 00221 } 00222 00223 /// 00224 /// \brief Check if passed in Decl is a field or potentially shared global var 00225 /// \return true if the Decl is a field or potentially shared global variable 00226 /// 00227 static bool mayBeSharedVariable(const Decl *D) { 00228 if (isa<FieldDecl>(D)) 00229 return true; 00230 if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 00231 return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 00232 00233 return false; 00234 } 00235 00236 /// \brief Check if the passed-in expression is of type int or bool. 00237 static bool isIntOrBool(Expr *Exp) { 00238 QualType QT = Exp->getType(); 00239 return QT->isBooleanType() || QT->isIntegerType(); 00240 } 00241 00242 00243 // Check to see if the type is a smart pointer of some kind. We assume 00244 // it's a smart pointer if it defines both operator-> and operator*. 00245 static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { 00246 DeclContextLookupConstResult Res1 = RT->getDecl()->lookup( 00247 S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); 00248 if (Res1.first == Res1.second) 00249 return false; 00250 00251 DeclContextLookupConstResult Res2 = RT->getDecl()->lookup( 00252 S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); 00253 if (Res2.first == Res2.second) 00254 return false; 00255 00256 return true; 00257 } 00258 00259 /// \brief Check if passed in Decl is a pointer type. 00260 /// Note that this function may produce an error message. 00261 /// \return true if the Decl is a pointer type; false otherwise 00262 static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 00263 const AttributeList &Attr) { 00264 if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 00265 QualType QT = vd->getType(); 00266 if (QT->isAnyPointerType()) 00267 return true; 00268 00269 if (const RecordType *RT = QT->getAs<RecordType>()) { 00270 // If it's an incomplete type, it could be a smart pointer; skip it. 00271 // (We don't want to force template instantiation if we can avoid it, 00272 // since that would alter the order in which templates are instantiated.) 00273 if (RT->isIncompleteType()) 00274 return true; 00275 00276 if (threadSafetyCheckIsSmartPointer(S, RT)) 00277 return true; 00278 } 00279 00280 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 00281 << Attr.getName()->getName() << QT; 00282 } else { 00283 S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 00284 << Attr.getName(); 00285 } 00286 return false; 00287 } 00288 00289 /// \brief Checks that the passed in QualType either is of RecordType or points 00290 /// to RecordType. Returns the relevant RecordType, null if it does not exit. 00291 static const RecordType *getRecordType(QualType QT) { 00292 if (const RecordType *RT = QT->getAs<RecordType>()) 00293 return RT; 00294 00295 // Now check if we point to record type. 00296 if (const PointerType *PT = QT->getAs<PointerType>()) 00297 return PT->getPointeeType()->getAs<RecordType>(); 00298 00299 return 0; 00300 } 00301 00302 00303 static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier, 00304 CXXBasePath &Path, void *Unused) { 00305 const RecordType *RT = Specifier->getType()->getAs<RecordType>(); 00306 if (RT->getDecl()->getAttr<LockableAttr>()) 00307 return true; 00308 return false; 00309 } 00310 00311 00312 /// \brief Thread Safety Analysis: Checks that the passed in RecordType 00313 /// resolves to a lockable object. 00314 static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 00315 QualType Ty) { 00316 const RecordType *RT = getRecordType(Ty); 00317 00318 // Warn if could not get record type for this argument. 00319 if (!RT) { 00320 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class) 00321 << Attr.getName() << Ty.getAsString(); 00322 return; 00323 } 00324 00325 // Don't check for lockable if the class hasn't been defined yet. 00326 if (RT->isIncompleteType()) 00327 return; 00328 00329 // Allow smart pointers to be used as lockable objects. 00330 // FIXME -- Check the type that the smart pointer points to. 00331 if (threadSafetyCheckIsSmartPointer(S, RT)) 00332 return; 00333 00334 // Check if the type is lockable. 00335 RecordDecl *RD = RT->getDecl(); 00336 if (RD->getAttr<LockableAttr>()) 00337 return; 00338 00339 // Else check if any base classes are lockable. 00340 if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { 00341 CXXBasePaths BPaths(false, false); 00342 if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths)) 00343 return; 00344 } 00345 00346 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 00347 << Attr.getName() << Ty.getAsString(); 00348 } 00349 00350 /// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 00351 /// from Sidx, resolve to a lockable object. 00352 /// \param Sidx The attribute argument index to start checking with. 00353 /// \param ParamIdxOk Whether an argument can be indexing into a function 00354 /// parameter list. 00355 static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 00356 const AttributeList &Attr, 00357 SmallVectorImpl<Expr*> &Args, 00358 int Sidx = 0, 00359 bool ParamIdxOk = false) { 00360 for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 00361 Expr *ArgExp = Attr.getArg(Idx); 00362 00363 if (ArgExp->isTypeDependent()) { 00364 // FIXME -- need to check this again on template instantiation 00365 Args.push_back(ArgExp); 00366 continue; 00367 } 00368 00369 if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 00370 // Ignore empty strings without warnings 00371 if (StrLit->getLength() == 0) 00372 continue; 00373 00374 // We allow constant strings to be used as a placeholder for expressions 00375 // that are not valid C++ syntax, but warn that they are ignored. 00376 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 00377 Attr.getName(); 00378 continue; 00379 } 00380 00381 QualType ArgTy = ArgExp->getType(); 00382 00383 // A pointer to member expression of the form &MyClass::mu is treated 00384 // specially -- we need to look at the type of the member. 00385 if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 00386 if (UOp->getOpcode() == UO_AddrOf) 00387 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 00388 if (DRE->getDecl()->isCXXInstanceMember()) 00389 ArgTy = DRE->getDecl()->getType(); 00390 00391 // First see if we can just cast to record type, or point to record type. 00392 const RecordType *RT = getRecordType(ArgTy); 00393 00394 // Now check if we index into a record type function param. 00395 if(!RT && ParamIdxOk) { 00396 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 00397 IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 00398 if(FD && IL) { 00399 unsigned int NumParams = FD->getNumParams(); 00400 llvm::APInt ArgValue = IL->getValue(); 00401 uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 00402 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 00403 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 00404 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 00405 << Attr.getName() << Idx + 1 << NumParams; 00406 continue; 00407 } 00408 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 00409 } 00410 } 00411 00412 checkForLockableRecord(S, D, Attr, ArgTy); 00413 00414 Args.push_back(ArgExp); 00415 } 00416 } 00417 00418 //===----------------------------------------------------------------------===// 00419 // Attribute Implementations 00420 //===----------------------------------------------------------------------===// 00421 00422 // FIXME: All this manual attribute parsing code is gross. At the 00423 // least add some helper functions to check most argument patterns (# 00424 // and types of args). 00425 00426 static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 00427 bool pointer = false) { 00428 assert(!Attr.isInvalid()); 00429 00430 if (!checkAttributeNumArgs(S, Attr, 0)) 00431 return; 00432 00433 // D must be either a member field or global (potentially shared) variable. 00434 if (!mayBeSharedVariable(D)) { 00435 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00436 << Attr.getName() << ExpectedFieldOrGlobalVar; 00437 return; 00438 } 00439 00440 if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 00441 return; 00442 00443 if (pointer) 00444 D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 00445 else 00446 D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 00447 } 00448 00449 static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 00450 bool pointer = false) { 00451 assert(!Attr.isInvalid()); 00452 00453 if (!checkAttributeNumArgs(S, Attr, 1)) 00454 return; 00455 00456 // D must be either a member field or global (potentially shared) variable. 00457 if (!mayBeSharedVariable(D)) { 00458 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00459 << Attr.getName() << ExpectedFieldOrGlobalVar; 00460 return; 00461 } 00462 00463 if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 00464 return; 00465 00466 SmallVector<Expr*, 1> Args; 00467 // check that all arguments are lockable objects 00468 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 00469 unsigned Size = Args.size(); 00470 if (Size != 1) 00471 return; 00472 Expr *Arg = Args[0]; 00473 00474 if (pointer) 00475 D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 00476 S.Context, Arg)); 00477 else 00478 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 00479 } 00480 00481 00482 static void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 00483 bool scoped = false) { 00484 assert(!Attr.isInvalid()); 00485 00486 if (!checkAttributeNumArgs(S, Attr, 0)) 00487 return; 00488 00489 // FIXME: Lockable structs for C code. 00490 if (!isa<CXXRecordDecl>(D)) { 00491 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00492 << Attr.getName() << ExpectedClass; 00493 return; 00494 } 00495 00496 if (scoped) 00497 D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 00498 else 00499 D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 00500 } 00501 00502 static void handleNoThreadSafetyAttr(Sema &S, Decl *D, 00503 const AttributeList &Attr) { 00504 assert(!Attr.isInvalid()); 00505 00506 if (!checkAttributeNumArgs(S, Attr, 0)) 00507 return; 00508 00509 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00510 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00511 << Attr.getName() << ExpectedFunctionOrMethod; 00512 return; 00513 } 00514 00515 D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 00516 S.Context)); 00517 } 00518 00519 static void handleNoAddressSafetyAttr(Sema &S, Decl *D, 00520 const AttributeList &Attr) { 00521 assert(!Attr.isInvalid()); 00522 00523 if (!checkAttributeNumArgs(S, Attr, 0)) 00524 return; 00525 00526 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00527 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00528 << Attr.getName() << ExpectedFunctionOrMethod; 00529 return; 00530 } 00531 00532 D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), 00533 S.Context)); 00534 } 00535 00536 static void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 00537 bool before) { 00538 assert(!Attr.isInvalid()); 00539 00540 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00541 return; 00542 00543 // D must be either a member field or global (potentially shared) variable. 00544 ValueDecl *VD = dyn_cast<ValueDecl>(D); 00545 if (!VD || !mayBeSharedVariable(D)) { 00546 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00547 << Attr.getName() << ExpectedFieldOrGlobalVar; 00548 return; 00549 } 00550 00551 // Check that this attribute only applies to lockable types. 00552 QualType QT = VD->getType(); 00553 if (!QT->isDependentType()) { 00554 const RecordType *RT = getRecordType(QT); 00555 if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 00556 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 00557 << Attr.getName(); 00558 return; 00559 } 00560 } 00561 00562 SmallVector<Expr*, 1> Args; 00563 // Check that all arguments are lockable objects. 00564 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 00565 unsigned Size = Args.size(); 00566 if (Size == 0) 00567 return; 00568 Expr **StartArg = &Args[0]; 00569 00570 if (before) 00571 D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 00572 StartArg, Size)); 00573 else 00574 D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 00575 StartArg, Size)); 00576 } 00577 00578 static void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 00579 bool exclusive = false) { 00580 assert(!Attr.isInvalid()); 00581 00582 // zero or more arguments ok 00583 00584 // check that the attribute is applied to a function 00585 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00586 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00587 << Attr.getName() << ExpectedFunctionOrMethod; 00588 return; 00589 } 00590 00591 // check that all arguments are lockable objects 00592 SmallVector<Expr*, 1> Args; 00593 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 00594 unsigned Size = Args.size(); 00595 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 00596 00597 if (exclusive) 00598 D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 00599 S.Context, StartArg, 00600 Size)); 00601 else 00602 D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 00603 S.Context, StartArg, 00604 Size)); 00605 } 00606 00607 static void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 00608 bool exclusive = false) { 00609 assert(!Attr.isInvalid()); 00610 00611 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00612 return; 00613 00614 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00615 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00616 << Attr.getName() << ExpectedFunctionOrMethod; 00617 return; 00618 } 00619 00620 if (!isIntOrBool(Attr.getArg(0))) { 00621 S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 00622 << Attr.getName(); 00623 return; 00624 } 00625 00626 SmallVector<Expr*, 2> Args; 00627 // check that all arguments are lockable objects 00628 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1); 00629 unsigned Size = Args.size(); 00630 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 00631 00632 if (exclusive) 00633 D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 00634 S.Context, 00635 Attr.getArg(0), 00636 StartArg, Size)); 00637 else 00638 D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 00639 S.Context, 00640 Attr.getArg(0), 00641 StartArg, Size)); 00642 } 00643 00644 static void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 00645 bool exclusive = false) { 00646 assert(!Attr.isInvalid()); 00647 00648 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00649 return; 00650 00651 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00652 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00653 << Attr.getName() << ExpectedFunctionOrMethod; 00654 return; 00655 } 00656 00657 // check that all arguments are lockable objects 00658 SmallVector<Expr*, 1> Args; 00659 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 00660 unsigned Size = Args.size(); 00661 if (Size == 0) 00662 return; 00663 Expr **StartArg = &Args[0]; 00664 00665 if (exclusive) 00666 D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 00667 S.Context, StartArg, 00668 Size)); 00669 else 00670 D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 00671 S.Context, StartArg, 00672 Size)); 00673 } 00674 00675 static void handleUnlockFunAttr(Sema &S, Decl *D, 00676 const AttributeList &Attr) { 00677 assert(!Attr.isInvalid()); 00678 00679 // zero or more arguments ok 00680 00681 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00682 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00683 << Attr.getName() << ExpectedFunctionOrMethod; 00684 return; 00685 } 00686 00687 // check that all arguments are lockable objects 00688 SmallVector<Expr*, 1> Args; 00689 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 00690 unsigned Size = Args.size(); 00691 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 00692 00693 D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 00694 StartArg, Size)); 00695 } 00696 00697 static void handleLockReturnedAttr(Sema &S, Decl *D, 00698 const AttributeList &Attr) { 00699 assert(!Attr.isInvalid()); 00700 00701 if (!checkAttributeNumArgs(S, Attr, 1)) 00702 return; 00703 Expr *Arg = Attr.getArg(0); 00704 00705 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00706 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00707 << Attr.getName() << ExpectedFunctionOrMethod; 00708 return; 00709 } 00710 00711 if (Arg->isTypeDependent()) 00712 return; 00713 00714 // check that the argument is lockable object 00715 SmallVector<Expr*, 1> Args; 00716 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 00717 unsigned Size = Args.size(); 00718 if (Size == 0) 00719 return; 00720 00721 D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, 00722 Args[0])); 00723 } 00724 00725 static void handleLocksExcludedAttr(Sema &S, Decl *D, 00726 const AttributeList &Attr) { 00727 assert(!Attr.isInvalid()); 00728 00729 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 00730 return; 00731 00732 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 00733 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00734 << Attr.getName() << ExpectedFunctionOrMethod; 00735 return; 00736 } 00737 00738 // check that all arguments are lockable objects 00739 SmallVector<Expr*, 1> Args; 00740 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 00741 unsigned Size = Args.size(); 00742 if (Size == 0) 00743 return; 00744 Expr **StartArg = &Args[0]; 00745 00746 D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 00747 StartArg, Size)); 00748 } 00749 00750 00751 static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 00752 const AttributeList &Attr) { 00753 TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 00754 if (tDecl == 0) { 00755 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 00756 return; 00757 } 00758 00759 QualType curType = tDecl->getUnderlyingType(); 00760 00761 Expr *sizeExpr; 00762 00763 // Special case where the argument is a template id. 00764 if (Attr.getParameterName()) { 00765 CXXScopeSpec SS; 00766 SourceLocation TemplateKWLoc; 00767 UnqualifiedId id; 00768 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 00769 00770 ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, 00771 false, false); 00772 if (Size.isInvalid()) 00773 return; 00774 00775 sizeExpr = Size.get(); 00776 } else { 00777 // check the attribute arguments. 00778 if (!checkAttributeNumArgs(S, Attr, 1)) 00779 return; 00780 00781 sizeExpr = Attr.getArg(0); 00782 } 00783 00784 // Instantiate/Install the vector type, and let Sema build the type for us. 00785 // This will run the reguired checks. 00786 QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 00787 if (!T.isNull()) { 00788 // FIXME: preserve the old source info. 00789 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 00790 00791 // Remember this typedef decl, we will need it later for diagnostics. 00792 S.ExtVectorDecls.push_back(tDecl); 00793 } 00794 } 00795 00796 static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00797 // check the attribute arguments. 00798 if (!checkAttributeNumArgs(S, Attr, 0)) 00799 return; 00800 00801 if (TagDecl *TD = dyn_cast<TagDecl>(D)) 00802 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 00803 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 00804 // If the alignment is less than or equal to 8 bits, the packed attribute 00805 // has no effect. 00806 if (!FD->getType()->isIncompleteType() && 00807 S.Context.getTypeAlign(FD->getType()) <= 8) 00808 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 00809 << Attr.getName() << FD->getType(); 00810 else 00811 FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 00812 } else 00813 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 00814 } 00815 00816 static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00817 if (TagDecl *TD = dyn_cast<TagDecl>(D)) 00818 TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 00819 else 00820 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 00821 } 00822 00823 static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 00824 // check the attribute arguments. 00825 if (!checkAttributeNumArgs(S, Attr, 0)) 00826 return; 00827 00828 // The IBAction attributes only apply to instance methods. 00829 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 00830 if (MD->isInstanceMethod()) { 00831 D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 00832 return; 00833 } 00834 00835 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 00836 } 00837 00838 static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 00839 // The IBOutlet/IBOutletCollection attributes only apply to instance 00840 // variables or properties of Objective-C classes. The outlet must also 00841 // have an object reference type. 00842 if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 00843 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 00844 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 00845 << Attr.getName() << VD->getType() << 0; 00846 return false; 00847 } 00848 } 00849 else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 00850 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 00851 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 00852 << Attr.getName() << PD->getType() << 1; 00853 return false; 00854 } 00855 } 00856 else { 00857 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 00858 return false; 00859 } 00860 00861 return true; 00862 } 00863 00864 static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 00865 // check the attribute arguments. 00866 if (!checkAttributeNumArgs(S, Attr, 0)) 00867 return; 00868 00869 if (!checkIBOutletCommon(S, D, Attr)) 00870 return; 00871 00872 D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 00873 } 00874 00875 static void handleIBOutletCollection(Sema &S, Decl *D, 00876 const AttributeList &Attr) { 00877 00878 // The iboutletcollection attribute can have zero or one arguments. 00879 if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 00880 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 00881 return; 00882 } 00883 00884 if (!checkIBOutletCommon(S, D, Attr)) 00885 return; 00886 00887 IdentifierInfo *II = Attr.getParameterName(); 00888 if (!II) 00889 II = &S.Context.Idents.get("NSObject"); 00890 00891 ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 00892 S.getScopeForContext(D->getDeclContext()->getParent())); 00893 if (!TypeRep) { 00894 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 00895 return; 00896 } 00897 QualType QT = TypeRep.get(); 00898 // Diagnose use of non-object type in iboutletcollection attribute. 00899 // FIXME. Gnu attribute extension ignores use of builtin types in 00900 // attributes. So, __attribute__((iboutletcollection(char))) will be 00901 // treated as __attribute__((iboutletcollection())). 00902 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 00903 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 00904 return; 00905 } 00906 D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 00907 QT, Attr.getParameterLoc())); 00908 } 00909 00910 static void possibleTransparentUnionPointerType(QualType &T) { 00911 if (const RecordType *UT = T->getAsUnionType()) 00912 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 00913 RecordDecl *UD = UT->getDecl(); 00914 for (RecordDecl::field_iterator it = UD->field_begin(), 00915 itend = UD->field_end(); it != itend; ++it) { 00916 QualType QT = it->getType(); 00917 if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 00918 T = QT; 00919 return; 00920 } 00921 } 00922 } 00923 } 00924 00925 static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 00926 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 00927 // ignore it as well 00928 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 00929 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 00930 << Attr.getName() << ExpectedFunction; 00931 return; 00932 } 00933 00934 // In C++ the implicit 'this' function parameter also counts, and they are 00935 // counted from one. 00936 bool HasImplicitThisParam = isInstanceMethod(D); 00937 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 00938 00939 // The nonnull attribute only applies to pointers. 00940 SmallVector<unsigned, 10> NonNullArgs; 00941 00942 for (AttributeList::arg_iterator I=Attr.arg_begin(), 00943 E=Attr.arg_end(); I!=E; ++I) { 00944 00945 00946 // The argument must be an integer constant expression. 00947 Expr *Ex = *I; 00948 llvm::APSInt ArgNum(32); 00949 if (Ex->isTypeDependent() || Ex->isValueDependent() || 00950 !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 00951 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 00952 << "nonnull" << Ex->getSourceRange(); 00953 return; 00954 } 00955 00956 unsigned x = (unsigned) ArgNum.getZExtValue(); 00957 00958 if (x < 1 || x > NumArgs) { 00959 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 00960 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 00961 return; 00962 } 00963 00964 --x; 00965 if (HasImplicitThisParam) { 00966 if (x == 0) { 00967 S.Diag(Attr.getLoc(), 00968 diag::err_attribute_invalid_implicit_this_argument) 00969 << "nonnull" << Ex->getSourceRange(); 00970 return; 00971 } 00972 --x; 00973 } 00974 00975 // Is the function argument a pointer type? 00976 QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 00977 possibleTransparentUnionPointerType(T); 00978 00979 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 00980 // FIXME: Should also highlight argument in decl. 00981 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 00982 << "nonnull" << Ex->getSourceRange(); 00983 continue; 00984 } 00985 00986 NonNullArgs.push_back(x); 00987 } 00988 00989 // If no arguments were specified to __attribute__((nonnull)) then all pointer 00990 // arguments have a nonnull attribute. 00991 if (NonNullArgs.empty()) { 00992 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 00993 QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 00994 possibleTransparentUnionPointerType(T); 00995 if (T->isAnyPointerType() || T->isBlockPointerType()) 00996 NonNullArgs.push_back(I); 00997 } 00998 00999 // No pointer arguments? 01000 if (NonNullArgs.empty()) { 01001 // Warn the trivial case only if attribute is not coming from a 01002 // macro instantiation. 01003 if (Attr.getLoc().isFileID()) 01004 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 01005 return; 01006 } 01007 } 01008 01009 unsigned* start = &NonNullArgs[0]; 01010 unsigned size = NonNullArgs.size(); 01011 llvm::array_pod_sort(start, start + size); 01012 D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 01013 size)); 01014 } 01015 01016 static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 01017 // This attribute must be applied to a function declaration. 01018 // The first argument to the attribute must be a string, 01019 // the name of the resource, for example "malloc". 01020 // The following arguments must be argument indexes, the arguments must be 01021 // of integer type for Returns, otherwise of pointer type. 01022 // The difference between Holds and Takes is that a pointer may still be used 01023 // after being held. free() should be __attribute((ownership_takes)), whereas 01024 // a list append function may well be __attribute((ownership_holds)). 01025 01026 if (!AL.getParameterName()) { 01027 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 01028 << AL.getName()->getName() << 1; 01029 return; 01030 } 01031 // Figure out our Kind, and check arguments while we're at it. 01032 OwnershipAttr::OwnershipKind K; 01033 switch (AL.getKind()) { 01034 case AttributeList::AT_ownership_takes: 01035 K = OwnershipAttr::Takes; 01036 if (AL.getNumArgs() < 1) { 01037 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 01038 return; 01039 } 01040 break; 01041 case AttributeList::AT_ownership_holds: 01042 K = OwnershipAttr::Holds; 01043 if (AL.getNumArgs() < 1) { 01044 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 01045 return; 01046 } 01047 break; 01048 case AttributeList::AT_ownership_returns: 01049 K = OwnershipAttr::Returns; 01050 if (AL.getNumArgs() > 1) { 01051 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 01052 << AL.getNumArgs() + 1; 01053 return; 01054 } 01055 break; 01056 default: 01057 // This should never happen given how we are called. 01058 llvm_unreachable("Unknown ownership attribute"); 01059 } 01060 01061 if (!isFunction(D) || !hasFunctionProto(D)) { 01062 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 01063 << AL.getName() << ExpectedFunction; 01064 return; 01065 } 01066 01067 // In C++ the implicit 'this' function parameter also counts, and they are 01068 // counted from one. 01069 bool HasImplicitThisParam = isInstanceMethod(D); 01070 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 01071 01072 StringRef Module = AL.getParameterName()->getName(); 01073 01074 // Normalize the argument, __foo__ becomes foo. 01075 if (Module.startswith("__") && Module.endswith("__")) 01076 Module = Module.substr(2, Module.size() - 4); 01077 01078 SmallVector<unsigned, 10> OwnershipArgs; 01079 01080 for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 01081 ++I) { 01082 01083 Expr *IdxExpr = *I; 01084 llvm::APSInt ArgNum(32); 01085 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 01086 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 01087 S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 01088 << AL.getName()->getName() << IdxExpr->getSourceRange(); 01089 continue; 01090 } 01091 01092 unsigned x = (unsigned) ArgNum.getZExtValue(); 01093 01094 if (x > NumArgs || x < 1) { 01095 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 01096 << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 01097 continue; 01098 } 01099 --x; 01100 if (HasImplicitThisParam) { 01101 if (x == 0) { 01102 S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 01103 << "ownership" << IdxExpr->getSourceRange(); 01104 return; 01105 } 01106 --x; 01107 } 01108 01109 switch (K) { 01110 case OwnershipAttr::Takes: 01111 case OwnershipAttr::Holds: { 01112 // Is the function argument a pointer type? 01113 QualType T = getFunctionOrMethodArgType(D, x); 01114 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 01115 // FIXME: Should also highlight argument in decl. 01116 S.Diag(AL.getLoc(), diag::err_ownership_type) 01117 << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 01118 << "pointer" 01119 << IdxExpr->getSourceRange(); 01120 continue; 01121 } 01122 break; 01123 } 01124 case OwnershipAttr::Returns: { 01125 if (AL.getNumArgs() > 1) { 01126 // Is the function argument an integer type? 01127 Expr *IdxExpr = AL.getArg(0); 01128 llvm::APSInt ArgNum(32); 01129 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 01130 || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 01131 S.Diag(AL.getLoc(), diag::err_ownership_type) 01132 << "ownership_returns" << "integer" 01133 << IdxExpr->getSourceRange(); 01134 return; 01135 } 01136 } 01137 break; 01138 } 01139 } // switch 01140 01141 // Check we don't have a conflict with another ownership attribute. 01142 for (specific_attr_iterator<OwnershipAttr> 01143 i = D->specific_attr_begin<OwnershipAttr>(), 01144 e = D->specific_attr_end<OwnershipAttr>(); 01145 i != e; ++i) { 01146 if ((*i)->getOwnKind() != K) { 01147 for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 01148 I!=E; ++I) { 01149 if (x == *I) { 01150 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 01151 << AL.getName()->getName() << "ownership_*"; 01152 } 01153 } 01154 } 01155 } 01156 OwnershipArgs.push_back(x); 01157 } 01158 01159 unsigned* start = OwnershipArgs.data(); 01160 unsigned size = OwnershipArgs.size(); 01161 llvm::array_pod_sort(start, start + size); 01162 01163 if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 01164 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 01165 return; 01166 } 01167 01168 D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 01169 start, size)); 01170 } 01171 01172 /// Whether this declaration has internal linkage for the purposes of 01173 /// things that want to complain about things not have internal linkage. 01174 static bool hasEffectivelyInternalLinkage(NamedDecl *D) { 01175 switch (D->getLinkage()) { 01176 case NoLinkage: 01177 case InternalLinkage: 01178 return true; 01179 01180 // Template instantiations that go from external to unique-external 01181 // shouldn't get diagnosed. 01182 case UniqueExternalLinkage: 01183 return true; 01184 01185 case ExternalLinkage: 01186 return false; 01187 } 01188 llvm_unreachable("unknown linkage kind!"); 01189 } 01190 01191 static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01192 // Check the attribute arguments. 01193 if (Attr.getNumArgs() > 1) { 01194 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01195 return; 01196 } 01197 01198 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 01199 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 01200 << Attr.getName() << ExpectedVariableOrFunction; 01201 return; 01202 } 01203 01204 NamedDecl *nd = cast<NamedDecl>(D); 01205 01206 // gcc rejects 01207 // class c { 01208 // static int a __attribute__((weakref ("v2"))); 01209 // static int b() __attribute__((weakref ("f3"))); 01210 // }; 01211 // and ignores the attributes of 01212 // void f(void) { 01213 // static int a __attribute__((weakref ("v2"))); 01214 // } 01215 // we reject them 01216 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 01217 if (!Ctx->isFileContext()) { 01218 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 01219 nd->getNameAsString(); 01220 return; 01221 } 01222 01223 // The GCC manual says 01224 // 01225 // At present, a declaration to which `weakref' is attached can only 01226 // be `static'. 01227 // 01228 // It also says 01229 // 01230 // Without a TARGET, 01231 // given as an argument to `weakref' or to `alias', `weakref' is 01232 // equivalent to `weak'. 01233 // 01234 // gcc 4.4.1 will accept 01235 // int a7 __attribute__((weakref)); 01236 // as 01237 // int a7 __attribute__((weak)); 01238 // This looks like a bug in gcc. We reject that for now. We should revisit 01239 // it if this behaviour is actually used. 01240 01241 if (!hasEffectivelyInternalLinkage(nd)) { 01242 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 01243 return; 01244 } 01245 01246 // GCC rejects 01247 // static ((alias ("y"), weakref)). 01248 // Should we? How to check that weakref is before or after alias? 01249 01250 if (Attr.getNumArgs() == 1) { 01251 Expr *Arg = Attr.getArg(0); 01252 Arg = Arg->IgnoreParenCasts(); 01253 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 01254 01255 if (!Str || !Str->isAscii()) { 01256 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 01257 << "weakref" << 1; 01258 return; 01259 } 01260 // GCC will accept anything as the argument of weakref. Should we 01261 // check for an existing decl? 01262 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 01263 Str->getString())); 01264 } 01265 01266 D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 01267 } 01268 01269 static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01270 // check the attribute arguments. 01271 if (Attr.getNumArgs() != 1) { 01272 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 01273 return; 01274 } 01275 01276 Expr *Arg = Attr.getArg(0); 01277 Arg = Arg->IgnoreParenCasts(); 01278 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 01279 01280 if (!Str || !Str->isAscii()) { 01281 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 01282 << "alias" << 1; 01283 return; 01284 } 01285 01286 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 01287 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 01288 return; 01289 } 01290 01291 // FIXME: check if target symbol exists in current file 01292 01293 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 01294 Str->getString())); 01295 } 01296 01297 static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01298 // Check the attribute arguments. 01299 if (!checkAttributeNumArgs(S, Attr, 0)) 01300 return; 01301 01302 if (!isa<FunctionDecl>(D)) { 01303 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01304 << Attr.getName() << ExpectedFunction; 01305 return; 01306 } 01307 01308 if (D->hasAttr<HotAttr>()) { 01309 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 01310 << Attr.getName() << "hot"; 01311 return; 01312 } 01313 01314 D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context)); 01315 } 01316 01317 static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01318 // Check the attribute arguments. 01319 if (!checkAttributeNumArgs(S, Attr, 0)) 01320 return; 01321 01322 if (!isa<FunctionDecl>(D)) { 01323 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01324 << Attr.getName() << ExpectedFunction; 01325 return; 01326 } 01327 01328 if (D->hasAttr<ColdAttr>()) { 01329 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 01330 << Attr.getName() << "cold"; 01331 return; 01332 } 01333 01334 D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context)); 01335 } 01336 01337 static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01338 // Check the attribute arguments. 01339 if (!checkAttributeNumArgs(S, Attr, 0)) 01340 return; 01341 01342 if (!isa<FunctionDecl>(D)) { 01343 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01344 << Attr.getName() << ExpectedFunction; 01345 return; 01346 } 01347 01348 D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 01349 } 01350 01351 static void handleAlwaysInlineAttr(Sema &S, Decl *D, 01352 const AttributeList &Attr) { 01353 // Check the attribute arguments. 01354 if (Attr.hasParameterOrArguments()) { 01355 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01356 return; 01357 } 01358 01359 if (!isa<FunctionDecl>(D)) { 01360 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01361 << Attr.getName() << ExpectedFunction; 01362 return; 01363 } 01364 01365 D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 01366 } 01367 01368 static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01369 // Check the attribute arguments. 01370 if (Attr.hasParameterOrArguments()) { 01371 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01372 return; 01373 } 01374 01375 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 01376 QualType RetTy = FD->getResultType(); 01377 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 01378 D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 01379 return; 01380 } 01381 } 01382 01383 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 01384 } 01385 01386 static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01387 // check the attribute arguments. 01388 if (!checkAttributeNumArgs(S, Attr, 0)) 01389 return; 01390 01391 D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 01392 } 01393 01394 static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01395 assert(!Attr.isInvalid()); 01396 if (isa<VarDecl>(D)) 01397 D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 01398 else 01399 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01400 << Attr.getName() << ExpectedVariable; 01401 } 01402 01403 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01404 assert(!Attr.isInvalid()); 01405 if (isa<VarDecl>(D)) 01406 D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 01407 else 01408 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01409 << Attr.getName() << ExpectedVariable; 01410 } 01411 01412 static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 01413 if (hasDeclarator(D)) return; 01414 01415 if (S.CheckNoReturnAttr(attr)) return; 01416 01417 if (!isa<ObjCMethodDecl>(D)) { 01418 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01419 << attr.getName() << ExpectedFunctionOrMethod; 01420 return; 01421 } 01422 01423 D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 01424 } 01425 01426 bool Sema::CheckNoReturnAttr(const AttributeList &attr) { 01427 if (attr.hasParameterOrArguments()) { 01428 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01429 attr.setInvalid(); 01430 return true; 01431 } 01432 01433 return false; 01434 } 01435 01436 static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 01437 const AttributeList &Attr) { 01438 01439 // The checking path for 'noreturn' and 'analyzer_noreturn' are different 01440 // because 'analyzer_noreturn' does not impact the type. 01441 01442 if(!checkAttributeNumArgs(S, Attr, 0)) 01443 return; 01444 01445 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 01446 ValueDecl *VD = dyn_cast<ValueDecl>(D); 01447 if (VD == 0 || (!VD->getType()->isBlockPointerType() 01448 && !VD->getType()->isFunctionPointerType())) { 01449 S.Diag(Attr.getLoc(), 01450 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 01451 : diag::warn_attribute_wrong_decl_type) 01452 << Attr.getName() << ExpectedFunctionMethodOrBlock; 01453 return; 01454 } 01455 } 01456 01457 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 01458 } 01459 01460 // PS3 PPU-specific. 01461 static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01462 /* 01463 Returning a Vector Class in Registers 01464 01465 According to the PPU ABI specifications, a class with a single member of 01466 vector type is returned in memory when used as the return value of a function. 01467 This results in inefficient code when implementing vector classes. To return 01468 the value in a single vector register, add the vecreturn attribute to the 01469 class definition. This attribute is also applicable to struct types. 01470 01471 Example: 01472 01473 struct Vector 01474 { 01475 __vector float xyzw; 01476 } __attribute__((vecreturn)); 01477 01478 Vector Add(Vector lhs, Vector rhs) 01479 { 01480 Vector result; 01481 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 01482 return result; // This will be returned in a register 01483 } 01484 */ 01485 if (!isa<RecordDecl>(D)) { 01486 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 01487 << Attr.getName() << ExpectedClass; 01488 return; 01489 } 01490 01491 if (D->getAttr<VecReturnAttr>()) { 01492 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 01493 return; 01494 } 01495 01496 RecordDecl *record = cast<RecordDecl>(D); 01497 int count = 0; 01498 01499 if (!isa<CXXRecordDecl>(record)) { 01500 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 01501 return; 01502 } 01503 01504 if (!cast<CXXRecordDecl>(record)->isPOD()) { 01505 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 01506 return; 01507 } 01508 01509 for (RecordDecl::field_iterator iter = record->field_begin(); 01510 iter != record->field_end(); iter++) { 01511 if ((count == 1) || !iter->getType()->isVectorType()) { 01512 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 01513 return; 01514 } 01515 count++; 01516 } 01517 01518 D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 01519 } 01520 01521 static void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01522 if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 01523 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 01524 << Attr.getName() << ExpectedFunctionMethodOrParameter; 01525 return; 01526 } 01527 // FIXME: Actually store the attribute on the declaration 01528 } 01529 01530 static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01531 // check the attribute arguments. 01532 if (Attr.hasParameterOrArguments()) { 01533 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01534 return; 01535 } 01536 01537 if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 01538 !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) { 01539 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01540 << Attr.getName() << ExpectedVariableFunctionOrLabel; 01541 return; 01542 } 01543 01544 D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 01545 } 01546 01547 static void handleReturnsTwiceAttr(Sema &S, Decl *D, 01548 const AttributeList &Attr) { 01549 // check the attribute arguments. 01550 if (Attr.hasParameterOrArguments()) { 01551 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01552 return; 01553 } 01554 01555 if (!isa<FunctionDecl>(D)) { 01556 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01557 << Attr.getName() << ExpectedFunction; 01558 return; 01559 } 01560 01561 D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 01562 } 01563 01564 static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01565 // check the attribute arguments. 01566 if (Attr.hasParameterOrArguments()) { 01567 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01568 return; 01569 } 01570 01571 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 01572 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 01573 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 01574 return; 01575 } 01576 } else if (!isFunctionOrMethod(D)) { 01577 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01578 << Attr.getName() << ExpectedVariableOrFunction; 01579 return; 01580 } 01581 01582 D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 01583 } 01584 01585 static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01586 // check the attribute arguments. 01587 if (Attr.getNumArgs() > 1) { 01588 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 01589 return; 01590 } 01591 01592 int priority = 65535; // FIXME: Do not hardcode such constants. 01593 if (Attr.getNumArgs() > 0) { 01594 Expr *E = Attr.getArg(0); 01595 llvm::APSInt Idx(32); 01596 if (E->isTypeDependent() || E->isValueDependent() || 01597 !E->isIntegerConstantExpr(Idx, S.Context)) { 01598 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 01599 << "constructor" << 1 << E->getSourceRange(); 01600 return; 01601 } 01602 priority = Idx.getZExtValue(); 01603 } 01604 01605 if (!isa<FunctionDecl>(D)) { 01606 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01607 << Attr.getName() << ExpectedFunction; 01608 return; 01609 } 01610 01611 D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 01612 priority)); 01613 } 01614 01615 static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01616 // check the attribute arguments. 01617 if (Attr.getNumArgs() > 1) { 01618 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 01619 return; 01620 } 01621 01622 int priority = 65535; // FIXME: Do not hardcode such constants. 01623 if (Attr.getNumArgs() > 0) { 01624 Expr *E = Attr.getArg(0); 01625 llvm::APSInt Idx(32); 01626 if (E->isTypeDependent() || E->isValueDependent() || 01627 !E->isIntegerConstantExpr(Idx, S.Context)) { 01628 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 01629 << "destructor" << 1 << E->getSourceRange(); 01630 return; 01631 } 01632 priority = Idx.getZExtValue(); 01633 } 01634 01635 if (!isa<FunctionDecl>(D)) { 01636 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 01637 << Attr.getName() << ExpectedFunction; 01638 return; 01639 } 01640 01641 D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 01642 priority)); 01643 } 01644 01645 template <typename AttrTy> 01646 static void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr, 01647 const char *Name) { 01648 unsigned NumArgs = Attr.getNumArgs(); 01649 if (NumArgs > 1) { 01650 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 01651 return; 01652 } 01653 01654 // Handle the case where the attribute has a text message. 01655 StringRef Str; 01656 if (NumArgs == 1) { 01657 StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 01658 if (!SE) { 01659 S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 01660 << Name; 01661 return; 01662 } 01663 Str = SE->getString(); 01664 } 01665 01666 D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str)); 01667 } 01668 01669 static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 01670 const AttributeList &Attr) { 01671 unsigned NumArgs = Attr.getNumArgs(); 01672 if (NumArgs > 0) { 01673 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 01674 return; 01675 } 01676 01677 D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 01678 Attr.getRange(), S.Context)); 01679 } 01680 01681 static void handleObjCRootClassAttr(Sema &S, Decl *D, 01682 const AttributeList &Attr) { 01683 if (!isa<ObjCInterfaceDecl>(D)) { 01684 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 01685 return; 01686 } 01687 01688 unsigned NumArgs = Attr.getNumArgs(); 01689 if (NumArgs > 0) { 01690 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 01691 return; 01692 } 01693 01694 D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context)); 01695 } 01696 01697 static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 01698 const AttributeList &Attr) { 01699 if (!isa<ObjCInterfaceDecl>(D)) { 01700 S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); 01701 return; 01702 } 01703 01704 unsigned NumArgs = Attr.getNumArgs(); 01705 if (NumArgs > 0) { 01706 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 01707 return; 01708 } 01709 01710 D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr( 01711 Attr.getRange(), S.Context)); 01712 } 01713 01714 static bool checkAvailabilityAttr(Sema &S, SourceRange Range, 01715 IdentifierInfo *Platform, 01716 VersionTuple Introduced, 01717 VersionTuple Deprecated, 01718 VersionTuple Obsoleted) { 01719 StringRef PlatformName 01720 = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 01721 if (PlatformName.empty()) 01722 PlatformName = Platform->getName(); 01723 01724 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 01725 // of these steps are needed). 01726 if (!Introduced.empty() && !Deprecated.empty() && 01727 !(Introduced <= Deprecated)) { 01728 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 01729 << 1 << PlatformName << Deprecated.getAsString() 01730 << 0 << Introduced.getAsString(); 01731 return true; 01732 } 01733 01734 if (!Introduced.empty() && !Obsoleted.empty() && 01735 !(Introduced <= Obsoleted)) { 01736 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 01737 << 2 << PlatformName << Obsoleted.getAsString() 01738 << 0 << Introduced.getAsString(); 01739 return true; 01740 } 01741 01742 if (!Deprecated.empty() && !Obsoleted.empty() && 01743 !(Deprecated <= Obsoleted)) { 01744 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 01745 << 2 << PlatformName << Obsoleted.getAsString() 01746 << 1 << Deprecated.getAsString(); 01747 return true; 01748 } 01749 01750 return false; 01751 } 01752 01753 AvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range, 01754 IdentifierInfo *Platform, 01755 VersionTuple Introduced, 01756 VersionTuple Deprecated, 01757 VersionTuple Obsoleted, 01758 bool IsUnavailable, 01759 StringRef Message) { 01760 VersionTuple MergedIntroduced = Introduced; 01761 VersionTuple MergedDeprecated = Deprecated; 01762 VersionTuple MergedObsoleted = Obsoleted; 01763 bool FoundAny = false; 01764 01765 if (D->hasAttrs()) { 01766 AttrVec &Attrs = D->getAttrs(); 01767 for (unsigned i = 0, e = Attrs.size(); i != e;) { 01768 const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); 01769 if (!OldAA) { 01770 ++i; 01771 continue; 01772 } 01773 01774 IdentifierInfo *OldPlatform = OldAA->getPlatform(); 01775 if (OldPlatform != Platform) { 01776 ++i; 01777 continue; 01778 } 01779 01780 FoundAny = true; 01781 VersionTuple OldIntroduced = OldAA->getIntroduced(); 01782 VersionTuple OldDeprecated = OldAA->getDeprecated(); 01783 VersionTuple OldObsoleted = OldAA->getObsoleted(); 01784 bool OldIsUnavailable = OldAA->getUnavailable(); 01785 StringRef OldMessage = OldAA->getMessage(); 01786 01787 if ((!OldIntroduced.empty() && !Introduced.empty() && 01788 OldIntroduced != Introduced) || 01789 (!OldDeprecated.empty() && !Deprecated.empty() && 01790 OldDeprecated != Deprecated) || 01791 (!OldObsoleted.empty() && !Obsoleted.empty() && 01792 OldObsoleted != Obsoleted) || 01793 (OldIsUnavailable != IsUnavailable) || 01794 (OldMessage != Message)) { 01795 Diag(OldAA->getLocation(), diag::warn_mismatched_availability); 01796 Diag(Range.getBegin(), diag::note_previous_attribute); 01797 Attrs.erase(Attrs.begin() + i); 01798 --e; 01799 continue; 01800 } 01801 01802 VersionTuple MergedIntroduced2 = MergedIntroduced; 01803 VersionTuple MergedDeprecated2 = MergedDeprecated; 01804 VersionTuple MergedObsoleted2 = MergedObsoleted; 01805 01806 if (MergedIntroduced2.empty()) 01807 MergedIntroduced2 = OldIntroduced; 01808 if (MergedDeprecated2.empty()) 01809 MergedDeprecated2 = OldDeprecated; 01810 if (MergedObsoleted2.empty()) 01811 MergedObsoleted2 = OldObsoleted; 01812 01813 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, 01814 MergedIntroduced2, MergedDeprecated2, 01815 MergedObsoleted2)) { 01816 Attrs.erase(Attrs.begin() + i); 01817 --e; 01818 continue; 01819 } 01820 01821 MergedIntroduced = MergedIntroduced2; 01822 MergedDeprecated = MergedDeprecated2; 01823 MergedObsoleted = MergedObsoleted2; 01824 ++i; 01825 } 01826 } 01827 01828 if (FoundAny && 01829 MergedIntroduced == Introduced && 01830 MergedDeprecated == Deprecated && 01831 MergedObsoleted == Obsoleted) 01832 return NULL; 01833 01834 if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, 01835 MergedDeprecated, MergedObsoleted)) { 01836 return ::new (Context) AvailabilityAttr(Range, Context, Platform, 01837 Introduced, Deprecated, 01838 Obsoleted, IsUnavailable, Message); 01839 } 01840 return NULL; 01841 } 01842 01843 static void handleAvailabilityAttr(Sema &S, Decl *D, 01844 const AttributeList &Attr) { 01845 IdentifierInfo *Platform = Attr.getParameterName(); 01846 SourceLocation PlatformLoc = Attr.getParameterLoc(); 01847 01848 if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty()) 01849 S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 01850 << Platform; 01851 01852 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 01853 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 01854 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 01855 bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 01856 StringRef Str; 01857 const StringLiteral *SE = 01858 dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); 01859 if (SE) 01860 Str = SE->getString(); 01861 01862 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(), 01863 Platform, 01864 Introduced.Version, 01865 Deprecated.Version, 01866 Obsoleted.Version, 01867 IsUnavailable, Str); 01868 if (NewAttr) 01869 D->addAttr(NewAttr); 01870 } 01871 01872 VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, 01873 VisibilityAttr::VisibilityType Vis) { 01874 if (isa<TypedefNameDecl>(D)) { 01875 Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility"; 01876 return NULL; 01877 } 01878 VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>(); 01879 if (ExistingAttr) { 01880 VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility(); 01881 if (ExistingVis == Vis) 01882 return NULL; 01883 Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility); 01884 Diag(Range.getBegin(), diag::note_previous_attribute); 01885 D->dropAttr<VisibilityAttr>(); 01886 } 01887 return ::new (Context) VisibilityAttr(Range, Context, Vis); 01888 } 01889 01890 static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 01891 // check the attribute arguments. 01892 if(!checkAttributeNumArgs(S, Attr, 1)) 01893 return; 01894 01895 Expr *Arg = Attr.getArg(0); 01896 Arg = Arg->IgnoreParenCasts(); 01897 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 01898 01899 if (!Str || !Str->isAscii()) { 01900 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 01901 << "visibility" << 1; 01902 return; 01903 } 01904 01905 StringRef TypeStr = Str->getString(); 01906 VisibilityAttr::VisibilityType type; 01907 01908 if (TypeStr == "default") 01909 type = VisibilityAttr::Default; 01910 else if (TypeStr == "hidden") 01911 type = VisibilityAttr::Hidden; 01912 else if (TypeStr == "internal") 01913 type = VisibilityAttr::Hidden; // FIXME 01914 else if (TypeStr == "protected") { 01915 // Complain about attempts to use protected visibility on targets 01916 // (like Darwin) that don't support it. 01917 if (!S.Context.getTargetInfo().hasProtectedVisibility()) { 01918 S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 01919 type = VisibilityAttr::Default; 01920 } else { 01921 type = VisibilityAttr::Protected; 01922 } 01923 } else { 01924 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 01925 return; 01926 } 01927 01928 VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type); 01929 if (NewAttr) 01930 D->addAttr(NewAttr); 01931 } 01932 01933 static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 01934 const AttributeList &Attr) { 01935 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 01936 if (!method) { 01937 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 01938 << ExpectedMethod; 01939 return; 01940 } 01941 01942 if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 01943 if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 01944 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 01945 << "objc_method_family" << 1; 01946 } else { 01947 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 01948 } 01949 Attr.setInvalid(); 01950 return; 01951 } 01952 01953 StringRef param = Attr.getParameterName()->getName(); 01954 ObjCMethodFamilyAttr::FamilyKind family; 01955 if (param == "none") 01956 family = ObjCMethodFamilyAttr::OMF_None; 01957 else if (param == "alloc") 01958 family = ObjCMethodFamilyAttr::OMF_alloc; 01959 else if (param == "copy") 01960 family = ObjCMethodFamilyAttr::OMF_copy; 01961 else if (param == "init") 01962 family = ObjCMethodFamilyAttr::OMF_init; 01963 else if (param == "mutableCopy") 01964 family = ObjCMethodFamilyAttr::OMF_mutableCopy; 01965 else if (param == "new") 01966 family = ObjCMethodFamilyAttr::OMF_new; 01967 else { 01968 // Just warn and ignore it. This is future-proof against new 01969 // families being used in system headers. 01970 S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 01971 return; 01972 } 01973 01974 if (family == ObjCMethodFamilyAttr::OMF_init && 01975 !method->getResultType()->isObjCObjectPointerType()) { 01976 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 01977 << method->getResultType(); 01978 // Ignore the attribute. 01979 return; 01980 } 01981 01982 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 01983 S.Context, family)); 01984 } 01985 01986 static void handleObjCExceptionAttr(Sema &S, Decl *D, 01987 const AttributeList &Attr) { 01988 if (!checkAttributeNumArgs(S, Attr, 0)) 01989 return; 01990 01991 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 01992 if (OCI == 0) { 01993 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 01994 return; 01995 } 01996 01997 D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 01998 } 01999 02000 static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 02001 if (Attr.getNumArgs() != 0) { 02002 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02003 return; 02004 } 02005 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 02006 QualType T = TD->getUnderlyingType(); 02007 if (!T->isPointerType() || 02008 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 02009 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 02010 return; 02011 } 02012 } 02013 else if (!isa<ObjCPropertyDecl>(D)) { 02014 // It is okay to include this attribute on properties, e.g.: 02015 // 02016 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 02017 // 02018 // In this case it follows tradition and suppresses an error in the above 02019 // case. 02020 S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 02021 } 02022 D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 02023 } 02024 02025 static void 02026 handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02027 if (Attr.getNumArgs() != 0) { 02028 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02029 return; 02030 } 02031 02032 if (!isa<FunctionDecl>(D)) { 02033 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 02034 return; 02035 } 02036 02037 D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 02038 } 02039 02040 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02041 if (!Attr.getParameterName()) { 02042 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 02043 << "blocks" << 1; 02044 return; 02045 } 02046 02047 if (Attr.getNumArgs() != 0) { 02048 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02049 return; 02050 } 02051 02052 BlocksAttr::BlockType type; 02053 if (Attr.getParameterName()->isStr("byref")) 02054 type = BlocksAttr::ByRef; 02055 else { 02056 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 02057 << "blocks" << Attr.getParameterName(); 02058 return; 02059 } 02060 02061 D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 02062 } 02063 02064 static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02065 // check the attribute arguments. 02066 if (Attr.getNumArgs() > 2) { 02067 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 02068 return; 02069 } 02070 02071 unsigned sentinel = 0; 02072 if (Attr.getNumArgs() > 0) { 02073 Expr *E = Attr.getArg(0); 02074 llvm::APSInt Idx(32); 02075 if (E->isTypeDependent() || E->isValueDependent() || 02076 !E->isIntegerConstantExpr(Idx, S.Context)) { 02077 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 02078 << "sentinel" << 1 << E->getSourceRange(); 02079 return; 02080 } 02081 02082 if (Idx.isSigned() && Idx.isNegative()) { 02083 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 02084 << E->getSourceRange(); 02085 return; 02086 } 02087 02088 sentinel = Idx.getZExtValue(); 02089 } 02090 02091 unsigned nullPos = 0; 02092 if (Attr.getNumArgs() > 1) { 02093 Expr *E = Attr.getArg(1); 02094 llvm::APSInt Idx(32); 02095 if (E->isTypeDependent() || E->isValueDependent() || 02096 !E->isIntegerConstantExpr(Idx, S.Context)) { 02097 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 02098 << "sentinel" << 2 << E->getSourceRange(); 02099 return; 02100 } 02101 nullPos = Idx.getZExtValue(); 02102 02103 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 02104 // FIXME: This error message could be improved, it would be nice 02105 // to say what the bounds actually are. 02106 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 02107 << E->getSourceRange(); 02108 return; 02109 } 02110 } 02111 02112 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 02113 const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 02114 if (isa<FunctionNoProtoType>(FT)) { 02115 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 02116 return; 02117 } 02118 02119 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 02120 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 02121 return; 02122 } 02123 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 02124 if (!MD->isVariadic()) { 02125 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 02126 return; 02127 } 02128 } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 02129 if (!BD->isVariadic()) { 02130 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 02131 return; 02132 } 02133 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 02134 QualType Ty = V->getType(); 02135 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 02136 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 02137 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 02138 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 02139 int m = Ty->isFunctionPointerType() ? 0 : 1; 02140 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 02141 return; 02142 } 02143 } else { 02144 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02145 << Attr.getName() << ExpectedFunctionMethodOrBlock; 02146 return; 02147 } 02148 } else { 02149 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02150 << Attr.getName() << ExpectedFunctionMethodOrBlock; 02151 return; 02152 } 02153 D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 02154 nullPos)); 02155 } 02156 02157 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 02158 // check the attribute arguments. 02159 if (!checkAttributeNumArgs(S, Attr, 0)) 02160 return; 02161 02162 if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 02163 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02164 << Attr.getName() << ExpectedFunctionOrMethod; 02165 return; 02166 } 02167 02168 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 02169 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 02170 << Attr.getName() << 0; 02171 return; 02172 } 02173 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 02174 if (MD->getResultType()->isVoidType()) { 02175 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 02176 << Attr.getName() << 1; 02177 return; 02178 } 02179 02180 D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 02181 } 02182 02183 static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02184 // check the attribute arguments. 02185 if (Attr.hasParameterOrArguments()) { 02186 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 02187 return; 02188 } 02189 02190 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 02191 if (isa<CXXRecordDecl>(D)) { 02192 D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 02193 return; 02194 } 02195 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02196 << Attr.getName() << ExpectedVariableOrFunction; 02197 return; 02198 } 02199 02200 NamedDecl *nd = cast<NamedDecl>(D); 02201 02202 // 'weak' only applies to declarations with external linkage. 02203 if (hasEffectivelyInternalLinkage(nd)) { 02204 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 02205 return; 02206 } 02207 02208 nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 02209 } 02210 02211 static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02212 // check the attribute arguments. 02213 if (!checkAttributeNumArgs(S, Attr, 0)) 02214 return; 02215 02216 02217 // weak_import only applies to variable & function declarations. 02218 bool isDef = false; 02219 if (!D->canBeWeakImported(isDef)) { 02220 if (isDef) 02221 S.Diag(Attr.getLoc(), 02222 diag::warn_attribute_weak_import_invalid_on_definition) 02223 << "weak_import" << 2 /*variable and function*/; 02224 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 02225 (S.Context.getTargetInfo().getTriple().isOSDarwin() && 02226 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 02227 // Nothing to warn about here. 02228 } else 02229 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02230 << Attr.getName() << ExpectedVariableOrFunction; 02231 02232 return; 02233 } 02234 02235 D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 02236 } 02237 02238 static void handleReqdWorkGroupSize(Sema &S, Decl *D, 02239 const AttributeList &Attr) { 02240 // Attribute has 3 arguments. 02241 if (!checkAttributeNumArgs(S, Attr, 3)) 02242 return; 02243 02244 unsigned WGSize[3]; 02245 for (unsigned i = 0; i < 3; ++i) { 02246 Expr *E = Attr.getArg(i); 02247 llvm::APSInt ArgNum(32); 02248 if (E->isTypeDependent() || E->isValueDependent() || 02249 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 02250 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 02251 << "reqd_work_group_size" << E->getSourceRange(); 02252 return; 02253 } 02254 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 02255 } 02256 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 02257 WGSize[0], WGSize[1], 02258 WGSize[2])); 02259 } 02260 02261 SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, 02262 StringRef Name) { 02263 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { 02264 if (ExistingAttr->getName() == Name) 02265 return NULL; 02266 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); 02267 Diag(Range.getBegin(), diag::note_previous_attribute); 02268 return NULL; 02269 } 02270 return ::new (Context) SectionAttr(Range, Context, Name); 02271 } 02272 02273 static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02274 // Attribute has no arguments. 02275 if (!checkAttributeNumArgs(S, Attr, 1)) 02276 return; 02277 02278 // Make sure that there is a string literal as the sections's single 02279 // argument. 02280 Expr *ArgExpr = Attr.getArg(0); 02281 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 02282 if (!SE) { 02283 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 02284 return; 02285 } 02286 02287 // If the target wants to validate the section specifier, make it happen. 02288 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 02289 if (!Error.empty()) { 02290 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 02291 << Error; 02292 return; 02293 } 02294 02295 // This attribute cannot be applied to local variables. 02296 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 02297 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 02298 return; 02299 } 02300 SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), 02301 SE->getString()); 02302 if (NewAttr) 02303 D->addAttr(NewAttr); 02304 } 02305 02306 02307 static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02308 // check the attribute arguments. 02309 if (Attr.hasParameterOrArguments()) { 02310 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 02311 return; 02312 } 02313 02314 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 02315 if (Existing->getLocation().isInvalid()) 02316 Existing->setRange(Attr.getRange()); 02317 } else { 02318 D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 02319 } 02320 } 02321 02322 static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02323 // check the attribute arguments. 02324 if (Attr.hasParameterOrArguments()) { 02325 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 02326 return; 02327 } 02328 02329 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 02330 if (Existing->getLocation().isInvalid()) 02331 Existing->setRange(Attr.getRange()); 02332 } else { 02333 D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 02334 } 02335 } 02336 02337 static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02338 // check the attribute arguments. 02339 if (!checkAttributeNumArgs(S, Attr, 0)) 02340 return; 02341 02342 D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 02343 } 02344 02345 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02346 if (!Attr.getParameterName()) { 02347 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02348 return; 02349 } 02350 02351 if (Attr.getNumArgs() != 0) { 02352 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02353 return; 02354 } 02355 02356 VarDecl *VD = dyn_cast<VarDecl>(D); 02357 02358 if (!VD || !VD->hasLocalStorage()) { 02359 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 02360 return; 02361 } 02362 02363 // Look up the function 02364 // FIXME: Lookup probably isn't looking in the right place 02365 NamedDecl *CleanupDecl 02366 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 02367 Attr.getParameterLoc(), Sema::LookupOrdinaryName); 02368 if (!CleanupDecl) { 02369 S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 02370 Attr.getParameterName(); 02371 return; 02372 } 02373 02374 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 02375 if (!FD) { 02376 S.Diag(Attr.getParameterLoc(), 02377 diag::err_attribute_cleanup_arg_not_function) 02378 << Attr.getParameterName(); 02379 return; 02380 } 02381 02382 if (FD->getNumParams() != 1) { 02383 S.Diag(Attr.getParameterLoc(), 02384 diag::err_attribute_cleanup_func_must_take_one_arg) 02385 << Attr.getParameterName(); 02386 return; 02387 } 02388 02389 // We're currently more strict than GCC about what function types we accept. 02390 // If this ever proves to be a problem it should be easy to fix. 02391 QualType Ty = S.Context.getPointerType(VD->getType()); 02392 QualType ParamTy = FD->getParamDecl(0)->getType(); 02393 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 02394 ParamTy, Ty) != Sema::Compatible) { 02395 S.Diag(Attr.getParameterLoc(), 02396 diag::err_attribute_cleanup_func_arg_incompatible_type) << 02397 Attr.getParameterName() << ParamTy << Ty; 02398 return; 02399 } 02400 02401 D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 02402 S.MarkFunctionReferenced(Attr.getParameterLoc(), FD); 02403 } 02404 02405 /// Handle __attribute__((format_arg((idx)))) attribute based on 02406 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 02407 static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02408 if (!checkAttributeNumArgs(S, Attr, 1)) 02409 return; 02410 02411 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 02412 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02413 << Attr.getName() << ExpectedFunction; 02414 return; 02415 } 02416 02417 // In C++ the implicit 'this' function parameter also counts, and they are 02418 // counted from one. 02419 bool HasImplicitThisParam = isInstanceMethod(D); 02420 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 02421 unsigned FirstIdx = 1; 02422 02423 // checks for the 2nd argument 02424 Expr *IdxExpr = Attr.getArg(0); 02425 llvm::APSInt Idx(32); 02426 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 02427 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 02428 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 02429 << "format" << 2 << IdxExpr->getSourceRange(); 02430 return; 02431 } 02432 02433 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 02434 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 02435 << "format" << 2 << IdxExpr->getSourceRange(); 02436 return; 02437 } 02438 02439 unsigned ArgIdx = Idx.getZExtValue() - 1; 02440 02441 if (HasImplicitThisParam) { 02442 if (ArgIdx == 0) { 02443 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 02444 << "format_arg" << IdxExpr->getSourceRange(); 02445 return; 02446 } 02447 ArgIdx--; 02448 } 02449 02450 // make sure the format string is really a string 02451 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 02452 02453 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 02454 if (not_nsstring_type && 02455 !isCFStringType(Ty, S.Context) && 02456 (!Ty->isPointerType() || 02457 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 02458 // FIXME: Should highlight the actual expression that has the wrong type. 02459 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02460 << (not_nsstring_type ? "a string type" : "an NSString") 02461 << IdxExpr->getSourceRange(); 02462 return; 02463 } 02464 Ty = getFunctionOrMethodResultType(D); 02465 if (!isNSStringType(Ty, S.Context) && 02466 !isCFStringType(Ty, S.Context) && 02467 (!Ty->isPointerType() || 02468 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 02469 // FIXME: Should highlight the actual expression that has the wrong type. 02470 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 02471 << (not_nsstring_type ? "string type" : "NSString") 02472 << IdxExpr->getSourceRange(); 02473 return; 02474 } 02475 02476 D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 02477 Idx.getZExtValue())); 02478 } 02479 02480 enum FormatAttrKind { 02481 CFStringFormat, 02482 NSStringFormat, 02483 StrftimeFormat, 02484 SupportedFormat, 02485 IgnoredFormat, 02486 InvalidFormat 02487 }; 02488 02489 /// getFormatAttrKind - Map from format attribute names to supported format 02490 /// types. 02491 static FormatAttrKind getFormatAttrKind(StringRef Format) { 02492 return llvm::StringSwitch<FormatAttrKind>(Format) 02493 // Check for formats that get handled specially. 02494 .Case("NSString", NSStringFormat) 02495 .Case("CFString", CFStringFormat) 02496 .Case("strftime", StrftimeFormat) 02497 02498 // Otherwise, check for supported formats. 02499 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) 02500 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) 02501 .Case("kprintf", SupportedFormat) // OpenBSD. 02502 02503 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) 02504 .Default(InvalidFormat); 02505 } 02506 02507 /// Handle __attribute__((init_priority(priority))) attributes based on 02508 /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 02509 static void handleInitPriorityAttr(Sema &S, Decl *D, 02510 const AttributeList &Attr) { 02511 if (!S.getLangOpts().CPlusPlus) { 02512 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 02513 return; 02514 } 02515 02516 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 02517 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 02518 Attr.setInvalid(); 02519 return; 02520 } 02521 QualType T = dyn_cast<VarDecl>(D)->getType(); 02522 if (S.Context.getAsArrayType(T)) 02523 T = S.Context.getBaseElementType(T); 02524 if (!T->getAs<RecordType>()) { 02525 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 02526 Attr.setInvalid(); 02527 return; 02528 } 02529 02530 if (Attr.getNumArgs() != 1) { 02531 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02532 Attr.setInvalid(); 02533 return; 02534 } 02535 Expr *priorityExpr = Attr.getArg(0); 02536 02537 llvm::APSInt priority(32); 02538 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 02539 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 02540 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 02541 << "init_priority" << priorityExpr->getSourceRange(); 02542 Attr.setInvalid(); 02543 return; 02544 } 02545 unsigned prioritynum = priority.getZExtValue(); 02546 if (prioritynum < 101 || prioritynum > 65535) { 02547 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 02548 << priorityExpr->getSourceRange(); 02549 Attr.setInvalid(); 02550 return; 02551 } 02552 D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 02553 prioritynum)); 02554 } 02555 02556 FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, 02557 int FormatIdx, int FirstArg) { 02558 // Check whether we already have an equivalent format attribute. 02559 for (specific_attr_iterator<FormatAttr> 02560 i = D->specific_attr_begin<FormatAttr>(), 02561 e = D->specific_attr_end<FormatAttr>(); 02562 i != e ; ++i) { 02563 FormatAttr *f = *i; 02564 if (f->getType() == Format && 02565 f->getFormatIdx() == FormatIdx && 02566 f->getFirstArg() == FirstArg) { 02567 // If we don't have a valid location for this attribute, adopt the 02568 // location. 02569 if (f->getLocation().isInvalid()) 02570 f->setRange(Range); 02571 return NULL; 02572 } 02573 } 02574 02575 return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, 02576 FirstArg); 02577 } 02578 02579 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on 02580 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 02581 static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02582 02583 if (!Attr.getParameterName()) { 02584 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 02585 << "format" << 1; 02586 return; 02587 } 02588 02589 if (Attr.getNumArgs() != 2) { 02590 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 02591 return; 02592 } 02593 02594 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 02595 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02596 << Attr.getName() << ExpectedFunction; 02597 return; 02598 } 02599 02600 // In C++ the implicit 'this' function parameter also counts, and they are 02601 // counted from one. 02602 bool HasImplicitThisParam = isInstanceMethod(D); 02603 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 02604 unsigned FirstIdx = 1; 02605 02606 StringRef Format = Attr.getParameterName()->getName(); 02607 02608 // Normalize the argument, __foo__ becomes foo. 02609 if (Format.startswith("__") && Format.endswith("__")) 02610 Format = Format.substr(2, Format.size() - 4); 02611 02612 // Check for supported formats. 02613 FormatAttrKind Kind = getFormatAttrKind(Format); 02614 02615 if (Kind == IgnoredFormat) 02616 return; 02617 02618 if (Kind == InvalidFormat) { 02619 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 02620 << "format" << Attr.getParameterName()->getName(); 02621 return; 02622 } 02623 02624 // checks for the 2nd argument 02625 Expr *IdxExpr = Attr.getArg(0); 02626 llvm::APSInt Idx(32); 02627 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 02628 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 02629 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 02630 << "format" << 2 << IdxExpr->getSourceRange(); 02631 return; 02632 } 02633 02634 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 02635 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 02636 << "format" << 2 << IdxExpr->getSourceRange(); 02637 return; 02638 } 02639 02640 // FIXME: Do we need to bounds check? 02641 unsigned ArgIdx = Idx.getZExtValue() - 1; 02642 02643 if (HasImplicitThisParam) { 02644 if (ArgIdx == 0) { 02645 S.Diag(Attr.getLoc(), 02646 diag::err_format_attribute_implicit_this_format_string) 02647 << IdxExpr->getSourceRange(); 02648 return; 02649 } 02650 ArgIdx--; 02651 } 02652 02653 // make sure the format string is really a string 02654 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 02655 02656 if (Kind == CFStringFormat) { 02657 if (!isCFStringType(Ty, S.Context)) { 02658 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02659 << "a CFString" << IdxExpr->getSourceRange(); 02660 return; 02661 } 02662 } else if (Kind == NSStringFormat) { 02663 // FIXME: do we need to check if the type is NSString*? What are the 02664 // semantics? 02665 if (!isNSStringType(Ty, S.Context)) { 02666 // FIXME: Should highlight the actual expression that has the wrong type. 02667 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02668 << "an NSString" << IdxExpr->getSourceRange(); 02669 return; 02670 } 02671 } else if (!Ty->isPointerType() || 02672 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 02673 // FIXME: Should highlight the actual expression that has the wrong type. 02674 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 02675 << "a string type" << IdxExpr->getSourceRange(); 02676 return; 02677 } 02678 02679 // check the 3rd argument 02680 Expr *FirstArgExpr = Attr.getArg(1); 02681 llvm::APSInt FirstArg(32); 02682 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 02683 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 02684 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 02685 << "format" << 3 << FirstArgExpr->getSourceRange(); 02686 return; 02687 } 02688 02689 // check if the function is variadic if the 3rd argument non-zero 02690 if (FirstArg != 0) { 02691 if (isFunctionOrMethodVariadic(D)) { 02692 ++NumArgs; // +1 for ... 02693 } else { 02694 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 02695 return; 02696 } 02697 } 02698 02699 // strftime requires FirstArg to be 0 because it doesn't read from any 02700 // variable the input is just the current time + the format string. 02701 if (Kind == StrftimeFormat) { 02702 if (FirstArg != 0) { 02703 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 02704 << FirstArgExpr->getSourceRange(); 02705 return; 02706 } 02707 // if 0 it disables parameter checking (to use with e.g. va_list) 02708 } else if (FirstArg != 0 && FirstArg != NumArgs) { 02709 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 02710 << "format" << 3 << FirstArgExpr->getSourceRange(); 02711 return; 02712 } 02713 02714 FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format, 02715 Idx.getZExtValue(), 02716 FirstArg.getZExtValue()); 02717 if (NewAttr) 02718 D->addAttr(NewAttr); 02719 } 02720 02721 static void handleTransparentUnionAttr(Sema &S, Decl *D, 02722 const AttributeList &Attr) { 02723 // check the attribute arguments. 02724 if (!checkAttributeNumArgs(S, Attr, 0)) 02725 return; 02726 02727 02728 // Try to find the underlying union declaration. 02729 RecordDecl *RD = 0; 02730 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 02731 if (TD && TD->getUnderlyingType()->isUnionType()) 02732 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 02733 else 02734 RD = dyn_cast<RecordDecl>(D); 02735 02736 if (!RD || !RD->isUnion()) { 02737 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 02738 << Attr.getName() << ExpectedUnion; 02739 return; 02740 } 02741 02742 if (!RD->isCompleteDefinition()) { 02743 S.Diag(Attr.getLoc(), 02744 diag::warn_transparent_union_attribute_not_definition); 02745 return; 02746 } 02747 02748 RecordDecl::field_iterator Field = RD->field_begin(), 02749 FieldEnd = RD->field_end(); 02750 if (Field == FieldEnd) { 02751 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 02752 return; 02753 } 02754 02755 FieldDecl *FirstField = &*Field; 02756 QualType FirstType = FirstField->getType(); 02757 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 02758 S.Diag(FirstField->getLocation(), 02759 diag::warn_transparent_union_attribute_floating) 02760 << FirstType->isVectorType() << FirstType; 02761 return; 02762 } 02763 02764 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 02765 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 02766 for (; Field != FieldEnd; ++Field) { 02767 QualType FieldType = Field->getType(); 02768 if (S.Context.getTypeSize(FieldType) != FirstSize || 02769 S.Context.getTypeAlign(FieldType) != FirstAlign) { 02770 // Warn if we drop the attribute. 02771 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 02772 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 02773 : S.Context.getTypeAlign(FieldType); 02774 S.Diag(Field->getLocation(), 02775 diag::warn_transparent_union_attribute_field_size_align) 02776 << isSize << Field->getDeclName() << FieldBits; 02777 unsigned FirstBits = isSize? FirstSize : FirstAlign; 02778 S.Diag(FirstField->getLocation(), 02779 diag::note_transparent_union_first_field_size_align) 02780 << isSize << FirstBits; 02781 return; 02782 } 02783 } 02784 02785 RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 02786 } 02787 02788 static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02789 // check the attribute arguments. 02790 if (!checkAttributeNumArgs(S, Attr, 1)) 02791 return; 02792 02793 Expr *ArgExpr = Attr.getArg(0); 02794 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 02795 02796 // Make sure that there is a string literal as the annotation's single 02797 // argument. 02798 if (!SE) { 02799 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 02800 return; 02801 } 02802 02803 // Don't duplicate annotations that are already set. 02804 for (specific_attr_iterator<AnnotateAttr> 02805 i = D->specific_attr_begin<AnnotateAttr>(), 02806 e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 02807 if ((*i)->getAnnotation() == SE->getString()) 02808 return; 02809 } 02810 D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 02811 SE->getString())); 02812 } 02813 02814 static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02815 // check the attribute arguments. 02816 if (Attr.getNumArgs() > 1) { 02817 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 02818 return; 02819 } 02820 02821 //FIXME: The C++0x version of this attribute has more limited applicabilty 02822 // than GNU's, and should error out when it is used to specify a 02823 // weaker alignment, rather than being silently ignored. 02824 02825 if (Attr.getNumArgs() == 0) { 02826 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); 02827 return; 02828 } 02829 02830 S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 02831 } 02832 02833 void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { 02834 // FIXME: Handle pack-expansions here. 02835 if (DiagnoseUnexpandedParameterPack(E)) 02836 return; 02837 02838 if (E->isTypeDependent() || E->isValueDependent()) { 02839 // Save dependent expressions in the AST to be instantiated. 02840 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 02841 return; 02842 } 02843 02844 SourceLocation AttrLoc = AttrRange.getBegin(); 02845 // FIXME: Cache the number on the Attr object? 02846 llvm::APSInt Alignment(32); 02847 ExprResult ICE 02848 = VerifyIntegerConstantExpression(E, &Alignment, 02849 diag::err_aligned_attribute_argument_not_int, 02850 /*AllowFold*/ false); 02851 if (ICE.isInvalid()) 02852 return; 02853 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 02854 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 02855 << E->getSourceRange(); 02856 return; 02857 } 02858 02859 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take())); 02860 } 02861 02862 void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 02863 // FIXME: Cache the number on the Attr object if non-dependent? 02864 // FIXME: Perform checking of type validity 02865 D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 02866 return; 02867 } 02868 02869 /// handleModeAttr - This attribute modifies the width of a decl with primitive 02870 /// type. 02871 /// 02872 /// Despite what would be logical, the mode attribute is a decl attribute, not a 02873 /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 02874 /// HImode, not an intermediate pointer. 02875 static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 02876 // This attribute isn't documented, but glibc uses it. It changes 02877 // the width of an int or unsigned int to the specified size. 02878 02879 // Check that there aren't any arguments 02880 if (!checkAttributeNumArgs(S, Attr, 0)) 02881 return; 02882 02883 02884 IdentifierInfo *Name = Attr.getParameterName(); 02885 if (!Name) { 02886 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 02887 return; 02888 } 02889 02890 StringRef Str = Attr.getParameterName()->getName(); 02891 02892 // Normalize the attribute name, __foo__ becomes foo. 02893 if (Str.startswith("__") && Str.endswith("__")) 02894 Str = Str.substr(2, Str.size() - 4); 02895 02896 unsigned DestWidth = 0; 02897 bool IntegerMode = true; 02898 bool ComplexMode = false; 02899 switch (Str.size()) { 02900 case 2: 02901 switch (Str[0]) { 02902 case 'Q': DestWidth = 8; break; 02903 case 'H': DestWidth = 16; break; 02904 case 'S': DestWidth = 32; break; 02905 case 'D': DestWidth = 64; break; 02906 case 'X': DestWidth = 96; break; 02907 case 'T': DestWidth = 128; break; 02908 } 02909 if (Str[1] == 'F') { 02910 IntegerMode = false; 02911 } else if (Str[1] == 'C') { 02912 IntegerMode = false; 02913 ComplexMode = true; 02914 } else if (Str[1] != 'I') { 02915 DestWidth = 0; 02916 } 02917 break; 02918 case 4: 02919 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 02920 // pointer on PIC16 and other embedded platforms. 02921 if (Str == "word") 02922 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 02923 else if (Str == "byte") 02924 DestWidth = S.Context.getTargetInfo().getCharWidth(); 02925 break; 02926 case 7: 02927 if (Str == "pointer") 02928 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 02929 break; 02930 } 02931 02932 QualType OldTy; 02933 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 02934 OldTy = TD->getUnderlyingType(); 02935 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 02936 OldTy = VD->getType(); 02937 else { 02938 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 02939 << "mode" << Attr.getRange(); 02940 return; 02941 } 02942 02943 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 02944 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 02945 else if (IntegerMode) { 02946 if (!OldTy->isIntegralOrEnumerationType()) 02947 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 02948 } else if (ComplexMode) { 02949 if (!OldTy->isComplexType()) 02950 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 02951 } else { 02952 if (!OldTy->isFloatingType()) 02953 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 02954 } 02955 02956 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 02957 // and friends, at least with glibc. 02958 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 02959 // width on unusual platforms. 02960 // FIXME: Make sure floating-point mappings are accurate 02961 // FIXME: Support XF and TF types 02962 QualType NewTy; 02963 switch (DestWidth) { 02964 case 0: 02965 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 02966 return; 02967 default: 02968 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 02969 return; 02970 case 8: 02971 if (!IntegerMode) { 02972 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 02973 return; 02974 } 02975 if (OldTy->isSignedIntegerType()) 02976 NewTy = S.Context.SignedCharTy; 02977 else 02978 NewTy = S.Context.UnsignedCharTy; 02979 break; 02980 case 16: 02981 if (!IntegerMode) { 02982 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 02983 return; 02984 } 02985 if (OldTy->isSignedIntegerType()) 02986 NewTy = S.Context.ShortTy; 02987 else 02988 NewTy = S.Context.UnsignedShortTy; 02989 break; 02990 case 32: 02991 if (!IntegerMode) 02992 NewTy = S.Context.FloatTy; 02993 else if (OldTy->isSignedIntegerType()) 02994 NewTy = S.Context.IntTy; 02995 else 02996 NewTy = S.Context.UnsignedIntTy; 02997 break; 02998 case 64: 02999 if (!IntegerMode) 03000 NewTy = S.Context.DoubleTy; 03001 else if (OldTy->isSignedIntegerType()) 03002 if (S.Context.getTargetInfo().getLongWidth() == 64) 03003 NewTy = S.Context.LongTy; 03004 else 03005 NewTy = S.Context.LongLongTy; 03006 else 03007 if (S.Context.getTargetInfo().getLongWidth() == 64) 03008 NewTy = S.Context.UnsignedLongTy; 03009 else 03010 NewTy = S.Context.UnsignedLongLongTy; 03011 break; 03012 case 96: 03013 NewTy = S.Context.LongDoubleTy; 03014 break; 03015 case 128: 03016 if (!IntegerMode) { 03017 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 03018 return; 03019 } 03020 if (OldTy->isSignedIntegerType()) 03021 NewTy = S.Context.Int128Ty; 03022 else 03023 NewTy = S.Context.UnsignedInt128Ty; 03024 break; 03025 } 03026 03027 if (ComplexMode) { 03028 NewTy = S.Context.getComplexType(NewTy); 03029 } 03030 03031 // Install the new type. 03032 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 03033 // FIXME: preserve existing source info. 03034 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 03035 } else 03036 cast<ValueDecl>(D)->setType(NewTy); 03037 } 03038 03039 static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03040 // check the attribute arguments. 03041 if (!checkAttributeNumArgs(S, Attr, 0)) 03042 return; 03043 03044 if (!isFunctionOrMethod(D)) { 03045 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03046 << Attr.getName() << ExpectedFunction; 03047 return; 03048 } 03049 03050 D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 03051 } 03052 03053 static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03054 // check the attribute arguments. 03055 if (!checkAttributeNumArgs(S, Attr, 0)) 03056 return; 03057 03058 03059 if (!isa<FunctionDecl>(D)) { 03060 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03061 << Attr.getName() << ExpectedFunction; 03062 return; 03063 } 03064 03065 D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 03066 } 03067 03068 static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 03069 const AttributeList &Attr) { 03070 // check the attribute arguments. 03071 if (!checkAttributeNumArgs(S, Attr, 0)) 03072 return; 03073 03074 03075 if (!isa<FunctionDecl>(D)) { 03076 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03077 << Attr.getName() << ExpectedFunction; 03078 return; 03079 } 03080 03081 D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 03082 S.Context)); 03083 } 03084 03085 static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03086 if (S.LangOpts.CUDA) { 03087 // check the attribute arguments. 03088 if (Attr.hasParameterOrArguments()) { 03089 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 03090 return; 03091 } 03092 03093 if (!isa<VarDecl>(D)) { 03094 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03095 << Attr.getName() << ExpectedVariable; 03096 return; 03097 } 03098 03099 D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 03100 } else { 03101 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 03102 } 03103 } 03104 03105 static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03106 if (S.LangOpts.CUDA) { 03107 // check the attribute arguments. 03108 if (Attr.getNumArgs() != 0) { 03109 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 03110 return; 03111 } 03112 03113 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 03114 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03115 << Attr.getName() << ExpectedVariableOrFunction; 03116 return; 03117 } 03118 03119 D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 03120 } else { 03121 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 03122 } 03123 } 03124 03125 static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03126 if (S.LangOpts.CUDA) { 03127 // check the attribute arguments. 03128 if (!checkAttributeNumArgs(S, Attr, 0)) 03129 return; 03130 03131 if (!isa<FunctionDecl>(D)) { 03132 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03133 << Attr.getName() << ExpectedFunction; 03134 return; 03135 } 03136 03137 FunctionDecl *FD = cast<FunctionDecl>(D); 03138 if (!FD->getResultType()->isVoidType()) { 03139 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 03140 if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 03141 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 03142 << FD->getType() 03143 << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 03144 "void"); 03145 } else { 03146 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 03147 << FD->getType(); 03148 } 03149 return; 03150 } 03151 03152 D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 03153 } else { 03154 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 03155 } 03156 } 03157 03158 static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03159 if (S.LangOpts.CUDA) { 03160 // check the attribute arguments. 03161 if (!checkAttributeNumArgs(S, Attr, 0)) 03162 return; 03163 03164 03165 if (!isa<FunctionDecl>(D)) { 03166 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03167 << Attr.getName() << ExpectedFunction; 03168 return; 03169 } 03170 03171 D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 03172 } else { 03173 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 03174 } 03175 } 03176 03177 static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03178 if (S.LangOpts.CUDA) { 03179 // check the attribute arguments. 03180 if (!checkAttributeNumArgs(S, Attr, 0)) 03181 return; 03182 03183 03184 if (!isa<VarDecl>(D)) { 03185 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03186 << Attr.getName() << ExpectedVariable; 03187 return; 03188 } 03189 03190 D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 03191 } else { 03192 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 03193 } 03194 } 03195 03196 static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03197 // check the attribute arguments. 03198 if (!checkAttributeNumArgs(S, Attr, 0)) 03199 return; 03200 03201 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 03202 if (Fn == 0) { 03203 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03204 << Attr.getName() << ExpectedFunction; 03205 return; 03206 } 03207 03208 if (!Fn->isInlineSpecified()) { 03209 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 03210 return; 03211 } 03212 03213 D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 03214 } 03215 03216 static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03217 if (hasDeclarator(D)) return; 03218 03219 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 03220 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 03221 CallingConv CC; 03222 if (S.CheckCallingConvAttr(Attr, CC)) 03223 return; 03224 03225 if (!isa<ObjCMethodDecl>(D)) { 03226 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03227 << Attr.getName() << ExpectedFunctionOrMethod; 03228 return; 03229 } 03230 03231 switch (Attr.getKind()) { 03232 case AttributeList::AT_fastcall: 03233 D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 03234 return; 03235 case AttributeList::AT_stdcall: 03236 D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 03237 return; 03238 case AttributeList::AT_thiscall: 03239 D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 03240 return; 03241 case AttributeList::AT_cdecl: 03242 D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 03243 return; 03244 case AttributeList::AT_pascal: 03245 D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 03246 return; 03247 case AttributeList::AT_pcs: { 03248 Expr *Arg = Attr.getArg(0); 03249 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 03250 if (!Str || !Str->isAscii()) { 03251 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 03252 << "pcs" << 1; 03253 Attr.setInvalid(); 03254 return; 03255 } 03256 03257 StringRef StrRef = Str->getString(); 03258 PcsAttr::PCSType PCS; 03259 if (StrRef == "aapcs") 03260 PCS = PcsAttr::AAPCS; 03261 else if (StrRef == "aapcs-vfp") 03262 PCS = PcsAttr::AAPCS_VFP; 03263 else { 03264 S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 03265 Attr.setInvalid(); 03266 return; 03267 } 03268 03269 D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 03270 } 03271 default: 03272 llvm_unreachable("unexpected attribute kind"); 03273 } 03274 } 03275 03276 static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 03277 assert(!Attr.isInvalid()); 03278 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 03279 } 03280 03281 bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 03282 if (attr.isInvalid()) 03283 return true; 03284 03285 if ((attr.getNumArgs() != 0 && 03286 !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 03287 attr.getParameterName()) { 03288 Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 03289 attr.setInvalid(); 03290 return true; 03291 } 03292 03293 // TODO: diagnose uses of these conventions on the wrong target. Or, better 03294 // move to TargetAttributesSema one day. 03295 switch (attr.getKind()) { 03296 case AttributeList::AT_cdecl: CC = CC_C; break; 03297 case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 03298 case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 03299 case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 03300 case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 03301 case AttributeList::AT_pcs: { 03302 Expr *Arg = attr.getArg(0); 03303 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 03304 if (!Str || !Str->isAscii()) { 03305 Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 03306 << "pcs" << 1; 03307 attr.setInvalid(); 03308 return true; 03309 } 03310 03311 StringRef StrRef = Str->getString(); 03312 if (StrRef == "aapcs") { 03313 CC = CC_AAPCS; 03314 break; 03315 } else if (StrRef == "aapcs-vfp") { 03316 CC = CC_AAPCS_VFP; 03317 break; 03318 } 03319 // FALLS THROUGH 03320 } 03321 default: llvm_unreachable("unexpected attribute kind"); 03322 } 03323 03324 return false; 03325 } 03326 03327 static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03328 if (hasDeclarator(D)) return; 03329 03330 unsigned numParams; 03331 if (S.CheckRegparmAttr(Attr, numParams)) 03332 return; 03333 03334 if (!isa<ObjCMethodDecl>(D)) { 03335 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03336 << Attr.getName() << ExpectedFunctionOrMethod; 03337 return; 03338 } 03339 03340 D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 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 (Attr.getNumArgs() != 1) { 03350 Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 03351 Attr.setInvalid(); 03352 return true; 03353 } 03354 03355 Expr *NumParamsExpr = Attr.getArg(0); 03356 llvm::APSInt NumParams(32); 03357 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 03358 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 03359 Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 03360 << "regparm" << NumParamsExpr->getSourceRange(); 03361 Attr.setInvalid(); 03362 return true; 03363 } 03364 03365 if (Context.getTargetInfo().getRegParmMax() == 0) { 03366 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 03367 << NumParamsExpr->getSourceRange(); 03368 Attr.setInvalid(); 03369 return true; 03370 } 03371 03372 numParams = NumParams.getZExtValue(); 03373 if (numParams > Context.getTargetInfo().getRegParmMax()) { 03374 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 03375 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 03376 Attr.setInvalid(); 03377 return true; 03378 } 03379 03380 return false; 03381 } 03382 03383 static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 03384 if (S.LangOpts.CUDA) { 03385 // check the attribute arguments. 03386 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 03387 // FIXME: 0 is not okay. 03388 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 03389 return; 03390 } 03391 03392 if (!isFunctionOrMethod(D)) { 03393 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 03394 << Attr.getName() << ExpectedFunctionOrMethod; 03395 return; 03396 } 03397 03398 Expr *MaxThreadsExpr = Attr.getArg(0); 03399 llvm::APSInt MaxThreads(32); 03400 if (MaxThreadsExpr->isTypeDependent() || 03401 MaxThreadsExpr->isValueDependent() || 03402 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 03403 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 03404 << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 03405 return; 03406 } 03407 03408 llvm::APSInt MinBlocks(32); 03409 if (Attr.getNumArgs() > 1) { 03410 Expr *MinBlocksExpr = Attr.getArg(1); 03411 if (MinBlocksExpr->isTypeDependent() || 03412 MinBlocksExpr->isValueDependent() || 03413 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 03414 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 03415 << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 03416 return; 03417 } 03418 } 03419 03420 D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 03421 MaxThreads.getZExtValue(), 03422 MinBlocks.getZExtValue())); 03423 } else { 03424 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 03425 } 03426 } 03427 03428 //===----------------------------------------------------------------------===// 03429 // Checker-specific attribute handlers. 03430 //===----------------------------------------------------------------------===// 03431 03432 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 03433 return type->isDependentType() || 03434 type->isObjCObjectPointerType() || 03435 S.Context.isObjCNSObjectType(type); 03436 } 03437 static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 03438 return type->isDependentType() || 03439 type->isPointerType() || 03440 isValidSubjectOfNSAttribute(S, type); 03441 } 03442 03443 static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03444 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 03445 if (!param) { 03446 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 03447 << Attr.getRange() << Attr.getName() << ExpectedParameter; 03448 return; 03449 } 03450 03451 bool typeOK, cf; 03452 if (Attr.getKind() == AttributeList::AT_ns_consumed) { 03453 typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 03454 cf = false; 03455 } else { 03456 typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 03457 cf = true; 03458 } 03459 03460 if (!typeOK) { 03461 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 03462 << Attr.getRange() << Attr.getName() << cf; 03463 return; 03464 } 03465 03466 if (cf) 03467 param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 03468 else 03469 param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 03470 } 03471 03472 static void handleNSConsumesSelfAttr(Sema &S, Decl *D, 03473 const AttributeList &Attr) { 03474 if (!isa<ObjCMethodDecl>(D)) { 03475 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 03476 << Attr.getRange() << Attr.getName() << ExpectedMethod; 03477 return; 03478 } 03479 03480 D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 03481 } 03482 03483 static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 03484 const AttributeList &Attr) { 03485 03486 QualType returnType; 03487 03488 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 03489 returnType = MD->getResultType(); 03490 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 03491 returnType = PD->getType(); 03492 else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 03493 (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 03494 return; // ignore: was handled as a type attribute 03495 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 03496 returnType = FD->getResultType(); 03497 else { 03498 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 03499 << Attr.getRange() << Attr.getName() 03500 << ExpectedFunctionOrMethod; 03501 return; 03502 } 03503 03504 bool typeOK; 03505 bool cf; 03506 switch (Attr.getKind()) { 03507 default: llvm_unreachable("invalid ownership attribute"); 03508 case AttributeList::AT_ns_returns_autoreleased: 03509 case AttributeList::AT_ns_returns_retained: 03510 case AttributeList::AT_ns_returns_not_retained: 03511 typeOK = isValidSubjectOfNSAttribute(S, returnType); 03512 cf = false; 03513 break; 03514 03515 case AttributeList::AT_cf_returns_retained: 03516 case AttributeList::AT_cf_returns_not_retained: 03517 typeOK = isValidSubjectOfCFAttribute(S, returnType); 03518 cf = true; 03519 break; 03520 } 03521 03522 if (!typeOK) { 03523 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 03524 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 03525 return; 03526 } 03527 03528 switch (Attr.getKind()) { 03529 default: 03530 llvm_unreachable("invalid ownership attribute"); 03531 case AttributeList::AT_ns_returns_autoreleased: 03532 D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 03533 S.Context)); 03534 return; 03535 case AttributeList::AT_cf_returns_not_retained: 03536 D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 03537 S.Context)); 03538 return; 03539 case AttributeList::AT_ns_returns_not_retained: 03540 D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 03541 S.Context)); 03542 return; 03543 case AttributeList::AT_cf_returns_retained: 03544 D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 03545 S.Context)); 03546 return; 03547 case AttributeList::AT_ns_returns_retained: 03548 D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 03549 S.Context)); 03550 return; 03551 }; 03552 } 03553 03554 static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 03555 const AttributeList &attr) { 03556 SourceLocation loc = attr.getLoc(); 03557 03558 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 03559 03560 if (!method) { 03561 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 03562 << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 03563 return; 03564 } 03565 03566 // Check that the method returns a normal pointer. 03567 QualType resultType = method->getResultType(); 03568 03569 if (!resultType->isReferenceType() && 03570 (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 03571 S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 03572 << SourceRange(loc) 03573 << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 03574 03575 // Drop the attribute. 03576 return; 03577 } 03578 03579 method->addAttr( 03580 ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 03581 } 03582 03583 /// Handle cf_audited_transfer and cf_unknown_transfer. 03584 static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 03585 if (!isa<FunctionDecl>(D)) { 03586 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 03587 << A.getRange() << A.getName() << ExpectedFunction; 03588 return; 03589 } 03590 03591 bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer); 03592 03593 // Check whether there's a conflicting attribute already present. 03594 Attr *Existing; 03595 if (IsAudited) { 03596 Existing = D->getAttr<CFUnknownTransferAttr>(); 03597 } else { 03598 Existing = D->getAttr<CFAuditedTransferAttr>(); 03599 } 03600 if (Existing) { 03601 S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 03602 << A.getName() 03603 << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 03604 << A.getRange() << Existing->getRange(); 03605 return; 03606 } 03607 03608 // All clear; add the attribute. 03609 if (IsAudited) { 03610 D->addAttr( 03611 ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 03612 } else { 03613 D->addAttr( 03614 ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 03615 } 03616 } 03617 03618 static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 03619 const AttributeList &Attr) { 03620 RecordDecl *RD = dyn_cast<RecordDecl>(D); 03621 if (!RD || RD->isUnion()) { 03622 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 03623 << Attr.getRange() << Attr.getName() << ExpectedStruct; 03624 } 03625 03626 IdentifierInfo *ParmName = Attr.getParameterName(); 03627 03628 // In Objective-C, verify that the type names an Objective-C type. 03629 // We don't want to check this outside of ObjC because people sometimes 03630 // do crazy C declarations of Objective-C types. 03631 if (ParmName && S.getLangOpts().ObjC1) { 03632 // Check for an existing type with this name. 03633 LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 03634 Sema::LookupOrdinaryName); 03635 if (S.LookupName(R, Sc)) { 03636 NamedDecl *Target = R.getFoundDecl(); 03637 if (Target && !isa<ObjCInterfaceDecl>(Target)) { 03638 S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 03639 S.Diag(Target->getLocStart(), diag::note_declared_at); 03640 } 03641 } 03642 } 03643 03644 D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 03645 ParmName)); 03646 } 03647 03648 static void handleObjCOwnershipAttr(Sema &S, Decl *D, 03649 const AttributeList &Attr) { 03650 if (hasDeclarator(D)) return; 03651 03652 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 03653 << Attr.getRange() << Attr.getName() << ExpectedVariable; 03654 } 03655 03656 static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 03657 const AttributeList &Attr) { 03658 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 03659 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 03660 << Attr.getRange() << Attr.getName() << ExpectedVariable; 03661 return; 03662 } 03663 03664 ValueDecl *vd = cast<ValueDecl>(D); 03665 QualType type = vd->getType(); 03666 03667 if (!type->isDependentType() && 03668 !type->isObjCLifetimeType()) { 03669 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 03670 << type; 03671 return; 03672 } 03673 03674 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 03675 03676 // If we have no lifetime yet, check the lifetime we're presumably 03677 // going to infer. 03678 if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 03679 lifetime = type->getObjCARCImplicitLifetime(); 03680 03681 switch (lifetime) { 03682 case Qualifiers::OCL_None: 03683 assert(type->isDependentType() && 03684 "didn't infer lifetime for non-dependent type?"); 03685 break; 03686 03687 case Qualifiers::OCL_Weak: // meaningful 03688 case Qualifiers::OCL_Strong: // meaningful 03689 break; 03690 03691 case Qualifiers::OCL_ExplicitNone: 03692 case Qualifiers::OCL_Autoreleasing: 03693 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 03694 << (lifetime == Qualifiers::OCL_Autoreleasing); 03695 break; 03696 } 03697 03698 D->addAttr(::new (S.Context) 03699 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 03700 } 03701 03702 static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 03703 switch (Attr.getKind()) { 03704 default: 03705 return false; 03706 case AttributeList::AT_dllimport: 03707 case AttributeList::AT_dllexport: 03708 case AttributeList::AT_uuid: 03709 case AttributeList::AT_deprecated: 03710 case AttributeList::AT_noreturn: 03711 case AttributeList::AT_nothrow: 03712 case AttributeList::AT_naked: 03713 case AttributeList::AT_noinline: 03714 return true; 03715 } 03716 } 03717 03718 //===----------------------------------------------------------------------===// 03719 // Microsoft specific attribute handlers. 03720 //===----------------------------------------------------------------------===// 03721 03722 static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 03723 if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 03724 // check the attribute arguments. 03725 if (!checkAttributeNumArgs(S, Attr, 1)) 03726 return; 03727 03728 Expr *Arg = Attr.getArg(0); 03729 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 03730 if (!Str || !Str->isAscii()) { 03731 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 03732 << "uuid" << 1; 03733 return; 03734 } 03735 03736 StringRef StrRef = Str->getString(); 03737 03738 bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 03739 StrRef.back() == '}'; 03740 03741 // Validate GUID length. 03742 if (IsCurly && StrRef.size() != 38) { 03743 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 03744 return; 03745 } 03746 if (!IsCurly && StrRef.size() != 36) { 03747 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 03748 return; 03749 } 03750 03751 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 03752 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 03753 StringRef::iterator I = StrRef.begin(); 03754 if (IsCurly) // Skip the optional '{' 03755 ++I; 03756 03757 for (int i = 0; i < 36; ++i) { 03758 if (i == 8 || i == 13 || i == 18 || i == 23) { 03759 if (*I != '-') { 03760 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 03761 return; 03762 } 03763 } else if (!isxdigit(*I)) { 03764 S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 03765 return; 03766 } 03767 I++; 03768 } 03769 03770 D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 03771 Str->getString())); 03772 } else 03773 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 03774 } 03775 03776 //===----------------------------------------------------------------------===// 03777 // Top Level Sema Entry Points 03778 //===----------------------------------------------------------------------===// 03779 03780 static void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 03781 const AttributeList &Attr) { 03782 switch (Attr.getKind()) { 03783 case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 03784 case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 03785 case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 03786 default: 03787 break; 03788 } 03789 } 03790 03791 static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 03792 const AttributeList &Attr) { 03793 switch (Attr.getKind()) { 03794 case AttributeList::AT_ibaction: handleIBAction(S, D, Attr); break; 03795 case AttributeList::AT_iboutlet: handleIBOutlet(S, D, Attr); break; 03796 case AttributeList::AT_iboutletcollection: 03797 handleIBOutletCollection(S, D, Attr); break; 03798 case AttributeList::AT_address_space: 03799 case AttributeList::AT_opencl_image_access: 03800 case AttributeList::AT_objc_gc: 03801 case AttributeList::AT_vector_size: 03802 case AttributeList::AT_neon_vector_type: 03803 case AttributeList::AT_neon_polyvector_type: 03804 // Ignore these, these are type attributes, handled by 03805 // ProcessTypeAttributes. 03806 break; 03807 case AttributeList::AT_device: 03808 case AttributeList::AT_host: 03809 case AttributeList::AT_overloadable: 03810 // Ignore, this is a non-inheritable attribute, handled 03811 // by ProcessNonInheritableDeclAttr. 03812 break; 03813 case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 03814 case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 03815 case AttributeList::AT_always_inline: 03816 handleAlwaysInlineAttr (S, D, Attr); break; 03817 case AttributeList::AT_analyzer_noreturn: 03818 handleAnalyzerNoReturnAttr (S, D, Attr); break; 03819 case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 03820 case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 03821 case AttributeList::AT_carries_dependency: 03822 handleDependencyAttr (S, D, Attr); break; 03823 case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 03824 case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 03825 case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 03826 case AttributeList::AT_deprecated: 03827 handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated"); 03828 break; 03829 case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 03830 case AttributeList::AT_ext_vector_type: 03831 handleExtVectorTypeAttr(S, scope, D, Attr); 03832 break; 03833 case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 03834 case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 03835 case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 03836 case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 03837 case AttributeList::AT_launch_bounds: 03838 handleLaunchBoundsAttr(S, D, Attr); 03839 break; 03840 case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 03841 case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 03842 case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 03843 case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 03844 case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 03845 case AttributeList::AT_ownership_returns: 03846 case AttributeList::AT_ownership_takes: 03847 case AttributeList::AT_ownership_holds: 03848 handleOwnershipAttr (S, D, Attr); break; 03849 case AttributeList::AT_cold: handleColdAttr (S, D, Attr); break; 03850 case AttributeList::AT_hot: handleHotAttr (S, D, Attr); break; 03851 case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 03852 case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 03853 case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 03854 case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 03855 case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 03856 03857 case AttributeList::AT_objc_ownership: 03858 handleObjCOwnershipAttr(S, D, Attr); break; 03859 case AttributeList::AT_objc_precise_lifetime: 03860 handleObjCPreciseLifetimeAttr(S, D, Attr); break; 03861 03862 case AttributeList::AT_objc_returns_inner_pointer: 03863 handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 03864 03865 case AttributeList::AT_ns_bridged: 03866 handleNSBridgedAttr(S, scope, D, Attr); break; 03867 03868 case AttributeList::AT_cf_audited_transfer: 03869 case AttributeList::AT_cf_unknown_transfer: 03870 handleCFTransferAttr(S, D, Attr); break; 03871 03872 // Checker-specific. 03873 case AttributeList::AT_cf_consumed: 03874 case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 03875 case AttributeList::AT_ns_consumes_self: 03876 handleNSConsumesSelfAttr(S, D, Attr); break; 03877 03878 case AttributeList::AT_ns_returns_autoreleased: 03879 case AttributeList::AT_ns_returns_not_retained: 03880 case AttributeList::AT_cf_returns_not_retained: 03881 case AttributeList::AT_ns_returns_retained: 03882 case AttributeList::AT_cf_returns_retained: 03883 handleNSReturnsRetainedAttr(S, D, Attr); break; 03884 03885 case AttributeList::AT_reqd_work_group_size: 03886 handleReqdWorkGroupSize(S, D, Attr); break; 03887 03888 case AttributeList::AT_init_priority: 03889 handleInitPriorityAttr(S, D, Attr); break; 03890 03891 case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 03892 case AttributeList::AT_ms_struct: handleMsStructAttr (S, D, Attr); break; 03893 case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 03894 case AttributeList::AT_unavailable: 03895 handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable"); 03896 break; 03897 case AttributeList::AT_objc_arc_weak_reference_unavailable: 03898 handleArcWeakrefUnavailableAttr (S, D, Attr); 03899 break; 03900 case AttributeList::AT_objc_root_class: 03901 handleObjCRootClassAttr(S, D, Attr); 03902 break; 03903 case AttributeList::AT_objc_requires_property_definitions: 03904 handleObjCRequiresPropertyDefsAttr (S, D, Attr); 03905 break; 03906 case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 03907 case AttributeList::AT_returns_twice: 03908 handleReturnsTwiceAttr(S, D, Attr); 03909 break; 03910 case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 03911 case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 03912 case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 03913 break; 03914 case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 03915 case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 03916 case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 03917 case AttributeList::AT_transparent_union: 03918 handleTransparentUnionAttr(S, D, Attr); 03919 break; 03920 case AttributeList::AT_objc_exception: 03921 handleObjCExceptionAttr(S, D, Attr); 03922 break; 03923 case AttributeList::AT_objc_method_family: 03924 handleObjCMethodFamilyAttr(S, D, Attr); 03925 break; 03926 case AttributeList::AT_NSObject: handleObjCNSObject (S, D, Attr); break; 03927 case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 03928 case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 03929 case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 03930 case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 03931 case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 03932 case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 03933 case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 03934 case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 03935 case AttributeList::IgnoredAttribute: 03936 // Just ignore 03937 break; 03938 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 03939 handleNoInstrumentFunctionAttr(S, D, Attr); 03940 break; 03941 case AttributeList::AT_stdcall: 03942 case AttributeList::AT_cdecl: 03943 case AttributeList::AT_fastcall: 03944 case AttributeList::AT_thiscall: 03945 case AttributeList::AT_pascal: 03946 case AttributeList::AT_pcs: 03947 handleCallConvAttr(S, D, Attr); 03948 break; 03949 case AttributeList::AT_opencl_kernel_function: 03950 handleOpenCLKernelAttr(S, D, Attr); 03951 break; 03952 case AttributeList::AT_uuid: 03953 handleUuidAttr(S, D, Attr); 03954 break; 03955 03956 // Thread safety attributes: 03957 case AttributeList::AT_guarded_var: 03958 handleGuardedVarAttr(S, D, Attr); 03959 break; 03960 case AttributeList::AT_pt_guarded_var: 03961 handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 03962 break; 03963 case AttributeList::AT_scoped_lockable: 03964 handleLockableAttr(S, D, Attr, /*scoped = */true); 03965 break; 03966 case AttributeList::AT_no_address_safety_analysis: 03967 handleNoAddressSafetyAttr(S, D, Attr); 03968 break; 03969 case AttributeList::AT_no_thread_safety_analysis: 03970 handleNoThreadSafetyAttr(S, D, Attr); 03971 break; 03972 case AttributeList::AT_lockable: 03973 handleLockableAttr(S, D, Attr); 03974 break; 03975 case AttributeList::AT_guarded_by: 03976 handleGuardedByAttr(S, D, Attr); 03977 break; 03978 case AttributeList::AT_pt_guarded_by: 03979 handleGuardedByAttr(S, D, Attr, /*pointer = */true); 03980 break; 03981 case AttributeList::AT_exclusive_lock_function: 03982 handleLockFunAttr(S, D, Attr, /*exclusive = */true); 03983 break; 03984 case AttributeList::AT_exclusive_locks_required: 03985 handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 03986 break; 03987 case AttributeList::AT_exclusive_trylock_function: 03988 handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 03989 break; 03990 case AttributeList::AT_lock_returned: 03991 handleLockReturnedAttr(S, D, Attr); 03992 break; 03993 case AttributeList::AT_locks_excluded: 03994 handleLocksExcludedAttr(S, D, Attr); 03995 break; 03996 case AttributeList::AT_shared_lock_function: 03997 handleLockFunAttr(S, D, Attr); 03998 break; 03999 case AttributeList::AT_shared_locks_required: 04000 handleLocksRequiredAttr(S, D, Attr); 04001 break; 04002 case AttributeList::AT_shared_trylock_function: 04003 handleTrylockFunAttr(S, D, Attr); 04004 break; 04005 case AttributeList::AT_unlock_function: 04006 handleUnlockFunAttr(S, D, Attr); 04007 break; 04008 case AttributeList::AT_acquired_before: 04009 handleAcquireOrderAttr(S, D, Attr, /*before = */true); 04010 break; 04011 case AttributeList::AT_acquired_after: 04012 handleAcquireOrderAttr(S, D, Attr, /*before = */false); 04013 break; 04014 04015 default: 04016 // Ask target about the attribute. 04017 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 04018 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 04019 S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 04020 << Attr.getName(); 04021 break; 04022 } 04023 } 04024 04025 /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 04026 /// the attribute applies to decls. If the attribute is a type attribute, just 04027 /// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 04028 /// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 04029 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 04030 const AttributeList &Attr, 04031 bool NonInheritable, bool Inheritable) { 04032 if (Attr.isInvalid()) 04033 return; 04034 04035 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 04036 // FIXME: Try to deal with other __declspec attributes! 04037 return; 04038 04039 if (NonInheritable) 04040 ProcessNonInheritableDeclAttr(S, scope, D, Attr); 04041 04042 if (Inheritable) 04043 ProcessInheritableDeclAttr(S, scope, D, Attr); 04044 } 04045 04046 /// ProcessDeclAttributeList - Apply all the decl attributes in the specified 04047 /// attribute list to the specified decl, ignoring any type attributes. 04048 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 04049 const AttributeList *AttrList, 04050 bool NonInheritable, bool Inheritable) { 04051 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 04052 ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 04053 } 04054 04055 // GCC accepts 04056 // static int a9 __attribute__((weakref)); 04057 // but that looks really pointless. We reject it. 04058 if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 04059 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 04060 dyn_cast<NamedDecl>(D)->getNameAsString(); 04061 return; 04062 } 04063 } 04064 04065 // Annotation attributes are the only attributes allowed after an access 04066 // specifier. 04067 bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 04068 const AttributeList *AttrList) { 04069 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 04070 if (l->getKind() == AttributeList::AT_annotate) { 04071 handleAnnotateAttr(*this, ASDecl, *l); 04072 } else { 04073 Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 04074 return true; 04075 } 04076 } 04077 04078 return false; 04079 } 04080 04081 /// checkUnusedDeclAttributes - Check a list of attributes to see if it 04082 /// contains any decl attributes that we should warn about. 04083 static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 04084 for ( ; A; A = A->getNext()) { 04085 // Only warn if the attribute is an unignored, non-type attribute. 04086 if (A->isUsedAsTypeAttr()) continue; 04087 if (A->getKind() == AttributeList::IgnoredAttribute) continue; 04088 04089 if (A->getKind() == AttributeList::UnknownAttribute) { 04090 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 04091 << A->getName() << A->getRange(); 04092 } else { 04093 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 04094 << A->getName() << A->getRange(); 04095 } 04096 } 04097 } 04098 04099 /// checkUnusedDeclAttributes - Given a declarator which is not being 04100 /// used to build a declaration, complain about any decl attributes 04101 /// which might be lying around on it. 04102 void Sema::checkUnusedDeclAttributes(Declarator &D) { 04103 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 04104 ::checkUnusedDeclAttributes(*this, D.getAttributes()); 04105 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 04106 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 04107 } 04108 04109 /// DeclClonePragmaWeak - clone existing decl (maybe definition), 04110 /// #pragma weak needs a non-definition decl and source may not have one 04111 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 04112 SourceLocation Loc) { 04113 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 04114 NamedDecl *NewD = 0; 04115 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 04116 FunctionDecl *NewFD; 04117 // FIXME: Missing call to CheckFunctionDeclaration(). 04118 // FIXME: Mangling? 04119 // FIXME: Is the qualifier info correct? 04120 // FIXME: Is the DeclContext correct? 04121 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 04122 Loc, Loc, DeclarationName(II), 04123 FD->getType(), FD->getTypeSourceInfo(), 04124 SC_None, SC_None, 04125 false/*isInlineSpecified*/, 04126 FD->hasPrototype(), 04127 false/*isConstexprSpecified*/); 04128 NewD = NewFD; 04129 04130 if (FD->getQualifier()) 04131 NewFD->setQualifierInfo(FD->getQualifierLoc()); 04132 04133 // Fake up parameter variables; they are declared as if this were 04134 // a typedef. 04135 QualType FDTy = FD->getType(); 04136 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 04137 SmallVector<ParmVarDecl*, 16> Params; 04138 for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 04139 AE = FT->arg_type_end(); AI != AE; ++AI) { 04140 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 04141 Param->setScopeInfo(0, Params.size()); 04142 Params.push_back(Param); 04143 } 04144 NewFD->setParams(Params); 04145 } 04146 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 04147 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 04148 VD->getInnerLocStart(), VD->getLocation(), II, 04149 VD->getType(), VD->getTypeSourceInfo(), 04150 VD->getStorageClass(), 04151 VD->getStorageClassAsWritten()); 04152 if (VD->getQualifier()) { 04153 VarDecl *NewVD = cast<VarDecl>(NewD); 04154 NewVD->setQualifierInfo(VD->getQualifierLoc()); 04155 } 04156 } 04157 return NewD; 04158 } 04159 04160 /// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 04161 /// applied to it, possibly with an alias. 04162 void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 04163 if (W.getUsed()) return; // only do this once 04164 W.setUsed(true); 04165 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 04166 IdentifierInfo *NDId = ND->getIdentifier(); 04167 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 04168 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 04169 NDId->getName())); 04170 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 04171 WeakTopLevelDecl.push_back(NewD); 04172 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 04173 // to insert Decl at TU scope, sorry. 04174 DeclContext *SavedContext = CurContext; 04175 CurContext = Context.getTranslationUnitDecl(); 04176 PushOnScopeChains(NewD, S); 04177 CurContext = SavedContext; 04178 } else { // just add weak to existing 04179 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 04180 } 04181 } 04182 04183 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 04184 /// it, apply them to D. This is a bit tricky because PD can have attributes 04185 /// specified in many different places, and we need to find and apply them all. 04186 void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 04187 bool NonInheritable, bool Inheritable) { 04188 // It's valid to "forward-declare" #pragma weak, in which case we 04189 // have to do this. 04190 if (Inheritable) { 04191 LoadExternalWeakUndeclaredIdentifiers(); 04192 if (!WeakUndeclaredIdentifiers.empty()) { 04193 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 04194 if (IdentifierInfo *Id = ND->getIdentifier()) { 04195 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 04196 = WeakUndeclaredIdentifiers.find(Id); 04197 if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 04198 WeakInfo W = I->second; 04199 DeclApplyPragmaWeak(S, ND, W); 04200 WeakUndeclaredIdentifiers[Id] = W; 04201 } 04202 } 04203 } 04204 } 04205 } 04206 04207 // Apply decl attributes from the DeclSpec if present. 04208 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 04209 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 04210 04211 // Walk the declarator structure, applying decl attributes that were in a type 04212 // position to the decl itself. This handles cases like: 04213 // int *__attr__(x)** D; 04214 // when X is a decl attribute. 04215 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 04216 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 04217 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 04218 04219 // Finally, apply any attributes on the decl itself. 04220 if (const AttributeList *Attrs = PD.getAttributes()) 04221 ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 04222 } 04223 04224 /// Is the given declaration allowed to use a forbidden type? 04225 static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 04226 // Private ivars are always okay. Unfortunately, people don't 04227 // always properly make their ivars private, even in system headers. 04228 // Plus we need to make fields okay, too. 04229 // Function declarations in sys headers will be marked unavailable. 04230 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 04231 !isa<FunctionDecl>(decl)) 04232 return false; 04233 04234 // Require it to be declared in a system header. 04235 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 04236 } 04237 04238 /// Handle a delayed forbidden-type diagnostic. 04239 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 04240 Decl *decl) { 04241 if (decl && isForbiddenTypeAllowed(S, decl)) { 04242 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 04243 "this system declaration uses an unsupported type")); 04244 return; 04245 } 04246 if (S.getLangOpts().ObjCAutoRefCount) 04247 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 04248 // FIXME. we may want to supress diagnostics for all 04249 // kind of forbidden type messages on unavailable functions. 04250 if (FD->hasAttr<UnavailableAttr>() && 04251 diag.getForbiddenTypeDiagnostic() == 04252 diag::err_arc_array_param_no_ownership) { 04253 diag.Triggered = true; 04254 return; 04255 } 04256 } 04257 04258 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 04259 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 04260 diag.Triggered = true; 04261 } 04262 04263 void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { 04264 assert(DelayedDiagnostics.getCurrentPool()); 04265 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); 04266 DelayedDiagnostics.popWithoutEmitting(state); 04267 04268 // When delaying diagnostics to run in the context of a parsed 04269 // declaration, we only want to actually emit anything if parsing 04270 // succeeds. 04271 if (!decl) return; 04272 04273 // We emit all the active diagnostics in this pool or any of its 04274 // parents. In general, we'll get one pool for the decl spec 04275 // and a child pool for each declarator; in a decl group like: 04276 // deprecated_typedef foo, *bar, baz(); 04277 // only the declarator pops will be passed decls. This is correct; 04278 // we really do need to consider delayed diagnostics from the decl spec 04279 // for each of the different declarations. 04280 const DelayedDiagnosticPool *pool = &poppedPool; 04281 do { 04282 for (DelayedDiagnosticPool::pool_iterator 04283 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { 04284 // This const_cast is a bit lame. Really, Triggered should be mutable. 04285 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); 04286 if (diag.Triggered) 04287 continue; 04288 04289 switch (diag.Kind) { 04290 case DelayedDiagnostic::Deprecation: 04291 // Don't bother giving deprecation diagnostics if the decl is invalid. 04292 if (!decl->isInvalidDecl()) 04293 HandleDelayedDeprecationCheck(diag, decl); 04294 break; 04295 04296 case DelayedDiagnostic::Access: 04297 HandleDelayedAccessCheck(diag, decl); 04298 break; 04299 04300 case DelayedDiagnostic::ForbiddenType: 04301 handleDelayedForbiddenType(*this, diag, decl); 04302 break; 04303 } 04304 } 04305 } while ((pool = pool->getParent())); 04306 } 04307 04308 /// Given a set of delayed diagnostics, re-emit them as if they had 04309 /// been delayed in the current context instead of in the given pool. 04310 /// Essentially, this just moves them to the current pool. 04311 void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { 04312 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); 04313 assert(curPool && "re-emitting in undelayed context not supported"); 04314 curPool->steal(pool); 04315 } 04316 04317 static bool isDeclDeprecated(Decl *D) { 04318 do { 04319 if (D->isDeprecated()) 04320 return true; 04321 // A category implicitly has the availability of the interface. 04322 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 04323 return CatD->getClassInterface()->isDeprecated(); 04324 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 04325 return false; 04326 } 04327 04328 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 04329 Decl *Ctx) { 04330 if (isDeclDeprecated(Ctx)) 04331 return; 04332 04333 DD.Triggered = true; 04334 if (!DD.getDeprecationMessage().empty()) 04335 Diag(DD.Loc, diag::warn_deprecated_message) 04336 << DD.getDeprecationDecl()->getDeclName() 04337 << DD.getDeprecationMessage(); 04338 else if (DD.getUnknownObjCClass()) { 04339 Diag(DD.Loc, diag::warn_deprecated_fwdclass_message) 04340 << DD.getDeprecationDecl()->getDeclName(); 04341 Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class); 04342 } 04343 else 04344 Diag(DD.Loc, diag::warn_deprecated) 04345 << DD.getDeprecationDecl()->getDeclName(); 04346 } 04347 04348 void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 04349 SourceLocation Loc, 04350 const ObjCInterfaceDecl *UnknownObjCClass) { 04351 // Delay if we're currently parsing a declaration. 04352 if (DelayedDiagnostics.shouldDelayDiagnostics()) { 04353 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 04354 UnknownObjCClass, 04355 Message)); 04356 return; 04357 } 04358 04359 // Otherwise, don't warn if our current context is deprecated. 04360 if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 04361 return; 04362 if (!Message.empty()) { 04363 Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 04364 << Message; 04365 Diag(D->getLocation(), 04366 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 04367 : diag::note_previous_decl) << D->getDeclName(); 04368 } 04369 else { 04370 if (!UnknownObjCClass) 04371 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 04372 else { 04373 Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 04374 Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 04375 } 04376 } 04377 }