2007-07-11 21:01:13 +04:00
|
|
|
//===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 22:59:25 +03:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-07-11 21:01:13 +04:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines the AttributeList class implementation
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Parse/AttributeList.h"
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
|
|
|
|
IdentifierInfo *pName, SourceLocation pLoc,
|
2009-02-09 21:23:29 +03:00
|
|
|
Action::ExprTy **elist, unsigned numargs,
|
2007-07-11 21:01:13 +04:00
|
|
|
AttributeList *n)
|
|
|
|
: AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc),
|
|
|
|
NumArgs(numargs), Next(n) {
|
|
|
|
Args = new Action::ExprTy*[numargs];
|
|
|
|
for (unsigned i = 0; i != numargs; ++i)
|
|
|
|
Args[i] = elist[i];
|
|
|
|
}
|
2008-02-21 02:14:47 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2008-07-16 02:26:48 +04:00
|
|
|
|
2008-08-01 02:40:48 +04:00
|
|
|
// FIXME: Hand generating this is neither smart nor efficient.
|
2008-02-21 02:14:47 +03:00
|
|
|
switch (Len) {
|
2008-03-03 06:28:21 +03:00
|
|
|
case 4:
|
|
|
|
if (!memcmp(Str, "weak", 4)) return AT_weak;
|
|
|
|
if (!memcmp(Str, "pure", 4)) return AT_pure;
|
2008-05-27 07:33:27 +04:00
|
|
|
if (!memcmp(Str, "mode", 4)) return AT_mode;
|
2008-03-03 06:28:21 +03:00
|
|
|
break;
|
2008-06-08 19:45:52 +04:00
|
|
|
case 5:
|
|
|
|
if (!memcmp(Str, "alias", 5)) return AT_alias;
|
|
|
|
break;
|
2008-03-03 06:28:21 +03:00
|
|
|
case 6:
|
2008-02-21 02:14:47 +03:00
|
|
|
if (!memcmp(Str, "packed", 6)) return AT_packed;
|
2008-03-03 06:28:21 +03:00
|
|
|
if (!memcmp(Str, "malloc", 6)) return AT_malloc;
|
|
|
|
if (!memcmp(Str, "format", 6)) return AT_format;
|
|
|
|
if (!memcmp(Str, "unused", 6)) return AT_unused;
|
2008-09-18 20:44:58 +04:00
|
|
|
if (!memcmp(Str, "blocks", 6)) return AT_blocks;
|
2008-02-21 02:14:47 +03:00
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (!memcmp(Str, "aligned", 7)) return AT_aligned;
|
2009-02-12 20:28:23 +03:00
|
|
|
if (!memcmp(Str, "cleanup", 7)) return AT_cleanup;
|
2008-03-03 06:28:21 +03:00
|
|
|
if (!memcmp(Str, "nonnull", 7)) return AT_nonnull;
|
2009-02-12 20:28:23 +03:00
|
|
|
if (!memcmp(Str, "nothrow", 7)) return AT_nothrow;
|
2008-08-24 03:22:21 +04:00
|
|
|
if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc;
|
2009-02-12 20:28:23 +03:00
|
|
|
if (!memcmp(Str, "section", 7)) return AT_section;
|
2008-03-07 23:04:22 +03:00
|
|
|
if (!memcmp(Str, "stdcall", 7)) return AT_stdcall;
|
2008-02-21 02:14:47 +03:00
|
|
|
break;
|
2008-02-21 22:30:49 +03:00
|
|
|
case 8:
|
|
|
|
if (!memcmp(Str, "annotate", 8)) return AT_annotate;
|
2008-02-27 23:43:06 +03:00
|
|
|
if (!memcmp(Str, "noreturn", 8)) return AT_noreturn;
|
2008-03-03 06:28:21 +03:00
|
|
|
if (!memcmp(Str, "noinline", 8)) return AT_noinline;
|
2008-03-07 23:04:22 +03:00
|
|
|
if (!memcmp(Str, "fastcall", 8)) return AT_fastcall;
|
2008-07-16 02:38:34 +04:00
|
|
|
if (!memcmp(Str, "iboutlet", 8)) return AT_IBOutlet;
|
2008-10-05 22:05:59 +04:00
|
|
|
if (!memcmp(Str, "sentinel", 8)) return AT_sentinel;
|
2009-01-14 02:34:40 +03:00
|
|
|
if (!memcmp(Str, "NSObject", 8)) return AT_nsobject;
|
2008-03-03 06:28:21 +03:00
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
if (!memcmp(Str, "dllimport", 9)) return AT_dllimport;
|
|
|
|
if (!memcmp(Str, "dllexport", 9)) return AT_dllexport;
|
2008-02-21 22:30:49 +03:00
|
|
|
break;
|
2008-02-29 19:48:43 +03:00
|
|
|
case 10:
|
|
|
|
if (!memcmp(Str, "deprecated", 10)) return AT_deprecated;
|
2008-03-03 06:28:21 +03:00
|
|
|
if (!memcmp(Str, "visibility", 10)) return AT_visibility;
|
2008-08-01 02:40:48 +04:00
|
|
|
if (!memcmp(Str, "destructor", 10)) return AT_destructor;
|
2008-02-29 19:48:43 +03:00
|
|
|
break;
|
|
|
|
case 11:
|
2008-02-21 02:14:47 +03:00
|
|
|
if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
|
2008-08-01 02:40:48 +04:00
|
|
|
if (!memcmp(Str, "constructor", 11)) return AT_constructor;
|
2008-12-17 04:07:27 +03:00
|
|
|
if (!memcmp(Str, "unavailable", 11)) return AT_unavailable;
|
2008-02-21 02:14:47 +03:00
|
|
|
break;
|
Initial implementation of function overloading in C.
This commit adds a new attribute, "overloadable", that enables C++
function overloading in C. The attribute can only be added to function
declarations, e.g.,
int *f(int) __attribute__((overloadable));
If the "overloadable" attribute exists on a function with a given
name, *all* functions with that name (and in that scope) must have the
"overloadable" attribute. Sets of overloaded functions with the
"overloadable" attribute then follow the normal C++ rules for
overloaded functions, e.g., overloads must have different
parameter-type-lists from each other.
When calling an overloaded function in C, we follow the same
overloading rules as C++, with three extensions to the set of standard
conversions:
- A value of a given struct or union type T can be converted to the
type T. This is just the identity conversion. (In C++, this would
go through a copy constructor).
- A value of pointer type T* can be converted to a value of type U*
if T and U are compatible types. This conversion has Conversion
rank (it's considered a pointer conversion in C).
- A value of type T can be converted to a value of type U if T and U
are compatible (and are not both pointer types). This conversion
has Conversion rank (it's considered to be a new kind of
conversion unique to C, a "compatible" conversion).
Known defects (and, therefore, next steps):
1) The standard-conversion handling does not understand conversions
involving _Complex or vector extensions, so it is likely to get
these wrong. We need to add these conversions.
2) All overloadable functions with the same name will have the same
linkage name, which means we'll get a collision in the linker (if
not sooner). We'll need to mangle the names of these functions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64336 91177308-0d34-0410-b5e6-96231b3b80d8
2009-02-12 02:02:49 +03:00
|
|
|
case 12:
|
|
|
|
if (!memcmp(Str, "overloadable", 12)) return AT_overloadable;
|
|
|
|
break;
|
2008-02-21 02:14:47 +03:00
|
|
|
case 13:
|
|
|
|
if (!memcmp(Str, "address_space", 13)) return AT_address_space;
|
2008-10-28 03:17:57 +03:00
|
|
|
if (!memcmp(Str, "always_inline", 13)) return AT_always_inline;
|
2008-02-21 02:14:47 +03:00
|
|
|
break;
|
|
|
|
case 15:
|
2008-04-19 03:10:10 +04:00
|
|
|
if (!memcmp(Str, "ext_vector_type", 15)) return AT_ext_vector_type;
|
2008-02-21 02:14:47 +03:00
|
|
|
break;
|
2008-04-25 13:32:00 +04:00
|
|
|
case 17:
|
|
|
|
if (!memcmp(Str, "transparent_union", 17)) return AT_transparent_union;
|
|
|
|
break;
|
2008-03-03 06:28:21 +03:00
|
|
|
case 18:
|
|
|
|
if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
|
|
|
|
break;
|
|
|
|
}
|
2008-02-21 02:14:47 +03:00
|
|
|
return UnknownAttribute;
|
|
|
|
}
|