Make ProcessDeclAttributes walk the declarator structure pulling

decl attributes out of the various places they can hide.  This makes
us correctly reject things like this:

t.c:2:22: error: mode attribute only supported for integer and floating-point types
  int **__attribute((mode(HI)))* i32;
                     ^

because you can't make a pointer be HImode.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52876 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-06-29 00:16:31 +00:00
Родитель 3ff30c8e6e
Коммит e5c5ee1cff
4 изменённых файлов: 59 добавлений и 20 удалений

Просмотреть файл

@ -457,6 +457,19 @@ struct DeclaratorChunk {
};
/// getAttrs - If there are attributes applied to this declaratorchunk, return
/// them.
const AttributeList *getAttrs() const {
switch (Kind) {
default: assert(0 && "Unknown declarator kind!");
case Pointer: return Ptr.AttrList;
case Reference: return Ref.AttrList;
case Array: return 0;
case Function: return 0;
}
}
/// getPointer - Return a DeclaratorChunk for a pointer.
///
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,

Просмотреть файл

@ -301,7 +301,7 @@ private:
ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
Scope *S);
// Decl attributes - this routine is the top level dispatcher.
void ProcessDeclAttributes(Decl *D, Declarator &PD);
void ProcessDeclAttributes(Decl *D, const Declarator &PD);
void ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList);
void ProcessDeclAttribute(Decl *D, const AttributeList &Attr);

Просмотреть файл

@ -16,9 +16,12 @@
#include "clang/Basic/TargetInfo.h"
using namespace clang;
//===----------------------------------------------------------------------===//
// Helper functions
//===----------------------------------------------------------------------===//
static const FunctionTypeProto *getFunctionProto(Decl *d) {
QualType Ty;
if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
Ty = decl->getType();
else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
@ -54,27 +57,44 @@ static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
ClsName == &Ctx.Idents.get("NSMutableString");
}
void Sema::ProcessDeclAttributes(Decl *D, Declarator &PD) {
const AttributeList *DeclSpecAttrs = PD.getDeclSpec().getAttributes();
const AttributeList *DeclaratorAttrs = PD.getAttributes();
if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return;
//===----------------------------------------------------------------------===//
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
ProcessDeclAttributeList(D, DeclSpecAttrs);
/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
/// it, apply them to D. This is a bit tricky because PD can have attributes
/// specified in many different places, and we need to find and apply them all.
void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
// Apply decl attributes from the DeclSpec if present.
if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
ProcessDeclAttributeList(D, Attrs);
// Walk the declarator structure, applying decl attributes that were in a type
// position to the decl itself. This handles cases like:
// int *__attr__(x)** D;
// when X is a decl attribute.
for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
ProcessDeclAttributeList(D, Attrs);
// If there are any type attributes that were in the declarator, apply them to
// its top level type.
if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType DT = VD->getType();
ProcessTypeAttributes(DT, DeclaratorAttrs);
VD->setType(DT);
} else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
QualType DT = TD->getUnderlyingType();
ProcessTypeAttributes(DT, DeclaratorAttrs);
TD->setUnderlyingType(DT);
// Finally, apply any attributes on the decl itself.
if (const AttributeList *Attrs = PD.getAttributes()) {
ProcessDeclAttributeList(D, Attrs);
// If there are any type attributes that were in the declarator, apply them to
// its top-level type.
// FIXME: we shouldn't allow type attributes here. :(
if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType DT = VD->getType();
ProcessTypeAttributes(DT, Attrs);
VD->setType(DT);
} else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
QualType DT = TD->getUnderlyingType();
ProcessTypeAttributes(DT, Attrs);
TD->setUnderlyingType(DT);
}
// FIXME: field decl?
}
ProcessDeclAttributeList(D, DeclaratorAttrs);
}
/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
@ -126,6 +146,10 @@ void Sema::ProcessDeclAttribute(Decl *D, const AttributeList &Attr) {
}
}
//===----------------------------------------------------------------------===//
// Attribute Implementations
//===----------------------------------------------------------------------===//
void Sema::HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr) {
TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
if (tDecl == 0) {

Просмотреть файл

@ -13,3 +13,5 @@ typedef int invalid_2 __attribute((mode())); // expected-error{{attribute requir
typedef int invalid_3 __attribute((mode(II))); // expected-error{{unknown machine mode}}
typedef struct {int i,j,k;} invalid_4 __attribute((mode(SI))); // expected-error{{mode attribute only supported for integer and floating-point types}}
typedef float invalid_5 __attribute((mode(SI))); // expected-error{{type of machine mode does not match type of base type}}
int **__attribute((mode(QI)))* i32; // expected-error{{mode attribute}}