[cfe-commits] r146616 - in /cfe/trunk: include/clang-c/Index.h tools/c-index-test/c-index-test.c tools/libclang/IndexingContext.cpp tools/libclang/IndexingContext.h

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Dec 14 16:05:00 PST 2011


Author: akirtzidis
Date: Wed Dec 14 18:05:00 2011
New Revision: 146616

URL: http://llvm.org/viewvc/llvm-project?rev=146616&view=rev
Log:
[libclang] Indexing API: provide an attribute list inside CXIdxEntityInfo
so that we can access the attributes of an entity for a reference.

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/IndexingContext.cpp
    cfe/trunk/tools/libclang/IndexingContext.h

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=146616&r1=146615&r2=146616&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Wed Dec 14 18:05:00 2011
@@ -4171,19 +4171,6 @@
   CXIdxEntity_TemplateSpecialization = 3
 } CXIdxEntityCXXTemplateKind;
 
-typedef struct {
-  CXIdxEntityKind kind;
-  CXIdxEntityCXXTemplateKind templateKind;
-  CXIdxEntityLanguage lang;
-  const char *name;
-  const char *USR;
-  CXCursor cursor;
-} CXIdxEntityInfo;
-
-typedef struct {
-  CXCursor cursor;
-} CXIdxContainerInfo;
-
 typedef enum {
   CXIdxAttr_Unexposed     = 0,
   CXIdxAttr_IBAction      = 1,
@@ -4198,6 +4185,21 @@
 } CXIdxAttrInfo;
 
 typedef struct {
+  CXIdxEntityKind kind;
+  CXIdxEntityCXXTemplateKind templateKind;
+  CXIdxEntityLanguage lang;
+  const char *name;
+  const char *USR;
+  CXCursor cursor;
+  const CXIdxAttrInfo *const *attributes;
+  unsigned numAttributes;
+} CXIdxEntityInfo;
+
+typedef struct {
+  CXCursor cursor;
+} CXIdxContainerInfo;
+
+typedef struct {
   const CXIdxAttrInfo *attrInfo;
   const CXIdxEntityInfo *objcClass;
   CXCursor classCursor;

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=146616&r1=146615&r2=146616&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Wed Dec 14 18:05:00 2011
@@ -1684,6 +1684,7 @@
                             const CXIdxEntityInfo *info) {
   const char *name;
   IndexData *index_data;
+  unsigned i;
   index_data = (IndexData *)client_data;
   printCheck(index_data);
 
@@ -1701,6 +1702,12 @@
   printf(" | name: %s", name);
   printf(" | USR: %s", info->USR);
   printf(" | lang: %s", getEntityLanguageString(info->lang));
+
+  for (i = 0; i != info->numAttributes; ++i) {
+    const CXIdxAttrInfo *Attr = info->attributes[i];
+    printf("     <attribute>: ");
+    PrintCursor(Attr->cursor);
+  }
 }
 
 static void printBaseClassInfo(CXClientData client_data,

Modified: cfe/trunk/tools/libclang/IndexingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext.cpp?rev=146616&r1=146615&r2=146616&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexingContext.cpp (original)
+++ cfe/trunk/tools/libclang/IndexingContext.cpp Wed Dec 14 18:05:00 2011
@@ -22,7 +22,7 @@
 IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
                                     const ObjCProtocolList &ProtList,
                                     IndexingContext &IdxCtx,
-                                    StrAdapter &SA) {
+                                    ScratchAlloc &SA) {
   ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
   for (ObjCInterfaceDecl::protocol_iterator
          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
@@ -46,9 +46,27 @@
     Prots.push_back(&ProtInfos[i]);
 }
 
-IndexingContext::AttrListInfo::AttrListInfo(const Decl *D,
-                                            IndexingContext &IdxCtx,
-                                            StrAdapter &SA) {
+
+IBOutletCollectionInfo::IBOutletCollectionInfo(
+                                          const IBOutletCollectionInfo &other)
+  : AttrInfo(CXIdxAttr_IBOutletCollection, other.cursor, other.loc, A) {
+
+  IBCollInfo.attrInfo = this;
+  IBCollInfo.classCursor = other.IBCollInfo.classCursor;
+  IBCollInfo.classLoc = other.IBCollInfo.classLoc;
+  if (other.IBCollInfo.objcClass) {
+    ClassInfo = other.ClassInfo;
+    IBCollInfo.objcClass = &ClassInfo;
+  } else
+    IBCollInfo.objcClass = 0;
+}
+
+AttrListInfo::AttrListInfo(const Decl *D,
+                           IndexingContext &IdxCtx,
+                           ScratchAlloc &SA) : ref_cnt(0) {
+  if (!D->hasAttrs())
+    return;
+
   for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
          AttrI != AttrE; ++AttrI) {
     const Attr *A = *AttrI;
@@ -95,9 +113,24 @@
     CXAttrs.push_back(&Attrs[i]);
 }
 
+AttrListInfo::AttrListInfo(const AttrListInfo &other) {
+  assert(other.ref_cnt == 0 &&
+         "Should not copy an AttrListInfo that is ref-counted");
+  ref_cnt = 0;
+
+  Attrs = other.Attrs;
+  IBCollAttrs = other.IBCollAttrs;
+
+  for (unsigned i = 0, e = IBCollAttrs.size(); i != e; ++i)
+    CXAttrs.push_back(&IBCollAttrs[i]);
+
+  for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
+    CXAttrs.push_back(&Attrs[i]);
+}
+
 IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
                                    IndexingContext &IdxCtx,
-                                   IndexingContext::StrAdapter &SA) {
+                                   ScratchAlloc &SA) {
   for (CXXRecordDecl::base_class_const_iterator
          I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
     const CXXBaseSpecifier &Base = *I;
@@ -155,7 +188,7 @@
   return Loc;
 }
 
-const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
+const char *ScratchAlloc::toCStr(StringRef Str) {
   if (Str.empty())
     return "";
   if (Str.data()[Str.size()] == '\0')
@@ -163,7 +196,7 @@
   return copyCStr(Str);
 }
 
-const char *IndexingContext::StrAdapter::copyCStr(StringRef Str) {
+const char *ScratchAlloc::copyCStr(StringRef Str) {
   char *buf = IdxCtx.StrScratch.Allocate<char>(Str.size() + 1);
   std::uninitialized_copy(Str.begin(), Str.end(), buf);
   buf[Str.size()] = '\0';
@@ -195,7 +228,7 @@
   if (!CB.ppIncludedFile)
     return;
 
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
   CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
                                  SA.toCStr(filename),
                                  (CXFile)File,
@@ -226,7 +259,7 @@
   if (D->isImplicit() && shouldIgnoreIfImplicit(D))
     return false;
 
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
   getEntityInfo(D, DInfo.EntInfo, SA);
   if (!DInfo.EntInfo.USR || Loc.isInvalid())
     return false;
@@ -320,7 +353,7 @@
 }
 
 bool IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
 
   CXIdxBaseClassInfo BaseClass;
   EntityInfo BaseEntity;
@@ -366,7 +399,7 @@
 }
 
 bool IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
   ObjCProtocolListInfo ProtListInfo(D->getReferencedProtocols(), *this, SA);
   
   ObjCProtocolDeclInfo ProtInfo(D);
@@ -378,7 +411,7 @@
 bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
   EntityInfo ClassEntity;
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
   const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
   SourceLocation ClassLoc = D->getLocation();
   SourceLocation CategoryLoc = D->IsClassExtension() ? ClassLoc
@@ -410,7 +443,7 @@
   const ObjCCategoryDecl *CatD = D->getCategoryDecl();
   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
   EntityInfo ClassEntity;
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
   const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();
   SourceLocation ClassLoc = D->getLocation();
   SourceLocation CategoryLoc = D->getCategoryNameLoc();
@@ -519,7 +552,7 @@
       return false; // already occurred.
   }
 
-  StrAdapter SA(*this);
+  ScratchAlloc SA(*this);
   EntityInfo RefEntity, ParentEntity;
   getEntityInfo(D, RefEntity, SA);
   if (!RefEntity.USR)
@@ -586,7 +619,7 @@
 bool IndexingContext::handleCXXRecordDecl(const CXXRecordDecl *RD,
                                           const NamedDecl *OrigD) {
   if (RD->isThisDeclarationADefinition()) {
-    StrAdapter SA(*this);
+    ScratchAlloc SA(*this);
     CXXClassDeclInfo CXXDInfo(/*isRedeclaration=*/!OrigD->isCanonicalDecl(),
                            /*isDefinition=*/RD->isThisDeclarationADefinition());
     CXXBasesListInfo BaseList(RD, *this, SA);
@@ -731,7 +764,7 @@
 
 void IndexingContext::getEntityInfo(const NamedDecl *D,
                                     EntityInfo &EntityInfo,
-                                    StrAdapter &SA) {
+                                    ScratchAlloc &SA) {
   if (!D)
     return;
 
@@ -743,6 +776,14 @@
   EntityInfo.templateKind = CXIdxEntity_NonTemplate;
   EntityInfo.lang = CXIdxEntityLang_C;
 
+  if (D->hasAttrs()) {
+    AttrListInfo *attrs = SA.allocate<AttrListInfo>();
+    new (attrs) AttrListInfo(D, *this, SA);
+    EntityInfo.AttrList = attrs;
+    EntityInfo.attributes = attrs->getAttrs();
+    EntityInfo.numAttributes = attrs->getNumAttrs();
+  }
+
   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
     switch (TD->getTagKind()) {
     case TTK_Struct:

Modified: cfe/trunk/tools/libclang/IndexingContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexingContext.h?rev=146616&r1=146615&r2=146616&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/IndexingContext.h (original)
+++ cfe/trunk/tools/libclang/IndexingContext.h Wed Dec 14 18:05:00 2011
@@ -24,13 +24,18 @@
 
 namespace cxindex {
   class IndexingContext;
+  class ScratchAlloc;
+  class AttrListInfo;
 
 struct EntityInfo : public CXIdxEntityInfo {
   const NamedDecl *Dcl;
   IndexingContext *IndexCtx;
+  llvm::IntrusiveRefCntPtr<AttrListInfo> AttrList;
 
   EntityInfo() {
     name = USR = 0;
+    attributes = 0;
+    numAttributes = 0;
   }
 };
 
@@ -195,14 +200,49 @@
   IBOutletCollectionInfo(CXCursor C, CXIdxLoc Loc, const Attr *A) :
     AttrInfo(CXIdxAttr_IBOutletCollection, C, Loc, A) {
     assert(C.kind == CXCursor_IBOutletCollectionAttr);
+    IBCollInfo.objcClass = 0;
   }
 
+  IBOutletCollectionInfo(const IBOutletCollectionInfo &other);
+
   static bool classof(const AttrInfo *A) {
     return A->kind == CXIdxAttr_IBOutletCollection;
   }
   static bool classof(const IBOutletCollectionInfo *D) { return true; }
 };
 
+class AttrListInfo {
+  SmallVector<AttrInfo, 2> Attrs;
+  SmallVector<IBOutletCollectionInfo, 2> IBCollAttrs;
+  SmallVector<CXIdxAttrInfo *, 2> CXAttrs;
+  unsigned ref_cnt;
+
+public:
+  AttrListInfo(const Decl *D,
+               IndexingContext &IdxCtx,
+               ScratchAlloc &SA);
+  AttrListInfo(const AttrListInfo &other);
+
+  const CXIdxAttrInfo *const *getAttrs() const {
+    if (CXAttrs.empty())
+      return 0;
+    return CXAttrs.data();
+  }
+  unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); }
+
+  /// \brief Retain/Release only useful when we allocate a AttrListInfo from the
+  /// BumpPtrAllocator, and not from the stack; so that we keep a pointer
+  // in the EntityInfo
+  void Retain() { ++ref_cnt; }
+  void Release() {
+    assert (ref_cnt > 0 && "Reference count is already zero.");
+    if (--ref_cnt == 0) {
+      // Memory is allocated from a BumpPtrAllocator, no need to delete it.
+      this->~AttrListInfo();
+    }
+  }
+};
+
 struct RefFileOccurence {
   const FileEntry *File;
   const Decl *Dcl;
@@ -233,24 +273,7 @@
   
   llvm::BumpPtrAllocator StrScratch;
   unsigned StrAdapterCount;
-
-  class StrAdapter {
-    IndexingContext &IdxCtx;
-
-  public:
-    StrAdapter(IndexingContext &indexCtx) : IdxCtx(indexCtx) {
-      ++IdxCtx.StrAdapterCount;
-    }
-
-    ~StrAdapter() {
-      --IdxCtx.StrAdapterCount;
-      if (IdxCtx.StrAdapterCount == 0)
-        IdxCtx.StrScratch.Reset();
-    }
-
-    const char *toCStr(StringRef Str);
-    const char *copyCStr(StringRef Str);
-  };
+  friend class ScratchAlloc;
 
   struct ObjCProtocolListInfo {
     SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
@@ -265,22 +288,7 @@
 
     ObjCProtocolListInfo(const ObjCProtocolList &ProtList,
                          IndexingContext &IdxCtx,
-                         IndexingContext::StrAdapter &SA);
-  };
-
-  struct AttrListInfo {
-    SmallVector<AttrInfo, 2> Attrs;
-    SmallVector<IBOutletCollectionInfo, 2> IBCollAttrs;
-    SmallVector<CXIdxAttrInfo *, 2> CXAttrs;
-
-    const CXIdxAttrInfo *const *getAttrs() const {
-      return CXAttrs.data();
-    }
-    unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); }
-
-    AttrListInfo(const Decl *D,
-                 IndexingContext &IdxCtx,
-                 IndexingContext::StrAdapter &SA);
+                         ScratchAlloc &SA);
   };
 
   struct CXXBasesListInfo {
@@ -294,12 +302,14 @@
     unsigned getNumBases() const { return (unsigned)CXBases.size(); }
 
     CXXBasesListInfo(const CXXRecordDecl *D,
-                     IndexingContext &IdxCtx, IndexingContext::StrAdapter &SA);
+                     IndexingContext &IdxCtx, ScratchAlloc &SA);
 
   private:
     SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const;
   };
 
+  friend class AttrListInfo;
+
 public:
   IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
                   unsigned indexOptions, CXTranslationUnit cxTU)
@@ -440,7 +450,7 @@
 
   void getEntityInfo(const NamedDecl *D,
                      EntityInfo &EntityInfo,
-                     StrAdapter &SA);
+                     ScratchAlloc &SA);
 
   void getContainerInfo(const DeclContext *DC, ContainerInfo &ContInfo);
 
@@ -453,6 +463,29 @@
   static bool shouldIgnoreIfImplicit(const NamedDecl *D);
 };
 
+class ScratchAlloc {
+  IndexingContext &IdxCtx;
+
+public:
+  explicit ScratchAlloc(IndexingContext &indexCtx) : IdxCtx(indexCtx) {
+    ++IdxCtx.StrAdapterCount;
+  }
+
+  ~ScratchAlloc() {
+    --IdxCtx.StrAdapterCount;
+    if (IdxCtx.StrAdapterCount == 0)
+      IdxCtx.StrScratch.Reset();
+  }
+
+  const char *toCStr(StringRef Str);
+  const char *copyCStr(StringRef Str);
+
+  template <typename T>
+  T *allocate() {
+    return IdxCtx.StrScratch.Allocate<T>();
+  }
+};
+
 }} // end clang::cxindex
 
 namespace llvm {





More information about the cfe-commits mailing list