diff options
author | Chris Lattner <sabre@nondot.org> | 2008-06-29 00:16:31 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-06-29 00:16:31 +0000 |
commit | 58418ffa32a0eeacfe59fab70449bbcef7c5680a (patch) | |
tree | 13cb99c43793794f7649ecaf1482ca293865647b /clang/lib/Sema | |
parent | 2727d1b221d70f742afac0fa5dbaf445b14eb56c (diff) | |
download | bcm5719-llvm-58418ffa32a0eeacfe59fab70449bbcef7c5680a.tar.gz bcm5719-llvm-58418ffa32a0eeacfe59fab70449bbcef7c5680a.zip |
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.
llvm-svn: 52876
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 64 |
2 files changed, 45 insertions, 21 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index da1747aab10..23f0cb6e5d4 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index cdb54856665..28905314ee8 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -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); - - // 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); +/// 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); + + // 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) { |