[cfe-commits] r52876 - in /cfe/trunk: include/clang/Parse/DeclSpec.h lib/Sema/Sema.h lib/Sema/SemaDeclAttr.cpp test/Sema/attr-mode.c

Chris Lattner sabre at nondot.org
Sat Jun 28 17:16:32 PDT 2008


Author: lattner
Date: Sat Jun 28 19:16:31 2008
New Revision: 52876

URL: http://llvm.org/viewvc/llvm-project?rev=52876&view=rev
Log:
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.


Modified:
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/attr-mode.c

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=52876&r1=52875&r2=52876&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Sat Jun 28 19:16:31 2008
@@ -457,6 +457,19 @@
   };
   
   
+  /// 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,

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=52876&r1=52875&r2=52876&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Jun 28 19:16:31 2008
@@ -301,7 +301,7 @@
   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);
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=52876&r1=52875&r2=52876&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sat Jun 28 19:16:31 2008
@@ -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 @@
          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;
-
-  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);
+//===----------------------------------------------------------------------===//
+// Top Level Sema Entry Points
+//===----------------------------------------------------------------------===//
+
+/// 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 @@
   }
 }
 
+//===----------------------------------------------------------------------===//
+// Attribute Implementations
+//===----------------------------------------------------------------------===//
+
 void Sema::HandleExtVectorTypeAttribute(Decl *d, const AttributeList &Attr) {
   TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
   if (tDecl == 0) {

Modified: cfe/trunk/test/Sema/attr-mode.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-mode.c?rev=52876&r1=52875&r2=52876&view=diff

==============================================================================
--- cfe/trunk/test/Sema/attr-mode.c (original)
+++ cfe/trunk/test/Sema/attr-mode.c Sat Jun 28 19:16:31 2008
@@ -13,3 +13,5 @@
 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}}





More information about the cfe-commits mailing list