@@ -24,7 +24,6 @@ static bool metasComparerByJsName(Meta* meta1, Meta* meta2)
24
24
return compareJsNames (meta1->jsName , meta2->jsName );
25
25
}
26
26
27
-
28
27
void MetaFactory::validate (Type* type)
29
28
{
30
29
ValidateMetaTypeVisitor validator (*this );
@@ -38,12 +37,12 @@ void MetaFactory::validate(Meta* meta)
38
37
if (declIt == this ->_metaToDecl .end ()) {
39
38
throw MetaCreationException (meta, " Metadata not created" , true );
40
39
}
41
-
40
+
42
41
auto metaIt = this ->_cache .find (declIt->second );
43
42
assert (metaIt != this ->_cache .end ());
44
- if (! metaIt->second .second .empty () ) {
43
+ if (metaIt->second .second .get () != nullptr ) {
45
44
// printf("**** Validation failed for %s: %s ***\n\n", meta->name.c_str(), metaIt->second.second.c_str());
46
- throw MetaCreationException (meta, metaIt->second .second , false );
45
+ POLYMORPHIC_THROW ( metaIt->second .second );
47
46
}
48
47
}
49
48
@@ -68,85 +67,89 @@ string MetaFactory::getTypedefOrOwnName(const clang::TagDecl* tagDecl)
68
67
return tagDecl->getNameAsString ();
69
68
}
70
69
71
- Meta* MetaFactory::create (const clang::Decl& decl)
70
+ template <class T >
71
+ void resetMetaAndAddToMap (std::unique_ptr<Meta>& metaPtrRef, MetaToDeclMap& metaToDecl, const clang::Decl& decl) {
72
+ if (metaPtrRef.get ()) {
73
+ // The pointer has been previously allocated. Reset it's value and assert that it's already present in the map
74
+ static_cast <T&>(*metaPtrRef) = T ();
75
+ assert (metaToDecl[metaPtrRef.get ()] == &decl);
76
+ } else {
77
+ // Allocate memory and add to map
78
+ metaPtrRef.reset (new T ());
79
+ metaToDecl[metaPtrRef.get ()] = &decl;
80
+ }
81
+ }
82
+
83
+ Meta* MetaFactory::create (const clang::Decl& decl, bool resetCached /* = false*/ )
72
84
{
73
- // check for cached Meta
74
- Cache::const_iterator cachedMetaIt = _cache.find (&decl);
75
- if (cachedMetaIt != _cache.end ()) {
85
+ // Check for cached Meta
86
+ Cache::iterator cachedMetaIt = _cache.find (&decl);
87
+ if (!resetCached && cachedMetaIt != _cache.end ()) {
76
88
Meta* meta = cachedMetaIt->second .first .get ();
77
- std::string errorMessage = cachedMetaIt->second .second ;
78
- if (errorMessage.empty ()) {
79
- /* TODO: The meta object is not guaranteed to be fully initialized. If the meta object is in the creation stack
80
- * it will appear in cache, but will not be fully initialized. This may cause some inconsistent results.
81
- * */
82
- return meta;
89
+ if (auto creationException = cachedMetaIt->second .second .get ()) {
90
+ POLYMORPHIC_THROW (creationException);
83
91
}
84
- throw MetaCreationException (meta, errorMessage, false );
85
- }
86
92
87
- std::pair<Cache::iterator, bool > insertionResult = _cache.insert (std::make_pair<Cache::key_type, Cache::mapped_type>(&decl, std::make_pair<std::unique_ptr<Meta>, std::string>(nullptr , std::string ())));
93
+ /* TODO: The meta object is not guaranteed to be fully initialized. If the meta object is in the creation stack
94
+ * it will appear in cache, but will not be fully initialized. This may cause some inconsistent results.
95
+ * */
96
+
97
+ return meta;
98
+ }
88
99
89
- assert (insertionResult.second );
90
- Cache::iterator insertionIt = insertionResult.first ;
91
- std::unique_ptr<Meta>& insertedMetaPtrRef = insertionIt->second .first ;
92
- std::string& insertedErrorMessageRef = insertionIt->second .second ;
100
+ if (cachedMetaIt == _cache.end ()) {
101
+ std::pair<Cache::iterator, bool > insertionResult = _cache.insert (std::make_pair (&decl, std::make_pair (nullptr , nullptr )));
102
+ assert (insertionResult.second );
103
+ cachedMetaIt = insertionResult.first ;
104
+ }
105
+ std::unique_ptr<Meta>& insertedMetaPtrRef = cachedMetaIt->second .first ;
106
+ std::unique_ptr<CreationException>& insertedException = cachedMetaIt->second .second ;
93
107
94
108
try {
95
109
if (const clang::FunctionDecl* function = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
96
- insertedMetaPtrRef.reset (new FunctionMeta ());
97
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
110
+ resetMetaAndAddToMap<FunctionMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
98
111
populateIdentificationFields (*function, *insertedMetaPtrRef.get ());
99
112
createFromFunction (*function, insertedMetaPtrRef.get ()->as <FunctionMeta>());
100
113
} else if (const clang::RecordDecl* record = clang::dyn_cast<clang::RecordDecl>(&decl)) {
101
114
if (record->isStruct ()) {
102
- insertedMetaPtrRef.reset (new StructMeta ());
103
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
115
+ resetMetaAndAddToMap<StructMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
104
116
populateIdentificationFields (*record, *insertedMetaPtrRef.get ());
105
117
createFromStruct (*record, insertedMetaPtrRef.get ()->as <StructMeta>());
106
118
} else {
107
- insertedMetaPtrRef.reset (new UnionMeta ());
108
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
119
+ resetMetaAndAddToMap<UnionMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
109
120
populateIdentificationFields (*record, *insertedMetaPtrRef.get ());
110
121
throw MetaCreationException (insertedMetaPtrRef.get (), " The record is union." , false );
111
122
}
112
123
} else if (const clang::VarDecl* var = clang::dyn_cast<clang::VarDecl>(&decl)) {
113
- insertedMetaPtrRef.reset (new VarMeta ());
114
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
124
+ resetMetaAndAddToMap<VarMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
115
125
populateIdentificationFields (*var, *insertedMetaPtrRef.get ());
116
126
createFromVar (*var, insertedMetaPtrRef.get ()->as <VarMeta>());
117
127
} else if (const clang::EnumDecl* enumDecl = clang::dyn_cast<clang::EnumDecl>(&decl)) {
118
- insertedMetaPtrRef.reset (new EnumMeta ());
119
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
128
+ resetMetaAndAddToMap<EnumMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
120
129
populateIdentificationFields (*enumDecl, *insertedMetaPtrRef.get ());
121
130
createFromEnum (*enumDecl, insertedMetaPtrRef.get ()->as <EnumMeta>());
122
131
} else if (const clang::EnumConstantDecl* enumConstantDecl = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
123
- insertedMetaPtrRef.reset (new EnumConstantMeta ());
124
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
132
+ resetMetaAndAddToMap<EnumConstantMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
125
133
populateIdentificationFields (*enumConstantDecl, *insertedMetaPtrRef.get ());
126
134
createFromEnumConstant (*enumConstantDecl, insertedMetaPtrRef.get ()->as <EnumConstantMeta>());
127
135
} else if (const clang::ObjCInterfaceDecl* interface = clang::dyn_cast<clang::ObjCInterfaceDecl>(&decl)) {
128
- insertedMetaPtrRef.reset (new InterfaceMeta ());
129
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
136
+ resetMetaAndAddToMap<InterfaceMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
130
137
populateIdentificationFields (*interface, *insertedMetaPtrRef.get ());
131
138
createFromInterface (*interface, insertedMetaPtrRef.get ()->as <InterfaceMeta>());
132
139
} else if (const clang::ObjCProtocolDecl* protocol = clang::dyn_cast<clang::ObjCProtocolDecl>(&decl)) {
133
- insertedMetaPtrRef.reset (new ProtocolMeta ());
134
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
140
+ resetMetaAndAddToMap<ProtocolMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
135
141
populateIdentificationFields (*protocol, *insertedMetaPtrRef.get ());
136
142
createFromProtocol (*protocol, insertedMetaPtrRef.get ()->as <ProtocolMeta>());
137
143
} else if (const clang::ObjCCategoryDecl* category = clang::dyn_cast<clang::ObjCCategoryDecl>(&decl)) {
138
- insertedMetaPtrRef.reset (new CategoryMeta ());
139
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
144
+ resetMetaAndAddToMap<CategoryMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
140
145
populateIdentificationFields (*category, *insertedMetaPtrRef.get ());
141
146
createFromCategory (*category, insertedMetaPtrRef.get ()->as <CategoryMeta>());
142
147
} else if (const clang::ObjCMethodDecl* method = clang::dyn_cast<clang::ObjCMethodDecl>(&decl)) {
143
- insertedMetaPtrRef.reset (new MethodMeta ());
144
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
148
+ resetMetaAndAddToMap<MethodMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
145
149
populateIdentificationFields (*method, *insertedMetaPtrRef.get ());
146
150
createFromMethod (*method, insertedMetaPtrRef.get ()->as <MethodMeta>());
147
151
} else if (const clang::ObjCPropertyDecl* property = clang::dyn_cast<clang::ObjCPropertyDecl>(&decl)) {
148
- insertedMetaPtrRef.reset (new PropertyMeta ());
149
- _metaToDecl[insertedMetaPtrRef.get ()] = &decl;
152
+ resetMetaAndAddToMap<PropertyMeta>(insertedMetaPtrRef, this ->_metaToDecl , decl);
150
153
populateIdentificationFields (*property, *insertedMetaPtrRef.get ());
151
154
createFromProperty (*property, insertedMetaPtrRef.get ()->as <PropertyMeta>());
152
155
} else {
@@ -156,16 +159,16 @@ Meta* MetaFactory::create(const clang::Decl& decl)
156
159
return insertedMetaPtrRef.get ();
157
160
} catch (MetaCreationException& e) {
158
161
if (e.getMeta () == insertedMetaPtrRef.get ()) {
159
- insertedErrorMessageRef = e. getMessage ( );
162
+ insertedException = llvm::make_unique<MetaCreationException>(e );
160
163
throw ;
161
164
}
162
165
std::string message = CreationException::constructMessage (" Can't create meta dependency." , e.getDetailedMessage ());
163
- insertedErrorMessageRef = message;
164
- throw MetaCreationException (insertedMetaPtrRef. get (), message, e. isError () );
166
+ insertedException = llvm::make_unique<MetaCreationException>(insertedMetaPtrRef. get (), message, e. isError ()) ;
167
+ POLYMORPHIC_THROW (insertedException );
165
168
} catch (TypeCreationException& e) {
166
169
std::string message = CreationException::constructMessage (" Can't create type dependency." , e.getDetailedMessage ());
167
- insertedErrorMessageRef = message;
168
- throw MetaCreationException (insertedMetaPtrRef. get (), message, e. isError () );
170
+ insertedException = llvm::make_unique<MetaCreationException>(insertedMetaPtrRef. get (), message, e. isError ()) ;
171
+ POLYMORPHIC_THROW (insertedException );
169
172
}
170
173
}
171
174
0 commit comments