151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- C++ -*-===// 251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// The LLVM Compiler Infrastructure 451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// This file is distributed under the University of Illinois Open Source 651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// License. See LICENSE.TXT for details. 751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// These tablegen backends emit Clang AST node tables 1151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 1351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 143cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/Record.h" 153cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 163cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include <cctype> 173cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include <map> 1851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <set> 193cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include <string> 2051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourneusing namespace llvm; 2151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 223cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// ClangASTNodesEmitter - The top-level class emits .inc files containing 233cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// declarations of Clang statements. 243cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// 253cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace { 263cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenclass ClangASTNodesEmitter { 273cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // A map from a node to each of its derived nodes. 283cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen typedef std::multimap<Record*, Record*> ChildMap; 293cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen typedef ChildMap::const_iterator ChildIterator; 303cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 313cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen RecordKeeper &Records; 323cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Record Root; 333cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen const std::string &BaseSuffix; 343cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 353cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // Create a macro-ized version of a name 363cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen static std::string macroName(std::string S) { 373cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen for (unsigned i = 0; i < S.size(); ++i) 383cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen S[i] = std::toupper(S[i]); 393cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 403cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen return S; 413cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen } 423cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 433cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // Return the name to be printed in the base field. Normally this is 443cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // the record's name plus the base suffix, but if it is the root node and 453cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // the suffix is non-empty, it's just the suffix. 463cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen std::string baseName(Record &R) { 473cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen if (&R == &Root && !BaseSuffix.empty()) 483cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen return BaseSuffix; 493cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 503cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen return R.getName() + BaseSuffix; 513cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen } 523cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 533cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS, 543cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Record *Base); 553cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenpublic: 563cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N, 573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen const std::string &S) 583cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen : Records(R), Root(N, SMLoc(), R), BaseSuffix(S) 593cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen {} 603cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 613cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // run - Output the .inc file contents 623cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen void run(raw_ostream &OS); 633cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen}; 643cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end anonymous namespace 653cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 6651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 6751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Statement Node Tables (.inc file) generation. 6851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 6951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 7051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Returns the first and last non-abstract subrecords 7151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Called recursively to ensure that nodes remain contiguous 7251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestd::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode( 7351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const ChildMap &Tree, 7451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne raw_ostream &OS, 7551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *Base) { 7651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string BaseName = macroName(Base->getName()); 7751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 7851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base); 7951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *First = 0, *Last = 0; 8151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // This might be the pseudo-node for Stmt; don't assume it has an Abstract 8251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // bit 8351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract")) 8451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne First = Last = Base; 8551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (; i != e; ++i) { 8751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = i->second; 8851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool Abstract = R->getValueAsBit("Abstract"); 8951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string NodeName = macroName(R->getName()); 9051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef " << NodeName << "\n"; 9251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "# define " << NodeName << "(Type, Base) " 9351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << BaseName << "(Type, Base)\n"; 9451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n"; 9551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Abstract) 9751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "(" 9851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << R->getName() << ", " << baseName(*Base) << "))\n"; 9951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 10051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << NodeName << "(" << R->getName() << ", " 10151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << baseName(*Base) << ")\n"; 10251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 10351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Tree.find(R) != Tree.end()) { 10451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::pair<Record *, Record *> &Result 10551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne = EmitNode(Tree, OS, R); 10651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!First && Result.first) 10751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne First = Result.first; 10851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Result.second) 10951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Last = Result.second; 11051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 11151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!Abstract) { 11251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Last = R; 11351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!First) 11551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne First = R; 11651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 11851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef " << NodeName << "\n\n"; 12051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 12151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 12251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (First) { 12351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert (Last && "Got a first node but not a last node for a range!"); 12451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Base == &Root) 12551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "LAST_" << macroName(Root.getName()) << "_RANGE("; 12651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 12751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << macroName(Root.getName()) << "_RANGE("; 12851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << Base->getName() << ", " << First->getName() << ", " 12951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << Last->getName() << ")\n\n"; 13051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 13151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 13251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return std::make_pair(First, Last); 13351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 13451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 13551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournevoid ClangASTNodesEmitter::run(raw_ostream &OS) { 13651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Write the preamble 13751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n"; 13851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n"; 13951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n"; 14051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 14151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n"; 14251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "# define " 14351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; 14451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 14551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 14651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n"; 14751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "# define LAST_" 14851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << macroName(Root.getName()) << "_RANGE(Base, First, Last) " 14951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; 15051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 15151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 15251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit statements 15351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<Record*> Stmts 15451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne = Records.getAllDerivedDefinitions(Root.getName()); 15551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 15651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ChildMap Tree; 15751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 15851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = Stmts.size(); i != e; ++i) { 15951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = Stmts[i]; 16051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 16151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R->getValue("Base")) 16251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Tree.insert(std::make_pair(R->getValueAsDef("Base"), R)); 16351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 16451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Tree.insert(std::make_pair(&Root, R)); 16551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 16651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 16751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne EmitNode(Tree, OS, &Root); 16851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 16951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef " << macroName(Root.getName()) << "\n"; 17051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef " << macroName(Root.getName()) << "_RANGE\n"; 17151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n"; 17251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n"; 17351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 17451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 1753cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 1763cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS, 1773cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen const std::string &N, const std::string &S) { 1783cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClangASTNodesEmitter(RK, N, S).run(OS); 1793cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} 1803cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1813cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits and addendum to a .inc file to enumerate the clang declaration 1823cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// contexts. 1833cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangDeclContext(RecordKeeper &Records, raw_ostream &OS) { 18451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: Find a .td file format to allow for this to be represented better. 18551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 18651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef DECL_CONTEXT\n"; 18751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "# define DECL_CONTEXT(DECL)\n"; 18851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n"; 18951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 19051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef DECL_CONTEXT_BASE\n"; 19151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "# define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n"; 19251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n"; 19351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 19451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne typedef std::set<Record*> RecordSet; 19551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne typedef std::vector<Record*> RecordVector; 19651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 19751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordVector DeclContextsVector 19851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne = Records.getAllDerivedDefinitions("DeclContext"); 19951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordVector Decls = Records.getAllDerivedDefinitions("Decl"); 20051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end()); 20151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 20251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) { 20351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = *i; 20451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 20551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R->getValue("Base")) { 20651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *B = R->getValueAsDef("Base"); 20751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (DeclContexts.find(B) != DeclContexts.end()) { 20851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n"; 20951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne DeclContexts.erase(B); 21051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 21151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 21251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 21351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 21451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // To keep identical order, RecordVector may be used 21551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // instead of RecordSet. 21651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (RecordVector::iterator 21751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne i = DeclContextsVector.begin(), e = DeclContextsVector.end(); 21851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne i != e; ++i) 21951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (DeclContexts.find(*i) != DeclContexts.end()) 22051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "DECL_CONTEXT(" << (*i)->getName() << ")\n"; 22151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 22251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef DECL_CONTEXT\n"; 22351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef DECL_CONTEXT_BASE\n"; 22451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 2253cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 226