Templates.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. // Copyright (c) 2008 Roberto Raggi <[email protected]>
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. #include "Templates.h"
  21. #include "CoreTypes.h"
  22. #include "Symbols.h"
  23. #include "Control.h"
  24. #include "Names.h"
  25. #include "Literals.h"
  26. #include "cppassert.h"
  27. #include <algorithm>
  28. using namespace CPlusPlus;
  29. CloneType::CloneType(Clone *clone)
  30. : _clone(clone)
  31. , _control(clone->control())
  32. , _subst(0)
  33. {
  34. }
  35. FullySpecifiedType CloneType::cloneType(const FullySpecifiedType &type, Subst *subst)
  36. {
  37. TypeSubstPair typeSubstPair = std::make_pair(type, subst);
  38. if (_cache.find(typeSubstPair) != _cache.end())
  39. return _cache[typeSubstPair];
  40. std::swap(_subst, subst);
  41. FullySpecifiedType ty(type);
  42. std::swap(_type, ty);
  43. accept(_type.type());
  44. std::swap(_type, ty);
  45. std::swap(_subst, subst);
  46. _cache[typeSubstPair] = ty;
  47. return ty;
  48. }
  49. void CloneType::visit(UndefinedType *type)
  50. {
  51. _type.setType(type);
  52. }
  53. void CloneType::visit(VoidType *)
  54. {
  55. _type.setType(_control->voidType());
  56. }
  57. void CloneType::visit(IntegerType *type)
  58. {
  59. _type.setType(_control->integerType(type->kind()));
  60. }
  61. void CloneType::visit(FloatType *type)
  62. {
  63. _type.setType(_control->floatType(type->kind()));
  64. }
  65. void CloneType::visit(PointerToMemberType *type)
  66. {
  67. _type.setType(_control->pointerToMemberType(_clone->name(type->memberName(), _subst),
  68. _clone->type(type->elementType(), _subst)));
  69. }
  70. void CloneType::visit(PointerType *type)
  71. {
  72. _type.setType(_control->pointerType(_clone->type(type->elementType(), _subst)));
  73. }
  74. void CloneType::visit(ReferenceType *type)
  75. {
  76. _type.setType(_control->referenceType(_clone->type(type->elementType(), _subst), type->isRvalueReference()));
  77. }
  78. void CloneType::visit(ArrayType *type)
  79. {
  80. _type.setType(_control->arrayType(_clone->type(type->elementType(), _subst), type->size()));
  81. }
  82. void CloneType::visit(NamedType *type)
  83. {
  84. const Name *name = _clone->name(type->name(), _subst);
  85. FullySpecifiedType ty;
  86. if (_subst)
  87. ty = _subst->apply(name);
  88. if (! ty.isValid())
  89. ty = _control->namedType(name);
  90. _type.setType(ty.type());
  91. }
  92. void CloneType::visit(Function *type)
  93. {
  94. Function *f = _clone->symbol(type, _subst)->asFunction();
  95. _type = f;
  96. }
  97. void CloneType::visit(Namespace *type)
  98. {
  99. Namespace *ns = _clone->symbol(type, _subst)->asNamespace();
  100. _type = ns;
  101. }
  102. void CloneType::visit(Template *type)
  103. {
  104. Template *templ = _clone->symbol(type, _subst)->asTemplate();
  105. _type = templ;
  106. }
  107. void CloneType::visit(Class *type)
  108. {
  109. Class *klass = _clone->symbol(type, _subst)->asClass();
  110. _type = klass;
  111. }
  112. void CloneType::visit(Enum *type)
  113. {
  114. Enum *e = _clone->symbol(type, _subst)->asEnum();
  115. _type = e;
  116. }
  117. void CloneType::visit(ForwardClassDeclaration *type)
  118. {
  119. ForwardClassDeclaration *fwd = _clone->symbol(type, _subst)->asForwardClassDeclaration();
  120. _type = fwd;
  121. }
  122. void CloneType::visit(ObjCClass *type)
  123. {
  124. ObjCClass *klass = _clone->symbol(type, _subst)->asObjCClass();
  125. _type = klass;
  126. }
  127. void CloneType::visit(ObjCProtocol *type)
  128. {
  129. ObjCProtocol *proto = _clone->symbol(type, _subst)->asObjCProtocol();
  130. _type = proto;
  131. }
  132. void CloneType::visit(ObjCMethod *type)
  133. {
  134. ObjCMethod *meth = _clone->symbol(type, _subst)->asObjCMethod();
  135. _type = meth;
  136. }
  137. void CloneType::visit(ObjCForwardClassDeclaration *type)
  138. {
  139. ObjCForwardClassDeclaration *fwd = _clone->symbol(type, _subst)->asObjCForwardClassDeclaration();
  140. _type = fwd;
  141. }
  142. void CloneType::visit(ObjCForwardProtocolDeclaration *type)
  143. {
  144. ObjCForwardProtocolDeclaration *fwd = _clone->symbol(type, _subst)->asObjCForwardProtocolDeclaration();
  145. _type = fwd;
  146. }
  147. CloneSymbol::CloneSymbol(Clone *clone)
  148. : _clone(clone)
  149. , _control(clone->control())
  150. , _subst(0)
  151. , _symbol(0)
  152. {
  153. }
  154. Symbol *CloneSymbol::cloneSymbol(Symbol *symbol, Subst *subst)
  155. {
  156. if (! symbol)
  157. return 0;
  158. SymbolSubstPair symbolSubstPair = std::make_pair(symbol, subst);
  159. if (_cache.find(symbolSubstPair) != _cache.end()) {
  160. Symbol *cachedSymbol = _cache[symbolSubstPair];
  161. if (cachedSymbol->enclosingScope() == symbol->enclosingScope())
  162. return cachedSymbol;
  163. }
  164. Symbol *r = 0;
  165. std::swap(_subst, subst);
  166. std::swap(_symbol, r);
  167. accept(symbol);
  168. std::swap(_symbol, r);
  169. std::swap(_subst, subst);
  170. CPP_CHECK(r != 0);
  171. _cache[symbolSubstPair] = r;
  172. return r;
  173. }
  174. bool CloneSymbol::visit(UsingNamespaceDirective *symbol)
  175. {
  176. UsingNamespaceDirective *u = new UsingNamespaceDirective(_clone, _subst, symbol);
  177. _symbol = u;
  178. _control->addSymbol(u);
  179. return false;
  180. }
  181. bool CloneSymbol::visit(UsingDeclaration *symbol)
  182. {
  183. UsingDeclaration *u = new UsingDeclaration(_clone, _subst, symbol);
  184. _symbol = u;
  185. _control->addSymbol(u);
  186. return false;
  187. }
  188. bool CloneSymbol::visit(NamespaceAlias *symbol)
  189. {
  190. NamespaceAlias *ns = new NamespaceAlias(_clone, _subst, symbol);
  191. _symbol = ns;
  192. _control->addSymbol(ns);
  193. return false;
  194. }
  195. bool CloneSymbol::visit(Declaration *symbol)
  196. {
  197. Declaration *decl = new Declaration(_clone, _subst, symbol);
  198. _symbol = decl;
  199. _control->addSymbol(decl);
  200. return false;
  201. }
  202. bool CloneSymbol::visit(Argument *symbol)
  203. {
  204. Argument *arg = new Argument(_clone, _subst, symbol);
  205. _symbol = arg;
  206. _control->addSymbol(arg);
  207. return false;
  208. }
  209. bool CloneSymbol::visit(TypenameArgument *symbol)
  210. {
  211. TypenameArgument *arg = new TypenameArgument(_clone, _subst, symbol);
  212. _symbol = arg;
  213. _control->addSymbol(arg);
  214. return false;
  215. }
  216. bool CloneSymbol::visit(BaseClass *symbol)
  217. {
  218. BaseClass *bc = new BaseClass(_clone, _subst, symbol);
  219. _symbol = bc;
  220. _control->addSymbol(bc);
  221. return false;
  222. }
  223. bool CloneSymbol::visit(Enum *symbol)
  224. {
  225. Enum *e = new Enum(_clone, _subst, symbol);
  226. _symbol = e;
  227. _control->addSymbol(e);
  228. return false;
  229. }
  230. bool CloneSymbol::visit(Function *symbol)
  231. {
  232. Function *fun = new Function(_clone, _subst, symbol);
  233. _symbol = fun;
  234. _control->addSymbol(fun);
  235. return false;
  236. }
  237. bool CloneSymbol::visit(Namespace *symbol)
  238. {
  239. Namespace *ns = new Namespace(_clone, _subst, symbol);
  240. _symbol = ns;
  241. _control->addSymbol(ns);
  242. return false;
  243. }
  244. bool CloneSymbol::visit(Template *symbol)
  245. {
  246. Template *templ = new Template(_clone, _subst, symbol);
  247. _symbol = templ;
  248. _control->addSymbol(templ);
  249. return false;
  250. }
  251. bool CloneSymbol::visit(Class *symbol)
  252. {
  253. Class *klass = new Class(_clone, _subst, symbol);
  254. _symbol = klass;
  255. _control->addSymbol(klass);
  256. return false;
  257. }
  258. bool CloneSymbol::visit(Block *symbol)
  259. {
  260. Block *block = new Block(_clone, _subst, symbol);
  261. _symbol = block;
  262. _control->addSymbol(block);
  263. return false;
  264. }
  265. bool CloneSymbol::visit(ForwardClassDeclaration *symbol)
  266. {
  267. ForwardClassDeclaration *fwd = new ForwardClassDeclaration(_clone, _subst, symbol);
  268. _symbol = fwd;
  269. _control->addSymbol(fwd);
  270. return false;
  271. }
  272. bool CloneSymbol::visit(QtPropertyDeclaration *symbol)
  273. {
  274. QtPropertyDeclaration *decl = new QtPropertyDeclaration(_clone, _subst, symbol);
  275. _symbol = decl;
  276. _control->addSymbol(decl);
  277. return false;
  278. }
  279. bool CloneSymbol::visit(QtEnum *symbol)
  280. {
  281. QtEnum *e = new QtEnum(_clone, _subst, symbol);
  282. _symbol = e;
  283. _control->addSymbol(e);
  284. return false;
  285. }
  286. bool CloneSymbol::visit(ObjCBaseClass *symbol)
  287. {
  288. ObjCBaseClass *bc = new ObjCBaseClass(_clone, _subst, symbol);
  289. _symbol = bc;
  290. _control->addSymbol(bc);
  291. return false;
  292. }
  293. bool CloneSymbol::visit(ObjCBaseProtocol *symbol)
  294. {
  295. ObjCBaseProtocol *bc = new ObjCBaseProtocol(_clone, _subst, symbol);
  296. _symbol = bc;
  297. _control->addSymbol(bc);
  298. return false;
  299. }
  300. bool CloneSymbol::visit(ObjCClass *symbol)
  301. {
  302. ObjCClass *klass = new ObjCClass(_clone, _subst, symbol);
  303. _symbol = klass;
  304. _control->addSymbol(klass);
  305. return false;
  306. }
  307. bool CloneSymbol::visit(ObjCForwardClassDeclaration *symbol)
  308. {
  309. ObjCForwardClassDeclaration *fwd = new ObjCForwardClassDeclaration(_clone, _subst, symbol);
  310. _symbol = fwd;
  311. _control->addSymbol(fwd);
  312. return false;
  313. }
  314. bool CloneSymbol::visit(ObjCProtocol *symbol)
  315. {
  316. ObjCProtocol *proto = new ObjCProtocol(_clone, _subst, symbol);
  317. _symbol = proto;
  318. _control->addSymbol(proto);
  319. return false;
  320. }
  321. bool CloneSymbol::visit(ObjCForwardProtocolDeclaration *symbol)
  322. {
  323. ObjCForwardProtocolDeclaration *fwd = new ObjCForwardProtocolDeclaration(_clone, _subst, symbol);
  324. _symbol = fwd;
  325. _control->addSymbol(fwd);
  326. return false;
  327. }
  328. bool CloneSymbol::visit(ObjCMethod *symbol)
  329. {
  330. ObjCMethod *meth = new ObjCMethod(_clone, _subst, symbol);
  331. _symbol = meth;
  332. _control->addSymbol(meth);
  333. return false;
  334. }
  335. bool CloneSymbol::visit(ObjCPropertyDeclaration *symbol)
  336. {
  337. ObjCPropertyDeclaration *decl = new ObjCPropertyDeclaration(_clone, _subst, symbol);
  338. _symbol = decl;
  339. _control->addSymbol(decl);
  340. return false;
  341. }
  342. CloneName::CloneName(Clone *clone)
  343. : _clone(clone)
  344. , _control(clone->control())
  345. , _subst(0)
  346. , _name(0)
  347. {
  348. }
  349. const Name *CloneName::cloneName(const Name *name, Subst *subst)
  350. {
  351. if (! name)
  352. return 0;
  353. NameSubstPair nameSubstPair = std::make_pair(name, subst);
  354. if (_cache.find(nameSubstPair) != _cache.end())
  355. return _cache[nameSubstPair];
  356. const Name *r = 0;
  357. std::swap(_subst, subst);
  358. std::swap(_name, r);
  359. accept(name);
  360. std::swap(_name, r);
  361. std::swap(_subst, subst);
  362. CPP_CHECK(r != 0);
  363. _cache[nameSubstPair] = r;
  364. return r;
  365. }
  366. void CloneName::visit(const Identifier *name)
  367. {
  368. _name = _control->identifier(name->chars(), name->size());
  369. }
  370. void CloneName::visit(const AnonymousNameId *name)
  371. {
  372. _name = _control->anonymousNameId(name->classTokenIndex());
  373. }
  374. void CloneName::visit(const TemplateNameId *name)
  375. {
  376. std::vector<FullySpecifiedType> args(name->templateArgumentCount());
  377. for (unsigned i = 0; i < args.size(); ++i)
  378. args[i] = _clone->type(name->templateArgumentAt(i), _subst);
  379. if (args.empty())
  380. _name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization());
  381. else
  382. _name = _control->templateNameId(_clone->identifier(name->identifier()), name->isSpecialization(),
  383. &args[0], unsigned(args.size()));
  384. }
  385. void CloneName::visit(const DestructorNameId *name)
  386. {
  387. _name = _control->destructorNameId(_clone->identifier(name->identifier()));
  388. }
  389. void CloneName::visit(const OperatorNameId *name)
  390. {
  391. _name = _control->operatorNameId(name->kind());
  392. }
  393. void CloneName::visit(const ConversionNameId *name)
  394. {
  395. _name = _control->conversionNameId(_clone->type(name->type(), _subst));
  396. }
  397. void CloneName::visit(const QualifiedNameId *name)
  398. {
  399. _name = _control->qualifiedNameId(_clone->name(name->base(), _subst),
  400. _clone->name(name->name(), _subst));
  401. }
  402. void CloneName::visit(const SelectorNameId *name)
  403. {
  404. CPP_CHECK(name->nameCount() > 0);
  405. std::vector<const Name *> names(name->nameCount());
  406. for (unsigned i = 0; i < names.size(); ++i)
  407. names[i] = _clone->name(name->nameAt(i), _subst);
  408. _name = _control->selectorNameId(&names[0], unsigned(names.size()), name->hasArguments());
  409. }
  410. Clone::Clone(Control *control)
  411. : _control(control)
  412. , _type(this)
  413. , _name(this)
  414. , _symbol(this)
  415. {
  416. }
  417. const StringLiteral *Clone::stringLiteral(const StringLiteral *literal)
  418. {
  419. return literal ? _control->stringLiteral(literal->chars(), literal->size()) : 0;
  420. }
  421. const NumericLiteral *Clone::numericLiteral(const NumericLiteral *literal)
  422. {
  423. return literal ? _control->numericLiteral(literal->chars(), literal->size()) : 0;
  424. }
  425. const Identifier *Clone::identifier(const Identifier *id)
  426. {
  427. return id ? _control->identifier(id->chars(), id->size()) : 0;
  428. }
  429. FullySpecifiedType Clone::type(const FullySpecifiedType &type, Subst *subst)
  430. {
  431. return _type(type, subst);
  432. }
  433. const Name *Clone::name(const Name *name, Subst *subst)
  434. {
  435. return _name(name, subst);
  436. }
  437. Symbol *Clone::symbol(Symbol *symbol, Subst *subst)
  438. {
  439. return _symbol(symbol, subst);
  440. }
  441. Symbol *Clone::instantiate(Template *templ, const FullySpecifiedType *const args, unsigned argc, Subst *s)
  442. {
  443. Subst subst(_control, s);
  444. for (unsigned i = 0, e = std::min(templ->templateParameterCount(), argc); i < e; ++i) {
  445. Symbol *formal = templ->templateParameterAt(i);
  446. FullySpecifiedType actual = args[i];
  447. subst.bind(name(formal->name(), 0), actual);
  448. }
  449. if (argc < templ->templateParameterCount()) {
  450. for (unsigned i = argc; i < templ->templateParameterCount(); ++i) {
  451. Symbol *formal = templ->templateParameterAt(i);
  452. if (TypenameArgument *tn = formal->asTypenameArgument())
  453. subst.bind(name(formal->name(), &subst), type(tn->type(), &subst));
  454. }
  455. }
  456. if (Symbol *inst = symbol(templ->declaration(), &subst)) {
  457. inst->setEnclosingScope(templ->enclosingScope());
  458. return inst;
  459. }
  460. return 0;
  461. }
  462. //
  463. // substitutions
  464. //
  465. FullySpecifiedType Subst::apply(const Name *name) const
  466. {
  467. if (name) {
  468. std::map<const Name *, FullySpecifiedType, Name::Compare>::const_iterator it = _map.find(name);
  469. if (it != _map.end())
  470. return it->second;
  471. else if (_previous)
  472. return _previous->apply(name);
  473. else if (const QualifiedNameId *q = name->asQualifiedNameId()) {
  474. const NamedType *baseNamedType = apply(q->base())->asNamedType();
  475. const NamedType *unqualified = apply(q->name())->asNamedType();
  476. if (baseNamedType) {
  477. if (! unqualified) {
  478. const Name *qualifiedBase = baseNamedType->name();
  479. const Name *qualifiedName = q->name();
  480. return control()->namedType(control()->qualifiedNameId(qualifiedBase,
  481. qualifiedName));
  482. }
  483. else if(baseNamedType->name()->identifier() != 0) {
  484. const QualifiedNameId *clonedQualifiedNameId
  485. = control()->qualifiedNameId(baseNamedType->name()->identifier(),
  486. unqualified->name());
  487. NamedType *clonedNamedType = control()->namedType(clonedQualifiedNameId);
  488. return clonedNamedType;
  489. }
  490. }
  491. }
  492. }
  493. return FullySpecifiedType();
  494. }