1 //===-- Annotation.cpp - Implement the Annotation Classes -----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the AnnotationManager class.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Support/Annotation.h"
15 #include "llvm/Support/ManagedStatic.h"
20 Annotation::~Annotation() {} // Designed to be subclassed
22 Annotable::~Annotable() { // Virtual because it's designed to be subclassed...
23 Annotation
*A
= AnnotationList
;
25 Annotation
*Next
= A
->getNext();
34 bool operator()(const char *a
, const char *b
) const {
35 return strcmp(a
, b
) < 0;
40 typedef std::map
<const char*, unsigned, StrCmp
> IDMapType
;
41 static unsigned IDCounter
= 0; // Unique ID counter
43 // Static member to ensure initialiation on demand.
44 static ManagedStatic
<IDMapType
> IDMap
;
46 // On demand annotation creation support...
47 typedef Annotation
*(*AnnFactory
)(AnnotationID
, const Annotable
*, void *);
48 typedef std::map
<unsigned, std::pair
<AnnFactory
,void*> > FactMapType
;
50 static FactMapType
*TheFactMap
= 0;
51 static FactMapType
&getFactMap() {
53 TheFactMap
= new FactMapType();
57 static void eraseFromFactMap(unsigned ID
) {
58 assert(TheFactMap
&& "No entries found!");
59 TheFactMap
->erase(ID
);
60 if (TheFactMap
->empty()) { // Delete when empty
66 AnnotationID
AnnotationManager::getID(const char *Name
) { // Name -> ID
67 IDMapType::iterator I
= IDMap
->find(Name
);
68 if (I
== IDMap
->end()) {
69 (*IDMap
)[Name
] = IDCounter
++; // Add a new element
70 return AnnotationID(IDCounter
-1);
72 return AnnotationID(I
->second
);
75 // getID - Name -> ID + registration of a factory function for demand driven
76 // annotation support.
77 AnnotationID
AnnotationManager::getID(const char *Name
, Factory Fact
,
79 AnnotationID
Result(getID(Name
));
80 registerAnnotationFactory(Result
, Fact
, Data
);
84 // getName - This function is especially slow, but that's okay because it should
85 // only be used for debugging.
87 const char *AnnotationManager::getName(AnnotationID ID
) { // ID -> Name
88 IDMapType
&TheMap
= *IDMap
;
89 for (IDMapType::iterator I
= TheMap
.begin(); ; ++I
) {
90 assert(I
!= TheMap
.end() && "Annotation ID is unknown!");
91 if (I
->second
== ID
.ID
) return I
->first
;
95 // registerAnnotationFactory - This method is used to register a callback
96 // function used to create an annotation on demand if it is needed by the
97 // Annotable::findOrCreateAnnotation method.
99 void AnnotationManager::registerAnnotationFactory(AnnotationID ID
, AnnFactory F
,
102 getFactMap()[ID
.ID
] = std::make_pair(F
, ExtraData
);
104 eraseFromFactMap(ID
.ID
);
107 // createAnnotation - Create an annotation of the specified ID for the
108 // specified object, using a register annotation creation function.
110 Annotation
*AnnotationManager::createAnnotation(AnnotationID ID
,
111 const Annotable
*Obj
) {
112 FactMapType::iterator I
= getFactMap().find(ID
.ID
);
113 if (I
== getFactMap().end()) return 0;
114 return I
->second
.first(ID
, Obj
, I
->second
.second
);