[cfe-commits] r39643 - in /cfe/cfe/trunk: Lex/Preprocessor.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/AttributeList.h include/clang/Parse/DeclSpec.h

Steve Naroff snaroff at apple.com
Wed Jul 11 09:46:34 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:46:34 2007
New Revision: 39643

URL: http://llvm.org/viewvc/llvm-project?rev=39643&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Implement semantic analysis for vector_size attribute!
We now produce the following diagnostics...

[administrators-powerbook59:~/llvm/tools/clang] admin% ../../Debug/bin/clang vector.c
vector.c:2:29: error: attribute requires precisely 1 argument
typedef int __attribute__(( vector_size )) tVecp;
                            ^
vector.c:7:32: error: attribute requires precisely 1 argument
extern int foo __attribute__(( vector_size ));
                               ^
vector.c:8:34: error: attribute requires precisely 1 argument
extern float bar __attribute__(( vector_size(16,18) ));
                                 ^
vector.c:11:34: error: vector_size requires integer constant (attribute ignored)
extern char foo2 __attribute__(( vector_size(16.2) ));
                                 ^           ~~~~
vector.c:21:47: error: invalid vector type 'struct s'
struct s { int a; } structVar __attribute__(( vector_size(16) ));

Modified:
    cfe/cfe/trunk/Lex/Preprocessor.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/AttributeList.h
    cfe/cfe/trunk/include/clang/Parse/DeclSpec.h

Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=39643&r1=39642&r2=39643&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:46:34 2007
@@ -969,7 +969,10 @@
   Identifier.setKind(II.getTokenID());
     
   // If this is an extension token, diagnose its use.
-  if (II.isExtensionToken()) Diag(Identifier, diag::ext_token_used);
+  // FIXME: tried (unsuccesfully) to shut this up when compiling with gnu99
+  // For now, I'm just commenting it out (while I work on attributes).
+  //if (II.isExtensionToken() && Features.C99) 
+  //  Diag(Identifier, diag::ext_token_used);
 }
 
 /// HandleEndOfFile - This callback is invoked when the lexer hits the end of

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

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:46:34 2007
@@ -138,6 +138,20 @@
   Decl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
   Decl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
                                  Scope *S);
+  // Decl attributes - this routine is the top level dispatcher. 
+  void HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
+                            AttributeList *declarator_postfix);
+  void HandleDeclAttribute(Decl *New, AttributeList *rawAttr);
+                                
+  // HandleVectorTypeAttribute - this attribute is only applicable to 
+  // integral and float scalars, although arrays, pointers, and function
+  // return values are allowed in conjunction with this construct. Aggregates
+  // with this attribute are invalid, even if they are of the same size as a
+  // corresponding scalar.
+  // The raw attribute should contain precisely 1 argument, the vector size 
+  // for the variable, measured in bytes. If curType and rawAttr are well
+  // formed, this routine will return a new vector type.
+  void *HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
   
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39643&r1=39642&r2=39643&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:46:34 2007
@@ -290,7 +290,10 @@
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
     TypedefDecl *NewTD = ParseTypedefDecl(S, D, LastDeclarator);
     if (!NewTD) return 0;
-    
+
+    // Handle attributes prior to checking for duplicates in MergeVarDecl
+    HandleDeclAttributes(NewTD, D.getDeclSpec().getAttributes(),
+                         D.getAttributes());
     // Merge the decl with the existing one if appropriate.
     if (PrevDecl) {
       NewTD = MergeTypeDefDecl(NewTD, PrevDecl);
@@ -395,6 +398,10 @@
       }
       NewVD = new BlockVarDecl(D.getIdentifierLoc(), II, R, SC, LastDeclarator);
     }    
+    // Handle attributes prior to checking for duplicates in MergeVarDecl
+    HandleDeclAttributes(NewVD, D.getDeclSpec().getAttributes(),
+                         D.getAttributes());
+     
     // Merge the decl with the existing one if appropriate.
     if (PrevDecl) {
       NewVD = MergeVarDecl(NewVD, PrevDecl);
@@ -403,7 +410,6 @@
     New = NewVD;
   }
   
-  
   // If this has an identifier, add it to the scope stack.
   if (II) {
     New->setNext(II->getFETokenInfo<Decl>());
@@ -904,3 +910,70 @@
   if (last)
     LastInGroupList.push_back((Decl*)last);
 }
+
+void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) {
+  if (strcmp(rawAttr->getAttributeName()->getName(), "vector_size") == 0) {
+    if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) {
+      HandleVectorTypeAttribute(vDecl->getType(), rawAttr);
+      // install the new vector type into the decl
+    } 
+    if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
+      HandleVectorTypeAttribute(tDecl->getUnderlyingType(), rawAttr);
+      // install the new vector type into the decl
+    }
+  }
+  // FIXME: add other attributes...
+}
+
+void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
+                                AttributeList *declarator_postfix) {
+  while (declspec_prefix) {
+    HandleDeclAttribute(New, declspec_prefix);
+    declspec_prefix = declspec_prefix->getNext();
+  }
+  while (declarator_postfix) {
+    HandleDeclAttribute(New, declarator_postfix);
+    declarator_postfix = declarator_postfix->getNext();
+  }
+}
+
+void *Sema::HandleVectorTypeAttribute(QualType curType, 
+                                      AttributeList *rawAttr) {
+  // check the attribute arugments
+  if (rawAttr->getNumArgs() != 1) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments,
+         std::string("1"));
+    return 0;
+  }
+  Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
+  APSInt vecSize(32);
+  if (!sizeExpr->isIntegerConstantExpr(vecSize)) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
+         sizeExpr->getSourceRange());
+    return 0;
+  }
+  // navigate to the base type - we need to provide for vector pointers, 
+  // vector arrays, and functions returning vectors.
+  Type *canonType = curType.getCanonicalType().getTypePtr();
+  
+  while (canonType->isPointerType() || canonType->isArrayType() ||
+         canonType->isFunctionType()) {
+    if (PointerType *PT = dyn_cast<PointerType>(canonType))
+      canonType = PT->getPointeeType().getTypePtr();
+    else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
+      canonType = AT->getElementType().getTypePtr();
+    else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
+      canonType = FT->getResultType().getTypePtr();
+  }
+  // the base type must be integer or float.
+  if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_invalid_vector_type,
+         curType.getCanonicalType().getAsString());
+    return 0;
+  }
+  // FIXME: check that the vector size is a multiple of the type size (and
+  // not 0). check that the vector components are a power of two. Last, and
+  // certainly not least, instantiate a vector type AST node!
+  return 0;
+}
+

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39643&r1=39642&r2=39643&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:46:34 2007
@@ -428,6 +428,14 @@
 DIAG(err_invalid_reference_qualifier_application, ERROR,
      "'%0' qualifier may not be applied to a reference")
 
+// Attributes
+DIAG(err_attribute_wrong_number_arguments, ERROR,
+     "attribute requires precisely %0 argument")
+DIAG(err_attribute_invalid_vector_type, ERROR,
+     "invalid vector type '%0'")
+DIAG(err_attribute_vector_size_not_int, ERROR,
+     "vector_size requires integer constant (attribute ignored)")
+
 // Function Parameter Semantic Analysis.
 DIAG(err_void_param_with_identifier, ERROR,
      "void argument may not have a name")

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/AttributeList.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/AttributeList.h Wed Jul 11 11:46:34 2007
@@ -56,6 +56,7 @@
   }
   
   IdentifierInfo *getAttributeName() const { return AttrName; }
+  SourceLocation getAttributeLoc() const { return AttrLoc; }
   IdentifierInfo *getParameterName() const { return ParmName; }
   
   AttributeList *getNext() const { return Next; }

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:46:34 2007
@@ -229,12 +229,11 @@
   /// int __attribute__(( may_alias, aligned(16) )) var;
   ///
   /// This declares 4 attributes using 2 lists. The following syntax is
-  /// also allowed and identical to the previous declaration.
+  /// also allowed and equivalent to the previous declaration.
   ///
   /// short __attribute__((unused)) __attribute__((deprecated)) 
   /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
   /// 
-  /// I don't believe this usage of attributes is common.
   void AddAttributes(AttributeList *alist) {
     if (!alist)
       return; // we parsed __attribute__(()) or had a syntax error
@@ -243,6 +242,8 @@
       alist->addAttributeList(AttrList); 
     AttrList = alist;
   }
+  AttributeList *getAttributes() const { return AttrList; }
+  
   /// Finish - This does final analysis of the declspec, issuing diagnostics for
   /// things like "_Imaginary" (lacking an FP type).  After calling this method,
   /// DeclSpec is guaranteed self-consistent, even if an error occurred.
@@ -543,6 +544,7 @@
     assert((AttrList == 0) && "Declarator already has an attribute list");
     AttrList = alist;
   }
+  AttributeList *getAttributes() const { return AttrList; }
 };
 
   





More information about the cfe-commits mailing list