blob: 45fd06f92e2fc4b14b22b6d044f71ce8027d374e [file] [log] [blame]
Chris Lattnercf3056d2003-10-13 03:32:08 +00001//===-- Annotation.cpp - Implement the Annotation Classes -----------------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner8dc89a32001-08-23 17:07:56 +00009//
10// This file implements the AnnotationManager class.
11//
12//===----------------------------------------------------------------------===//
13
14#include <map>
Chris Lattnercb09cc22003-01-14 21:29:58 +000015#include "Support/Annotation.h"
Chris Lattner2cdd21c2003-12-14 21:35:53 +000016using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000017
Chris Lattner1cd4c722004-02-26 07:24:18 +000018Annotation::~Annotation() {} // Designed to be subclassed
19
20Annotable::~Annotable() { // Virtual because it's designed to be subclassed...
21 Annotation *A = AnnotationList;
22 while (A) {
23 Annotation *Next = A->getNext();
24 delete A;
25 A = Next;
26 }
27}
28
29
Chris Lattner01e770a2003-05-22 21:59:35 +000030typedef std::map<const std::string, unsigned> IDMapType;
Chris Lattner8dc89a32001-08-23 17:07:56 +000031static unsigned IDCounter = 0; // Unique ID counter
32
33// Static member to ensure initialiation on demand.
34static IDMapType &getIDMap() { static IDMapType TheMap; return TheMap; }
35
36// On demand annotation creation support...
Chris Lattnerc0f483d2001-09-07 16:44:01 +000037typedef Annotation *(*AnnFactory)(AnnotationID, const Annotable *, void *);
Chris Lattner01e770a2003-05-22 21:59:35 +000038typedef std::map<unsigned, std::pair<AnnFactory,void*> > FactMapType;
Chris Lattner3fa61eb2003-01-13 00:52:43 +000039
40static FactMapType *TheFactMap = 0;
41static FactMapType &getFactMap() {
42 if (TheFactMap == 0)
43 TheFactMap = new FactMapType();
44 return *TheFactMap;
45}
46
47static void eraseFromFactMap(unsigned ID) {
48 assert(TheFactMap && "No entries found!");
49 TheFactMap->erase(ID);
50 if (TheFactMap->empty()) { // Delete when empty
51 delete TheFactMap;
52 TheFactMap = 0;
53 }
54}
Chris Lattner8dc89a32001-08-23 17:07:56 +000055
Chris Lattner01e770a2003-05-22 21:59:35 +000056AnnotationID AnnotationManager::getID(const std::string &Name) { // Name -> ID
Chris Lattner8dc89a32001-08-23 17:07:56 +000057 IDMapType::iterator I = getIDMap().find(Name);
58 if (I == getIDMap().end()) {
59 getIDMap()[Name] = IDCounter++; // Add a new element
60 return IDCounter-1;
61 }
62 return I->second;
63}
64
Chris Lattner82072d42001-09-09 21:02:38 +000065// getID - Name -> ID + registration of a factory function for demand driven
66// annotation support.
Chris Lattner01e770a2003-05-22 21:59:35 +000067AnnotationID AnnotationManager::getID(const std::string &Name, Factory Fact,
Chris Lattner60bfeb82002-07-24 20:17:22 +000068 void *Data) {
Chris Lattner82072d42001-09-09 21:02:38 +000069 AnnotationID Result(getID(Name));
70 registerAnnotationFactory(Result, Fact, Data);
71 return Result;
72}
73
74
Chris Lattner8dc89a32001-08-23 17:07:56 +000075// getName - This function is especially slow, but that's okay because it should
76// only be used for debugging.
77//
Chris Lattner01e770a2003-05-22 21:59:35 +000078const std::string &AnnotationManager::getName(AnnotationID ID) { // ID -> Name
Chris Lattner8dc89a32001-08-23 17:07:56 +000079 IDMapType &TheMap = getIDMap();
80 for (IDMapType::iterator I = TheMap.begin(); ; ++I) {
81 assert(I != TheMap.end() && "Annotation ID is unknown!");
82 if (I->second == ID.ID) return I->first;
83 }
84}
85
86
87// registerAnnotationFactory - This method is used to register a callback
88// function used to create an annotation on demand if it is needed by the
89// Annotable::findOrCreateAnnotation method.
90//
91void AnnotationManager::registerAnnotationFactory(AnnotationID ID,
Chris Lattnerda8f0042001-08-27 05:19:10 +000092 AnnFactory F,
93 void *ExtraData) {
Chris Lattner8dc89a32001-08-23 17:07:56 +000094 if (F)
Chris Lattner01e770a2003-05-22 21:59:35 +000095 getFactMap()[ID.ID] = std::make_pair(F, ExtraData);
Chris Lattner8dc89a32001-08-23 17:07:56 +000096 else
Chris Lattner3fa61eb2003-01-13 00:52:43 +000097 eraseFromFactMap(ID.ID);
Chris Lattner8dc89a32001-08-23 17:07:56 +000098}
99
100// createAnnotation - Create an annotation of the specified ID for the
101// specified object, using a register annotation creation function.
102//
103Annotation *AnnotationManager::createAnnotation(AnnotationID ID,
Chris Lattnerc0f483d2001-09-07 16:44:01 +0000104 const Annotable *Obj) {
Chris Lattner8dc89a32001-08-23 17:07:56 +0000105 FactMapType::iterator I = getFactMap().find(ID.ID);
106 if (I == getFactMap().end()) return 0;
Chris Lattnerda8f0042001-08-27 05:19:10 +0000107 return I->second.first(ID, Obj, I->second.second);
Chris Lattner8dc89a32001-08-23 17:07:56 +0000108}