Generate Attr subclasses with TableGen.
Now all classes derived from Attr are generated from TableGen.
Additionally, Attr* is no longer its own linked list; SmallVectors or
Attr* are used. The accompanying LLVM commit contains the updates to
TableGen necessary for this.
Some other notes about newly-generated attribute classes:
- The constructor arguments are a SourceLocation and a Context&,
followed by the attributes arguments in the order that they were
defined in Attr.td
- Every argument in Attr.td has an appropriate accessor named getFoo,
and there are sometimes a few extra ones (such as to get the length
of a variadic argument).
Additionally, specific_attr_iterator has been introduced, which will
iterate over an AttrVec, but only over attributes of a certain type. It
can be accessed through either Decl::specific_attr_begin/end or
the global functions of the same name.
llvm-svn: 111455
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 8bcb6162..0fd3d6e 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -1454,13 +1454,14 @@
}
static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &A) {
// The 'ibaction' attribute is allowed on method definitions because of
// how the IBAction macro is used on both method declarations and definitions.
// If the method definitions contains any other attributes, return true.
- while (A && A->getKind() == AttributeList::AT_IBAction)
- A = A->getNext();
- return A != NULL;
+ for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+ if ((*i)->getKind() != attr::IBAction)
+ return true;
+ return false;
}
Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
@@ -1590,7 +1591,8 @@
}
InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
MethodType == tok::minus);
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
} else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1601,7 +1603,8 @@
PrevMethod = CatImpDecl->getClassMethod(Sel);
CatImpDecl->addClassMethod(ObjCMethod);
}
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
}
if (PrevMethod) {
@@ -1613,8 +1616,10 @@
// If the interface declared this method, and it was deprecated there,
// mark it deprecated here.
- if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
- ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+ if (InterfaceMD)
+ if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+ ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+ Context));
return DeclPtrTy::make(ObjCMethod);
}