зеркало из https://github.com/microsoft/clang.git
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:
Родитель
3ff30c8e6e
Коммит
e5c5ee1cff
|
@ -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}}
|
||||
|
|
Загрузка…
Ссылка в новой задаче