[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