LLVM API Documentation
00001 //===-- Annotation.cpp - Implement the Annotation Classes -----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the AnnotationManager class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Support/Annotation.h" 00015 #include "llvm/Support/ManagedStatic.h" 00016 #include <map> 00017 #include <cstring> 00018 using namespace llvm; 00019 00020 Annotation::~Annotation() {} // Designed to be subclassed 00021 00022 Annotable::~Annotable() { // Virtual because it's designed to be subclassed... 00023 Annotation *A = AnnotationList; 00024 while (A) { 00025 Annotation *Next = A->getNext(); 00026 delete A; 00027 A = Next; 00028 } 00029 } 00030 00031 namespace { 00032 class StrCmp { 00033 public: 00034 bool operator()(const char *a, const char *b) const { 00035 return strcmp(a, b) < 0; 00036 } 00037 }; 00038 } 00039 00040 typedef std::map<const char*, unsigned, StrCmp> IDMapType; 00041 static unsigned IDCounter = 0; // Unique ID counter 00042 00043 // Static member to ensure initialiation on demand. 00044 static ManagedStatic<IDMapType> IDMap; 00045 00046 // On demand annotation creation support... 00047 typedef Annotation *(*AnnFactory)(AnnotationID, const Annotable *, void *); 00048 typedef std::map<unsigned, std::pair<AnnFactory,void*> > FactMapType; 00049 00050 static FactMapType *TheFactMap = 0; 00051 static FactMapType &getFactMap() { 00052 if (TheFactMap == 0) 00053 TheFactMap = new FactMapType(); 00054 return *TheFactMap; 00055 } 00056 00057 static void eraseFromFactMap(unsigned ID) { 00058 assert(TheFactMap && "No entries found!"); 00059 TheFactMap->erase(ID); 00060 if (TheFactMap->empty()) { // Delete when empty 00061 delete TheFactMap; 00062 TheFactMap = 0; 00063 } 00064 } 00065 00066 AnnotationID AnnotationManager::getID(const char *Name) { // Name -> ID 00067 IDMapType::iterator I = IDMap->find(Name); 00068 if (I == IDMap->end()) { 00069 (*IDMap)[Name] = IDCounter++; // Add a new element 00070 return AnnotationID(IDCounter-1); 00071 } 00072 return AnnotationID(I->second); 00073 } 00074 00075 // getID - Name -> ID + registration of a factory function for demand driven 00076 // annotation support. 00077 AnnotationID AnnotationManager::getID(const char *Name, Factory Fact, 00078 void *Data) { 00079 AnnotationID Result(getID(Name)); 00080 registerAnnotationFactory(Result, Fact, Data); 00081 return Result; 00082 } 00083 00084 // getName - This function is especially slow, but that's okay because it should 00085 // only be used for debugging. 00086 // 00087 const char *AnnotationManager::getName(AnnotationID ID) { // ID -> Name 00088 IDMapType &TheMap = *IDMap; 00089 for (IDMapType::iterator I = TheMap.begin(); ; ++I) { 00090 assert(I != TheMap.end() && "Annotation ID is unknown!"); 00091 if (I->second == ID.ID) return I->first; 00092 } 00093 } 00094 00095 // registerAnnotationFactory - This method is used to register a callback 00096 // function used to create an annotation on demand if it is needed by the 00097 // Annotable::findOrCreateAnnotation method. 00098 // 00099 void AnnotationManager::registerAnnotationFactory(AnnotationID ID, AnnFactory F, 00100 void *ExtraData) { 00101 if (F) 00102 getFactMap()[ID.ID] = std::make_pair(F, ExtraData); 00103 else 00104 eraseFromFactMap(ID.ID); 00105 } 00106 00107 // createAnnotation - Create an annotation of the specified ID for the 00108 // specified object, using a register annotation creation function. 00109 // 00110 Annotation *AnnotationManager::createAnnotation(AnnotationID ID, 00111 const Annotable *Obj) { 00112 FactMapType::iterator I = getFactMap().find(ID.ID); 00113 if (I == getFactMap().end()) return 0; 00114 return I->second.first(ID, Obj, I->second.second); 00115 }