15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- AttributeList.cpp --------------------------------------*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file defines the AttributeList class implementation 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/AttributeList.h" 15478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer#include "clang/AST/ASTContext.h" 160b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall#include "clang/AST/Expr.h" 178f823d2d3c557326d22699d66e5d367d0f0e44efChris Lattner#include "clang/Basic/IdentifierTable.h" 18d6268ffe94e5159ef41c61fe7f750c22546d3ef3Douglas Gregor#include "llvm/ADT/StringSwitch.h" 19e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith#include "llvm/ADT/SmallString.h" 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 220b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallsize_t AttributeList::allocated_size() const { 230b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall if (IsAvailability) return AttributeFactory::AvailabilityAllocSize; 240d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko else if (IsTypeTagForDatatype) 250d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return AttributeFactory::TypeTagForDatatypeAllocSize; 260b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall return (sizeof(AttributeList) + NumArgs * sizeof(Expr*)); 270b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall} 280b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 290b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallAttributeFactory::AttributeFactory() { 300b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Go ahead and configure all the inline capacity. This is just a memset. 310b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall FreeLists.resize(InlineFreeListsCapacity); 320b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall} 330b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallAttributeFactory::~AttributeFactory() {} 340b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 350b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallstatic size_t getFreeListIndexForSize(size_t size) { 360b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall assert(size >= sizeof(AttributeList)); 370b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall assert((size % sizeof(void*)) == 0); 380b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall return ((size - sizeof(AttributeList)) / sizeof(void*)); 390b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall} 400b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 410b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallvoid *AttributeFactory::allocate(size_t size) { 420b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Check for a previously reclaimed attribute. 430b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall size_t index = getFreeListIndexForSize(size); 440b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall if (index < FreeLists.size()) { 450b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall if (AttributeList *attr = FreeLists[index]) { 460b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall FreeLists[index] = attr->NextInPool; 470b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall return attr; 480b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall } 49005b235fbc8449142befa81ec30e8e4c654182c5Chris Lattner } 500b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 510b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Otherwise, allocate something new. 520b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall return Alloc.Allocate(size, llvm::AlignOf<AttributeFactory>::Alignment); 530b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall} 540b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 550b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallvoid AttributeFactory::reclaimPool(AttributeList *cur) { 560b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall assert(cur && "reclaiming empty pool!"); 570b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall do { 580b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Read this here, because we're going to overwrite NextInPool 590b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // when we toss 'cur' into the appropriate queue. 600b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall AttributeList *next = cur->NextInPool; 610b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 620b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall size_t size = cur->allocated_size(); 630b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall size_t freeListIndex = getFreeListIndexForSize(size); 640b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 650b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Expand FreeLists to the appropriate size, if required. 660b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall if (freeListIndex >= FreeLists.size()) 670b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall FreeLists.resize(freeListIndex+1); 680b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 690b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Add 'cur' to the appropriate free-list. 700b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall cur->NextInPool = FreeLists[freeListIndex]; 710b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall FreeLists[freeListIndex] = cur; 720b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 730b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall cur = next; 740b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall } while (cur); 750b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall} 760b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 770b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallvoid AttributePool::takePool(AttributeList *pool) { 780b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall assert(pool); 790b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 800b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Fast path: this pool is empty. 810b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall if (!Head) { 820b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall Head = pool; 830b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall return; 840b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall } 850b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall 860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // Reverse the pool onto the current head. This optimizes for the 870b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall // pattern of pulling a lot of pools into a single pool. 880b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall do { 890b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall AttributeList *next = pool->NextInPool; 900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall pool->NextInPool = Head; 910b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall Head = pool; 920b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall pool = next; 930b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall } while (pool); 945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 952335191341a58fa3f8abea3c9b391c5bb03d67b3Chris Lattner 960b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallAttributeList * 970b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCallAttributePool::createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, 980b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation TokLoc, int Arg) { 990b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall Expr *IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg), 1000b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall C.IntTy, TokLoc); 10193f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt return create(Name, TokLoc, 0, TokLoc, 0, TokLoc, &IArg, 1, 10293f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt AttributeList::AS_GNU); 1030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 1040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1050c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor#include "clang/Sema/AttrParsedAttrKinds.inc" 1060c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor 107e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard SmithAttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name, 10893f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt const IdentifierInfo *ScopeName, 10993f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Syntax SyntaxUsed) { 1105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef AttrName = Name->getName(); 1112335191341a58fa3f8abea3c9b391c5bb03d67b3Chris Lattner 1122335191341a58fa3f8abea3c9b391c5bb03d67b3Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1135297d71e8c85f9b04dc31c690e91c6a2f7eddb90Richard Smith if (AttrName.startswith("__") && AttrName.endswith("__") && 1145297d71e8c85f9b04dc31c690e91c6a2f7eddb90Richard Smith AttrName.size() >= 4) 1154f90d8d2b087450a84c331365017b2f53a60e09cDaniel Dunbar AttrName = AttrName.substr(2, AttrName.size() - 4); 1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 117e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith SmallString<64> Buf; 118e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (ScopeName) 11993f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf += ScopeName->getName(); 12093f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt // Ensure that in the case of C++11 attributes, we look for '::foo' if it is 12193f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt // unscoped. 12293f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt if (ScopeName || SyntaxUsed == AS_CXX11) 12393f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf += "::"; 12493f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf += AttrName; 12593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt 12693f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt return ::getAttrKind(Buf); 1272335191341a58fa3f8abea3c9b391c5bb03d67b3Chris Lattner} 128