summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp352
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)
OpenPOWER on IntegriCloud