From: Chris Lattner Date: Wed, 20 Feb 2008 23:14:47 +0000 (+0000) Subject: add a method to AttributeList that converts an identifier to an enum. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2335191341a58fa3f8abea3c9b391c5bb03d67b3;p=clang add a method to AttributeList that converts an identifier to an enum. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47412 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/AttributeList.cpp b/Parse/AttributeList.cpp index 82d07f0ff9..faa50eb32d 100644 --- a/Parse/AttributeList.cpp +++ b/Parse/AttributeList.cpp @@ -24,3 +24,48 @@ AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc, for (unsigned i = 0; i != numargs; ++i) Args[i] = elist[i]; } + +AttributeList::~AttributeList() { + if (Args) { + // FIXME: before we delete the vector, we need to make sure the Expr's + // have been deleted. Since Action::ExprTy is "void", we are dependent + // on the actions module for actually freeing the memory. The specific + // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType, + // ParseField, ParseTag. Once these routines have freed the expression, + // they should zero out the Args slot (to indicate the memory has been + // freed). If any element of the vector is non-null, we should assert. + delete [] Args; + } + delete Next; +} + +AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { + const char *Str = Name->getName(); + unsigned Len = Name->getLength(); + + // Normalize the attribute name, __foo__ becomes foo. + if (Len > 4 && Str[0] == '_' && Str[1] == '_' && + Str[Len - 2] == '_' && Str[Len - 1] == '_') { + Str += 2; + Len -= 4; + } + + switch (Len) { + case 6: + if (!memcmp(Str, "packed", 6)) return AT_packed; + break; + case 7: + if (!memcmp(Str, "aligned", 7)) return AT_aligned; + break; + case 11: + if (!memcmp(Str, "vector_size", 11)) return AT_vector_size; + break; + case 13: + if (!memcmp(Str, "address_space", 13)) return AT_address_space; + break; + case 15: + if (!memcmp(Str, "ocu_vector_type", 15)) return AT_ocu_vector_type; + break; + } + return UnknownAttribute; +} diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 231a214f49..9e25579378 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -18,7 +18,7 @@ #include namespace clang { - + /// AttributeList - Represents GCC's __attribute__ declaration. There are /// 4 forms of this construct...they are: /// @@ -39,24 +39,24 @@ public: AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc, IdentifierInfo *ParmName, SourceLocation ParmLoc, Action::ExprTy **args, unsigned numargs, AttributeList *Next); - ~AttributeList() { - if (Args) { - // FIXME: before we delete the vector, we need to make sure the Expr's - // have been deleted. Since Action::ExprTy is "void", we are dependent - // on the actions module for actually freeing the memory. The specific - // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType, - // ParseField, ParseTag. Once these routines have freed the expression, - // they should zero out the Args slot (to indicate the memory has been - // freed). If any element of the vector is non-null, we should assert. - delete [] Args; - } - delete Next; - } + ~AttributeList(); + + enum Kind { + UnknownAttribute, + AT_vector_size, + AT_ocu_vector_type, + AT_address_space, + AT_aligned, + AT_packed + }; IdentifierInfo *getAttributeName() const { return AttrName; } SourceLocation getAttributeLoc() const { return AttrLoc; } IdentifierInfo *getParameterName() const { return ParmName; } + Kind getKind() const { return getKind(getAttributeName()); } + static Kind getKind(const IdentifierInfo *Name); + AttributeList *getNext() const { return Next; } void setNext(AttributeList *N) { Next = N; }