diff options
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 352 |
1 files changed, 162 insertions, 190 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index b9e4ef06330..00f8af9382b 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -419,7 +419,7 @@ static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, int Sidx = 0, bool ParamIdxOk = false) { for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { - Expr *ArgExp = Attr.getArg(Idx); + Expr *ArgExp = Attr.getArgAsExpr(Idx); if (ArgExp->isTypeDependent()) { // FIXME -- need to check this again on template instantiation @@ -815,7 +815,7 @@ static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, return false; } - if (!isIntOrBool(Attr.getArg(0))) { + if (!isIntOrBool(Attr.getArgAsExpr(0))) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) << Attr.getName() << 1 << AANT_ArgumentIntOrBool; return false; @@ -833,11 +833,10 @@ static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) return; - unsigned Size = Args.size(); - Expr **StartArg = Size == 0 ? 0 : &Args[0]; D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), S.Context, - Attr.getArg(0), StartArg, Size, + Attr.getArgAsExpr(0), + Args.data(), Args.size(), Attr.getAttributeSpellingListIndex())); } @@ -847,11 +846,10 @@ static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) return; - unsigned Size = Args.size(); - Expr **StartArg = Size == 0 ? 0 : &Args[0]; D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context, - Attr.getArg(0), StartArg, Size, + Attr.getArgAsExpr(0), + Args.data(), Args.size(), Attr.getAttributeSpellingListIndex())); } @@ -1177,7 +1175,7 @@ static void handleIBOutletCollection(Sema &S, Decl *D, const AttributeList &Attr) { // The iboutletcollection attribute can have zero or one arguments. - if (Attr.getParameterName() && Attr.getNumArgs() > 0) { + if (Attr.getNumArgs() > 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr.getName() << 1; return; @@ -1186,9 +1184,15 @@ static void handleIBOutletCollection(Sema &S, Decl *D, if (!checkIBOutletCommon(S, D, Attr)) return; - IdentifierInfo *II = Attr.getParameterName(); - if (!II) + IdentifierLoc *IL = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0; + IdentifierInfo *II; + SourceLocation ILS; + if (IL) { + II = IL->Ident; + ILS = IL->Loc; + } else { II = &S.Context.Idents.get("NSObject"); + } ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), S.getScopeForContext(D->getDeclContext()->getParent())); @@ -1206,8 +1210,7 @@ static void handleIBOutletCollection(Sema &S, Decl *D, return; } D->addAttr(::new (S.Context) - IBOutletCollectionAttr(Attr.getRange(),S.Context, - QT, Attr.getParameterLoc(), + IBOutletCollectionAttr(Attr.getRange(), S.Context, QT, ILS, Attr.getAttributeSpellingListIndex())); } @@ -1238,7 +1241,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { SmallVector<unsigned, 8> SizeArgs; for (unsigned i = 0; i < Attr.getNumArgs(); ++i) { - Expr *Ex = Attr.getArg(i); + Expr *Ex = Attr.getArgAsExpr(i); uint64_t Idx; if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(), Attr.getLoc(), i + 1, Ex, Idx)) @@ -1278,7 +1281,7 @@ static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { SmallVector<unsigned, 8> NonNullArgs; for (unsigned i = 0; i < Attr.getNumArgs(); ++i) { - Expr *Ex = Attr.getArg(i); + Expr *Ex = Attr.getArgAsExpr(i); uint64_t Idx; if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(), Attr.getLoc(), i + 1, Ex, Idx)) @@ -1336,7 +1339,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { // after being held. free() should be __attribute((ownership_takes)), whereas // a list append function may well be __attribute((ownership_holds)). - if (!AL.getParameterName()) { + if (!AL.isArgIdent(0)) { S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) << AL.getName()->getName() << 1 << AANT_ArgumentString; return; @@ -1346,7 +1349,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { switch (AL.getKind()) { case AttributeList::AT_ownership_takes: K = OwnershipAttr::Takes; - if (AL.getNumArgs() < 1) { + if (AL.getNumArgs() < 2) { S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL.getName() << 2; return; @@ -1354,7 +1357,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { break; case AttributeList::AT_ownership_holds: K = OwnershipAttr::Holds; - if (AL.getNumArgs() < 1) { + if (AL.getNumArgs() < 2) { S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL.getName() << 2; return; @@ -1362,9 +1365,9 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { break; case AttributeList::AT_ownership_returns: K = OwnershipAttr::Returns; - if (AL.getNumArgs() > 1) { + if (AL.getNumArgs() > 2) { S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) - << AL.getName() << AL.getNumArgs() + 1; + << AL.getName() << AL.getNumArgs() + 2; return; } break; @@ -1379,7 +1382,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { return; } - StringRef Module = AL.getParameterName()->getName(); + StringRef Module = AL.getArgAsIdent(0)->Ident->getName(); // Normalize the argument, __foo__ becomes foo. if (Module.startswith("__") && Module.endswith("__")) @@ -1387,11 +1390,11 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { SmallVector<unsigned, 8> OwnershipArgs; - for (unsigned i = 0; i < AL.getNumArgs(); ++i) { - Expr *Ex = AL.getArg(i); + for (unsigned i = 1; i < AL.getNumArgs(); ++i) { + Expr *Ex = AL.getArgAsExpr(i); uint64_t Idx; if (!checkFunctionOrMethodArgumentIndex(S, D, AL.getName()->getName(), - AL.getLoc(), i + 1, Ex, Idx)) + AL.getLoc(), i, Ex, Idx)) return; switch (K) { @@ -1410,9 +1413,9 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { break; } case OwnershipAttr::Returns: { - if (AL.getNumArgs() > 1) { + if (AL.getNumArgs() > 2) { // Is the function argument an integer type? - Expr *IdxExpr = AL.getArg(0); + Expr *IdxExpr = AL.getArgAsExpr(1); llvm::APSInt ArgNum(32); if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { @@ -1514,8 +1517,8 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { // static ((alias ("y"), weakref)). // Should we? How to check that weakref is before or after alias? - if (Attr.getNumArgs() == 1) { - Expr *Arg = Attr.getArg(0); + if (Attr.isArgExpr(0)) { + Expr *Arg = Attr.getArgAsExpr(0); Arg = Arg->IgnoreParenCasts(); StringLiteral *Str = dyn_cast<StringLiteral>(Arg); @@ -1540,9 +1543,9 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (!checkAttributeNumArgs(S, Attr, 1)) return; - Expr *Arg = Attr.getArg(0); - Arg = Arg->IgnoreParenCasts(); - StringLiteral *Str = dyn_cast<StringLiteral>(Arg); + StringLiteral *Str = 0; + if (Attr.isArgExpr(0)) + Str = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0)->IgnoreParenCasts()); if (!Str || !Str->isAscii()) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) @@ -1639,11 +1642,8 @@ static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { static void handleAlwaysInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (!isa<FunctionDecl>(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) @@ -1662,7 +1662,7 @@ static void handleTLSModelAttr(Sema &S, Decl *D, if (!checkAttributeNumArgs(S, Attr, 1)) return; - Expr *Arg = Attr.getArg(0); + Expr *Arg = Attr.getArgAsExpr(0); Arg = Arg->IgnoreParenCasts(); StringLiteral *Str = dyn_cast<StringLiteral>(Arg); @@ -1694,11 +1694,8 @@ static void handleTLSModelAttr(Sema &S, Decl *D, static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { QualType RetTy = FD->getResultType(); @@ -1765,9 +1762,7 @@ static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { } bool Sema::CheckNoReturnAttr(const AttributeList &attr) { - if (attr.hasParameterOrArguments()) { - Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << attr.getName() << 0; + if (!checkAttributeNumArgs(*this, attr, 0)) { attr.setInvalid(); return true; } @@ -1904,11 +1899,8 @@ static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) { @@ -1925,11 +1917,8 @@ static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { static void handleReturnsTwiceAttr(Sema &S, Decl *D, const AttributeList &Attr) { // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (!isa<FunctionDecl>(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) @@ -1944,11 +1933,8 @@ static void handleReturnsTwiceAttr(Sema &S, Decl *D, static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (VD->hasLocalStorage()) { @@ -1975,7 +1961,7 @@ static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { int priority = 65535; // FIXME: Do not hardcode such constants. if (Attr.getNumArgs() > 0) { - Expr *E = Attr.getArg(0); + Expr *E = Attr.getArgAsExpr(0); llvm::APSInt Idx(32); if (E->isTypeDependent() || E->isValueDependent() || !E->isIntegerConstantExpr(Idx, S.Context)) { @@ -2007,7 +1993,7 @@ static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { int priority = 65535; // FIXME: Do not hardcode such constants. if (Attr.getNumArgs() > 0) { - Expr *E = Attr.getArg(0); + Expr *E = Attr.getArgAsExpr(0); llvm::APSInt Idx(32); if (E->isTypeDependent() || E->isValueDependent() || !E->isIntegerConstantExpr(Idx, S.Context)) { @@ -2041,11 +2027,12 @@ static void handleAttrWithMessage(Sema &S, Decl *D, // Handle the case where the attribute has a text message. StringRef Str; - if (NumArgs == 1) { - StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); + if (Attr.isArgExpr(0)) { + StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0)); if (!SE) { - S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_argument_type) - << Attr.getName() << AANT_ArgumentString; + S.Diag(Attr.getArgAsExpr(0)->getLocStart(), + diag::err_attribute_argument_type) << Attr.getName() + << AANT_ArgumentString; return; } Str = SE->getString(); @@ -2280,13 +2267,15 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, static void handleAvailabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { - IdentifierInfo *Platform = Attr.getParameterName(); - SourceLocation PlatformLoc = Attr.getParameterLoc(); + if (!checkAttributeNumArgs(S, Attr, 1)) + return; + IdentifierLoc *Platform = Attr.getArgAsIdent(0); unsigned Index = Attr.getAttributeSpellingListIndex(); - if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty()) - S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) - << Platform; + IdentifierInfo *II = Platform->Ident; + if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty()) + S.Diag(Platform->Loc, diag::warn_availability_unknown_platform) + << Platform->Ident; NamedDecl *ND = dyn_cast<NamedDecl>(D); if (!ND) { @@ -2304,8 +2293,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, if (SE) Str = SE->getString(); - AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), - Platform, + AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II, Introduced.Version, Deprecated.Version, Obsoleted.Version, @@ -2369,7 +2357,7 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr, if (!checkAttributeNumArgs(S, Attr, 1)) return; - Expr *Arg = Attr.getArg(0); + Expr *Arg = Attr.getArgAsExpr(0); Arg = Arg->IgnoreParenCasts(); StringLiteral *Str = dyn_cast<StringLiteral>(Arg); @@ -2424,19 +2412,18 @@ static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, return; } - if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { - if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) - << Attr.getName() << 1 << AANT_ArgumentString; - } else { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; - } - Attr.setInvalid(); + if (!Attr.isArgIdent(0)) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) + << Attr.getName() << 1 << AANT_ArgumentIdentifier; return; } + + if (!checkAttributeNumArgs(S, Attr, 1)) + return; + + IdentifierLoc *IL = Attr.getArgAsIdent(0); - StringRef param = Attr.getParameterName()->getName(); + StringRef param = IL->Ident->getName(); ObjCMethodFamilyAttr::FamilyKind family; if (param == "none") family = ObjCMethodFamilyAttr::OMF_None; @@ -2453,7 +2440,7 @@ static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, else { // Just warn and ignore it. This is future-proof against new // families being used in system headers. - S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); + S.Diag(IL->Loc, diag::warn_unknown_method_family); return; } @@ -2533,24 +2520,22 @@ handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { } static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { - if (!Attr.getParameterName()) { + if (!Attr.isArgIdent(0)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) - << Attr.getName() << 1 << AANT_ArgumentString; + << Attr.getName() << 1 << AANT_ArgumentIdentifier; return; } - - if (Attr.getNumArgs() != 0) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 1; + + if (!checkAttributeNumArgs(S, Attr, 1)) return; - } + IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; BlocksAttr::BlockType type; - if (Attr.getParameterName()->isStr("byref")) + if (II->isStr("byref")) type = BlocksAttr::ByRef; else { - S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) - << "blocks" << Attr.getParameterName(); + S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) << "blocks" + << II; return; } @@ -2568,7 +2553,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { unsigned sentinel = 0; if (Attr.getNumArgs() > 0) { - Expr *E = Attr.getArg(0); + Expr *E = Attr.getArgAsExpr(0); llvm::APSInt Idx(32); if (E->isTypeDependent() || E->isValueDependent() || !E->isIntegerConstantExpr(Idx, S.Context)) { @@ -2589,7 +2574,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { unsigned nullPos = 0; if (Attr.getNumArgs() > 1) { - Expr *E = Attr.getArg(1); + Expr *E = Attr.getArgAsExpr(1); llvm::APSInt Idx(32); if (E->isTypeDependent() || E->isValueDependent() || !E->isIntegerConstantExpr(Idx, S.Context)) { @@ -2696,11 +2681,8 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { if (isa<CXXRecordDecl>(D)) { @@ -2758,7 +2740,7 @@ static void handleWorkGroupSize(Sema &S, Decl *D, unsigned WGSize[3]; for (unsigned i = 0; i < 3; ++i) { - Expr *E = Attr.getArg(i); + Expr *E = Attr.getArgAsExpr(i); llvm::APSInt ArgNum(32); if (E->isTypeDependent() || E->isValueDependent() || !E->isIntegerConstantExpr(ArgNum, S.Context)) { @@ -2807,9 +2789,14 @@ static void handleWorkGroupSize(Sema &S, Decl *D, static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { assert(Attr.getKind() == AttributeList::AT_VecTypeHint); - // Attribute has 1 argument. - if (!checkAttributeNumArgs(S, Attr, 1)) + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + if (!Attr.hasParsedType()) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) + << Attr.getName() << 1; return; + } QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg()); @@ -2835,10 +2822,19 @@ static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { } static void handleEndianAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (!Attr.isArgIdent(0)) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) + << Attr.getName() << 1 << AANT_ArgumentIdentifier; + return; + } + + if (!checkAttributeNumArgs(S, Attr, 1)) + return; + if (!dyn_cast<VarDecl>(D)) - S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "endian" - << 9; - StringRef EndianType = Attr.getParameterName()->getName(); + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << Attr.getName() << ExpectedVariable; + StringRef EndianType = Attr.getArgAsIdent(0)->Ident->getName(); if (EndianType != "host" && EndianType != "device") S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_endian) << EndianType; } @@ -2864,7 +2860,7 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Make sure that there is a string literal as the sections's single // argument. - Expr *ArgExpr = Attr.getArg(0); + Expr *ArgExpr = Attr.getArgAsExpr(0); StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); if (!SE) { S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) @@ -2895,12 +2891,8 @@ static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { - // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { if (Existing->getLocation().isInvalid()) @@ -2913,12 +2905,8 @@ static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { } static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { - // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { if (Existing->getLocation().isInvalid()) @@ -2941,17 +2929,14 @@ static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { } static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { - if (!Attr.getParameterName()) { + if (!Attr.isArgIdent(0)) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr.getName() << 1; return; } - - if (Attr.getNumArgs() != 0) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 1; + + if (!checkAttributeNumArgs(S, Attr, 1)) return; - } VarDecl *VD = dyn_cast<VarDecl>(D); @@ -2960,29 +2945,27 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { return; } + IdentifierLoc *IL = Attr.getArgAsIdent(0); + // Look up the function // FIXME: Lookup probably isn't looking in the right place NamedDecl *CleanupDecl - = S.LookupSingleName(S.TUScope, Attr.getParameterName(), - Attr.getParameterLoc(), Sema::LookupOrdinaryName); + = S.LookupSingleName(S.TUScope, IL->Ident, IL->Loc, + Sema::LookupOrdinaryName); if (!CleanupDecl) { - S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << - Attr.getParameterName(); + S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_found) << IL->Ident; return; } FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); if (!FD) { - S.Diag(Attr.getParameterLoc(), - diag::err_attribute_cleanup_arg_not_function) - << Attr.getParameterName(); + S.Diag(IL->Loc, diag::err_attribute_cleanup_arg_not_function) << IL->Ident; return; } if (FD->getNumParams() != 1) { - S.Diag(Attr.getParameterLoc(), - diag::err_attribute_cleanup_func_must_take_one_arg) - << Attr.getParameterName(); + S.Diag(IL->Loc, diag::err_attribute_cleanup_func_must_take_one_arg) + << IL->Ident; return; } @@ -2992,17 +2975,16 @@ static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { QualType ParamTy = FD->getParamDecl(0)->getType(); if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), ParamTy, Ty) != Sema::Compatible) { - S.Diag(Attr.getParameterLoc(), - diag::err_attribute_cleanup_func_arg_incompatible_type) << - Attr.getParameterName() << ParamTy << Ty; + S.Diag(IL->Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) << + IL->Ident << ParamTy << Ty; return; } D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD, Attr.getAttributeSpellingListIndex())); - S.MarkFunctionReferenced(Attr.getParameterLoc(), FD); - S.DiagnoseUseOfDecl(FD, Attr.getParameterLoc()); + S.MarkFunctionReferenced(IL->Loc, FD); + S.DiagnoseUseOfDecl(FD, IL->Loc); } /// Handle __attribute__((format_arg((idx)))) attribute based on @@ -3017,7 +2999,7 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { return; } - Expr *IdxExpr = Attr.getArg(0); + Expr *IdxExpr = Attr.getArgAsExpr(0); uint64_t ArgIdx; if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(), Attr.getLoc(), 1, IdxExpr, ArgIdx)) @@ -3114,7 +3096,7 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, Attr.setInvalid(); return; } - Expr *priorityExpr = Attr.getArg(0); + Expr *priorityExpr = Attr.getArgAsExpr(0); llvm::APSInt priority(32); if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || @@ -3164,18 +3146,14 @@ FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, /// Handle __attribute__((format(type,idx,firstarg))) attributes based on /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { - - if (!Attr.getParameterName()) { + if (!Attr.isArgIdent(0)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) - << Attr.getName() << 1 << AANT_ArgumentString; + << Attr.getName() << 1 << AANT_ArgumentIdentifier; return; } - - if (Attr.getNumArgs() != 2) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 3; + + if (!checkAttributeNumArgs(S, Attr, 3)) return; - } if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) @@ -3189,7 +3167,8 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; unsigned FirstIdx = 1; - StringRef Format = Attr.getParameterName()->getName(); + IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; + StringRef Format = II->getName(); // Normalize the argument, __foo__ becomes foo. if (Format.startswith("__") && Format.endswith("__")) @@ -3203,12 +3182,12 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (Kind == InvalidFormat) { S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) - << "format" << Attr.getParameterName()->getName(); + << "format" << II->getName(); return; } // checks for the 2nd argument - Expr *IdxExpr = Attr.getArg(0); + Expr *IdxExpr = Attr.getArgAsExpr(1); llvm::APSInt Idx(32); if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { @@ -3264,7 +3243,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { } // check the 3rd argument - Expr *FirstArgExpr = Attr.getArg(1); + Expr *FirstArgExpr = Attr.getArgAsExpr(2); llvm::APSInt FirstArg(32); if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { @@ -3381,7 +3360,7 @@ static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (!checkAttributeNumArgs(S, Attr, 1)) return; - Expr *ArgExpr = Attr.getArg(0); + Expr *ArgExpr = Attr.getArgAsExpr(0); StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); // Make sure that there is a string literal as the annotation's single @@ -3419,7 +3398,7 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { return; } - Expr *E = Attr.getArg(0); + Expr *E = Attr.getArgAsExpr(0); if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) { S.Diag(Attr.getEllipsisLoc(), diag::err_pack_expansion_without_parameter_packs); @@ -3576,20 +3555,17 @@ void Sema::CheckAlignasUnderalignment(Decl *D) { static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { // This attribute isn't documented, but glibc uses it. It changes // the width of an int or unsigned int to the specified size. - - // Check that there aren't any arguments - if (!checkAttributeNumArgs(S, Attr, 0)) - return; - - - IdentifierInfo *Name = Attr.getParameterName(); - if (!Name) { + if (!Attr.isArgIdent(0)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() << AANT_ArgumentIdentifier; return; } + + if (!checkAttributeNumArgs(S, Attr, 1)) + return; - StringRef Str = Attr.getParameterName()->getName(); + IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident; + StringRef Str = Name->getName(); // Normalize the attribute name, __foo__ becomes foo. if (Str.startswith("__") && Str.endswith("__")) @@ -3808,12 +3784,8 @@ static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (S.LangOpts.CUDA) { - // check the attribute arguments. - if (Attr.hasParameterOrArguments()) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << 0; + if (!checkAttributeNumArgs(S, Attr, 0)) return; - } if (!isa<VarDecl>(D)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) @@ -4041,7 +4013,7 @@ static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ } static void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){ - Expr *E = Attr.getArg(0); + Expr *E = Attr.getArgAsExpr(0); llvm::APSInt ArgNum(32); if (E->isTypeDependent() || E->isValueDependent() || !E->isIntegerConstantExpr(ArgNum, S.Context)) { @@ -4061,9 +4033,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, return true; unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0; - if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) { - Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << attr.getName() << ReqArgs; + if (!checkAttributeNumArgs(*this, attr, ReqArgs)) { attr.setInvalid(); return true; } @@ -4085,8 +4055,10 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, CC_C; break; case AttributeList::AT_Pcs: { - Expr *Arg = attr.getArg(0); - StringLiteral *Str = dyn_cast<StringLiteral>(Arg); + StringLiteral *Str = 0; + if (attr.isArgExpr(0)) + Str = dyn_cast<StringLiteral>(attr.getArgAsExpr(0)); + if (!Str || !Str->isAscii()) { Diag(attr.getLoc(), diag::err_attribute_argument_type) << attr.getName() << AANT_ArgumentString; @@ -4156,7 +4128,7 @@ bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { return true; } - Expr *NumParamsExpr = Attr.getArg(0); + Expr *NumParamsExpr = Attr.getArgAsExpr(0); llvm::APSInt NumParams(32); if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { @@ -4200,7 +4172,7 @@ static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ return; } - Expr *MaxThreadsExpr = Attr.getArg(0); + Expr *MaxThreadsExpr = Attr.getArgAsExpr(0); llvm::APSInt MaxThreads(32); if (MaxThreadsExpr->isTypeDependent() || MaxThreadsExpr->isValueDependent() || @@ -4213,7 +4185,7 @@ static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ llvm::APSInt MinBlocks(32); if (Attr.getNumArgs() > 1) { - Expr *MinBlocksExpr = Attr.getArg(1); + Expr *MinBlocksExpr = Attr.getArgAsExpr(1); if (MinBlocksExpr->isTypeDependent() || MinBlocksExpr->isValueDependent() || !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { @@ -4236,20 +4208,17 @@ static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, const AttributeList &Attr) { - StringRef AttrName = Attr.getName()->getName(); - if (!Attr.getParameterName()) { + if (!Attr.isArgIdent(0)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier; return; } - - if (Attr.getNumArgs() != 2) { - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) - << Attr.getName() << /* required args = */ 3; + + if (!checkAttributeNumArgs(S, Attr, 3)) return; - } - IdentifierInfo *ArgumentKind = Attr.getParameterName(); + StringRef AttrName = Attr.getName()->getName(); + IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident; if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) @@ -4260,13 +4229,13 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, uint64_t ArgumentIdx; if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, Attr.getLoc(), 2, - Attr.getArg(0), ArgumentIdx)) + Attr.getArgAsExpr(1), ArgumentIdx)) return; uint64_t TypeTagIdx; if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, Attr.getLoc(), 3, - Attr.getArg(1), TypeTagIdx)) + Attr.getArgAsExpr(2), TypeTagIdx)) return; bool IsPointer = (AttrName == "pointer_with_type_tag"); @@ -4287,13 +4256,16 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, const AttributeList &Attr) { - IdentifierInfo *PointerKind = Attr.getParameterName(); - if (!PointerKind) { + if (!Attr.isArgIdent(0)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) << Attr.getName() << 1 << AANT_ArgumentIdentifier; return; } + + if (!checkAttributeNumArgs(S, Attr, 1)) + return; + IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident; QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL); D->addAttr(::new (S.Context) @@ -4544,14 +4516,14 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, << Attr.getRange() << Attr.getName() << ExpectedStruct; } - IdentifierInfo *ParmName = Attr.getParameterName(); + IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0; // In Objective-C, verify that the type names an Objective-C type. // We don't want to check this outside of ObjC because people sometimes // do crazy C declarations of Objective-C types. - if (ParmName && S.getLangOpts().ObjC1) { + if (Parm && S.getLangOpts().ObjC1) { // Check for an existing type with this name. - LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), + LookupResult R(S, DeclarationName(Parm->Ident), Parm->Loc, Sema::LookupOrdinaryName); if (S.LookupName(R, Sc)) { NamedDecl *Target = R.getFoundDecl(); @@ -4563,7 +4535,7 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, } D->addAttr(::new (S.Context) - NSBridgedAttr(Attr.getRange(), S.Context, ParmName, + NSBridgedAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0, Attr.getAttributeSpellingListIndex())); } @@ -4644,7 +4616,7 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (!checkAttributeNumArgs(S, Attr, 1)) return; - Expr *Arg = Attr.getArg(0); + Expr *Arg = Attr.getArgAsExpr(0); StringLiteral *Str = dyn_cast<StringLiteral>(Arg); if (!Str || !Str->isAscii()) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) |