diff --git a/GCC_XML/GXFront/gxConfiguration.cxx b/GCC_XML/GXFront/gxConfiguration.cxx index c201736..57c4954 100644 --- a/GCC_XML/GXFront/gxConfiguration.cxx +++ b/GCC_XML/GXFront/gxConfiguration.cxx @@ -875,6 +875,153 @@ bool gxConfiguration::CheckFlags() return true; } +//---------------------------------------------------------------------------- +// Implemented below (at the bottom of the cxx file) to avoid windows.h +// mangling of #define symbols... +int GetPID(); + +//---------------------------------------------------------------------------- +std::string AttemptTempFileName(const char* prefix, const char* ext) +{ + std::string dir; + std::string file; + + // Get TMP, TEMP or "/tmp" dir if one exists, + // or if not, use "." (current dir) + // + gxSystemTools::GetEnv("TMP", dir); + if(dir.empty() || !gxSystemTools::FileExists(dir.c_str())) + { + gxSystemTools::GetEnv("TEMP", dir); + } + if(dir.empty() || !gxSystemTools::FileExists(dir.c_str())) + { + dir = "/tmp"; + } + if(dir.empty() || !gxSystemTools::FileExists(dir.c_str())) + { + dir = "."; + } + gxSystemTools::ConvertToUnixSlashes(dir); + + file = dir; + + if(!gxSystemTools::StringEndsWith(file.c_str(), "/")) + { + file += "/"; + } + if(prefix) + { + file += prefix; + } + + gxsys_ios::ostringstream oss; + oss << GetPID(); + + file += oss.str(); + + if(ext) + { + file += ext; + } + + return file; +} + +//---------------------------------------------------------------------------- +std::string GetTempFileName(const char* prefix, const char* ext) +{ + std::string name(AttemptTempFileName(prefix, ext)); + int counter = 1; + + // Use counter to unique-ify and return a name that does not + // currently exist: + // + while (gxSystemTools::FileExists(name.c_str())) + { + gxsys_ios::ostringstream oss; + oss << "x"; + oss << counter; + if (ext) + { + oss << ext; + } + + name = AttemptTempFileName(prefix, oss.str().c_str()); + counter++; + } + + return name; +} + +//---------------------------------------------------------------------------- +std::string gxConfiguration::GetCompilerId() +{ + // This method uses the technique formerly found in the shell script + // "${GCCXML_SOURCE_DIR}/Support/gccxml_find_flags" to identify the + // compiler whose executable file is m_GCCXML_COMPILER. It presently + // depends on the compiler being able to preprocess a ".cpp" input file + // via the -E command line argument with no other flags. + // + // An arguably better approach (but one that is more complex) would be + // to mimic what CMake does: compile its Modules/CMakeCXXCompilerId.cpp + // file and analyze the resulting compiler produced files for strings. + // + std::string compilerID("ERROR_unsupported_compiler_in_gxConfiguration_GetCompilerId"); + + // Write a temp file such that after preprocessing there should only be + // one "(.*)" chunk in the output. + // + std::string cppFile(GetTempFileName("gx", ".cpp")); + std::ofstream ofs(cppFile.c_str()); + + ofs << "#if defined(__GNUC__)" << std::endl; + ofs << "GCC" << std::endl; + ofs << "#elif defined(__sgi) && defined(_COMPILER_VERSION)" << std::endl; + ofs << "MIPSpro" << std::endl; + ofs << "#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 700)" << std::endl; + ofs << "Intel" << std::endl; + ofs << "#else" << std::endl; + ofs << "ERROR_unsupported_compiler_in_gxConfiguration_GetCompilerId" << std::endl; + ofs << "#endif" << std::endl; + + ofs.flush(); + ofs.close(); + + // Try running the compiler against the temp file with -E to preprocess + // the input. Then analyze the output looking for the "(.*)" chunk. + // + std::string output; + int retVal=0; + if(gxSystemTools::RunCommand((m_GCCXML_COMPILER + " -E \"" + cppFile + + "\"").c_str(), output, retVal) && (0 == retVal)) + { + gxsys::RegularExpression reId; + reId.compile("(.*)"); + + std::vector lines = gxSystemTools::SplitString(output.c_str(), '\n'); + std::vector::iterator it; + for(it = lines.begin(); it != lines.end(); ++it) + { + if(reId.find(it->c_str())) + { + compilerID = reId.match(1); + break; + } + } + } + else + { + std::cerr << "error: could not identify compiler via -E preprocessing" << std::endl; + } + + // Clean up: + // + gxsys::SystemTools::RemoveFile(cppFile.c_str()); + + return compilerID; +} + //---------------------------------------------------------------------------- bool gxConfiguration::FindFlags() { @@ -1152,7 +1299,31 @@ bool gxConfiguration::FindFlags() } } - return this->FindFlagsBuiltIn(); + std::string compilerID = this->GetCompilerId(); + if(compilerID == "GCC") + { + return this->FindFlagsGCC(); + } + else if(compilerID == "Intel") + { + return this->FindFlagsIntel(); + } + else if(compilerID == "MIPSpro") + { + return this->FindFlagsMIPSpro(); + } + + // Didn't find / couldn't identify supported compiler. + // + std::cerr << std::endl; + std::cerr << "m_GCCXML_COMPILER: " << m_GCCXML_COMPILER << std::endl; + std::cerr << "compilerName: " << compilerName << std::endl; + std::cerr << "compilerID: " << compilerID << std::endl; + std::cerr << std::endl; + std::cerr << "Compiler \"" << m_GCCXML_COMPILER + << "\" is not supported by GCC_XML.\n" + << "(gxConfiguration::FindFlags)\n"; + return false; #else // This is a UNIX environment. Use the gccxml_find_flags script. std::string gccxmlFindFlags; @@ -1196,76 +1367,22 @@ bool gxConfiguration::FindFlags() #endif } -//---------------------------------------------------------------------------- -#if defined(__GNUC__) - #define GCCXML_SUPPORT_DEFINE "GCC" - #define MAJOR_VERSION_DEFINE __GNUC__ - #define MINOR_VERSION_DEFINE __GNUC_MINOR__ -#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 700) -// TODO - finish Intel translation from sh/find_flags to C++ - #define GCCXML_SUPPORT_DEFINE "Intel" - #define MAJOR_VERSION_DEFINE 12345 - #define MINOR_VERSION_DEFINE 4321 -#elif defined(__sgi) && defined(_COMPILER_VERSION) -// TODO - finish MIPSPro translation from sh/find_flags to C++ - #define GCCXML_SUPPORT_DEFINE "MIPSpro" - #define MAJOR_VERSION_DEFINE 12345 - #define MINOR_VERSION_DEFINE 4321 -#else - #define GCCXML_SUPPORT_DEFINE "" - #define MAJOR_VERSION_DEFINE 22222 - #define MINOR_VERSION_DEFINE 22222 -#endif - -//---------------------------------------------------------------------------- -bool gxConfiguration::FindFlagsBuiltIn() -{ - std::string GCCXML_SUPPORT(GCCXML_SUPPORT_DEFINE); - - if(GCCXML_SUPPORT == "GCC") - { - return this->FindFlagsGCC(); - } - else if(GCCXML_SUPPORT == "Intel") - { - return this->FindFlagsIntel(); - } - else if(GCCXML_SUPPORT == "MIPSpro") - { - return this->FindFlagsMIPSpro(); - } - - // Didn't find supported compiler. - std::cerr << "Compiler \"" << m_GCCXML_COMPILER - << "\" is not supported by GCC_XML.\n" - << "(gxConfiguration::FindFlagsBuiltIn)\n"; - - return false; -} - //---------------------------------------------------------------------------- bool gxConfiguration::FindFlagsGCC() { - // C++ translation of the script "GCC_XML/Support/GCC/find_flags" + // C++ translation of the script "${GCCXML_SOURCE_DIR}/Support/GCC/find_flags" // - std::string GCCXML_SUPPORT(GCCXML_SUPPORT_DEFINE); - - if(GCCXML_SUPPORT != "GCC") - { - return false; - } - - long MAJOR_VERSION = MAJOR_VERSION_DEFINE; - long MINOR_VERSION = MINOR_VERSION_DEFINE; + int MAJOR_VERSION = -1; + int MINOR_VERSION = -1; std::string MACROS; std::string INCLUDES; std::string SPECIAL; gxsys::String s; std::string supportPath; - // The support headers are located in "${GCCXML_SOURCE_DIR}/Support/${GCCXML_SUPPORT}" + // The support headers are located in "${GCCXML_SOURCE_DIR}/Support/GCC" // - this->FindData(GCCXML_SUPPORT.c_str(), supportPath, true); + this->FindData("GCC", supportPath, true); // Run the compiler preprocessor against an empty input file to get the list // of macros that are pre-defined by the compiler: @@ -1298,10 +1415,38 @@ bool gxConfiguration::FindFlagsGCC() MACROS += "='"; MACROS += reDefine.match(2); MACROS += "'"; + + if (-1 == MAJOR_VERSION) + { + if (reDefine.match(1) == "__GNUC__") + { + MAJOR_VERSION = atoi(reDefine.match(2).c_str()); + } + } + + if (-1 == MINOR_VERSION) + { + if (reDefine.match(1) == "__GNUC_MINOR__") + { + MINOR_VERSION = atoi(reDefine.match(2).c_str()); + } + } } } } + if (-1 == MAJOR_VERSION) + { + std::cerr << "error: gxConfiguration::FindFlagsGCC did not find __GNUC__ definition.\n"; + return false; + } + + if (-1 == MINOR_VERSION) + { + std::cerr << "error: gxConfiguration::FindFlagsGCC did not find __GNUC_MINOR__ definition.\n"; + return false; + } + // Run the compiler with "-v" against an empty input file to get the list // of default include paths used by the compiler: // @@ -1444,14 +1589,10 @@ bool gxConfiguration::FindFlagsGCC() //---------------------------------------------------------------------------- bool gxConfiguration::FindFlagsIntel() { - // C++ translation of the script "GCC_XML/Support/Intel/find_flags" + // C++ translation of the script "${GCCXML_SOURCE_DIR}/Support/Intel/find_flags" // - std::string GCCXML_SUPPORT(GCCXML_SUPPORT_DEFINE); - - if(GCCXML_SUPPORT != "Intel") - { - return false; - } + int MAJOR_VERSION = -1; + int MINOR_VERSION = -1; std::cerr << "gxConfiguration::FindFlagsIntel not implemented yet.\n" << "Use GCC_XML/Support/Intel/find_flags until implemented.\n"; @@ -1459,17 +1600,15 @@ bool gxConfiguration::FindFlagsIntel() // TODO - finish Intel translation from sh/find_flags to C++ - long MAJOR_VERSION = MAJOR_VERSION_DEFINE; - long MINOR_VERSION = MINOR_VERSION_DEFINE; std::string MACROS; std::string INCLUDES; std::string SPECIAL; gxsys::String s; std::string supportPath; - // The support headers are located in "${GCCXML_SOURCE_DIR}/Support/${GCCXML_SUPPORT}" + // The support headers are located in "${GCCXML_SOURCE_DIR}/Support/Intel" // - this->FindData(GCCXML_SUPPORT.c_str(), supportPath, true); + this->FindData("Intel", supportPath, true); // Run the compiler preprocessor against an empty input file to get the list // of macros that are pre-defined by the compiler: @@ -1502,10 +1641,38 @@ bool gxConfiguration::FindFlagsIntel() MACROS += "='"; MACROS += reDefine.match(2); MACROS += "'"; + + if (-1 == MAJOR_VERSION) + { + if (reDefine.match(1) == "__GNUC__") + { + MAJOR_VERSION = atoi(reDefine.match(2).c_str()); + } + } + + if (-1 == MINOR_VERSION) + { + if (reDefine.match(1) == "__GNUC_MINOR__") + { + MINOR_VERSION = atoi(reDefine.match(2).c_str()); + } + } } } } + if (-1 == MAJOR_VERSION) + { + std::cerr << "error: gxConfiguration::FindFlagsIntel did not find __GNUC__ definition.\n"; + return false; + } + + if (-1 == MINOR_VERSION) + { + std::cerr << "error: gxConfiguration::FindFlagsIntel did not find __GNUC_MINOR__ definition.\n"; + return false; + } + // Run the compiler with "-v" against an empty input file to get the list // of default include paths used by the compiler: // @@ -1648,14 +1815,10 @@ bool gxConfiguration::FindFlagsIntel() //---------------------------------------------------------------------------- bool gxConfiguration::FindFlagsMIPSpro() { - // C++ translation of the script "GCC_XML/Support/MIPSpro/find_flags" + // C++ translation of the script "${GCCXML_SOURCE_DIR}/Support/MIPSpro/find_flags" // - std::string GCCXML_SUPPORT(GCCXML_SUPPORT_DEFINE); - - if(GCCXML_SUPPORT != "MIPSpro") - { - return false; - } + int MAJOR_VERSION = -1; + int MINOR_VERSION = -1; std::cerr << "gxConfiguration::FindFlagsMIPSpro not implemented yet.\n" << "Use GCC_XML/Support/MIPSpro/find_flags until implemented.\n"; @@ -1663,17 +1826,15 @@ bool gxConfiguration::FindFlagsMIPSpro() // TODO - finish MIPSPro translation from sh/find_flags to C++ - long MAJOR_VERSION = MAJOR_VERSION_DEFINE; - long MINOR_VERSION = MINOR_VERSION_DEFINE; std::string MACROS; std::string INCLUDES; std::string SPECIAL; gxsys::String s; std::string supportPath; - // The support headers are located in "${GCCXML_SOURCE_DIR}/Support/${GCCXML_SUPPORT}" + // The support headers are located in "${GCCXML_SOURCE_DIR}/Support/MIPSpro" // - this->FindData(GCCXML_SUPPORT.c_str(), supportPath, true); + this->FindData("MIPSpro", supportPath, true); // Run the compiler preprocessor against an empty input file to get the list // of macros that are pre-defined by the compiler: @@ -1706,10 +1867,38 @@ bool gxConfiguration::FindFlagsMIPSpro() MACROS += "='"; MACROS += reDefine.match(2); MACROS += "'"; + + if (-1 == MAJOR_VERSION) + { + if (reDefine.match(1) == "__GNUC__") + { + MAJOR_VERSION = atoi(reDefine.match(2).c_str()); + } + } + + if (-1 == MINOR_VERSION) + { + if (reDefine.match(1) == "__GNUC_MINOR__") + { + MINOR_VERSION = atoi(reDefine.match(2).c_str()); + } + } } } } + if (-1 == MAJOR_VERSION) + { + std::cerr << "error: gxConfiguration::FindFlagsMIPSpro did not find __GNUC__ definition.\n"; + return false; + } + + if (-1 == MINOR_VERSION) + { + std::cerr << "error: gxConfiguration::FindFlagsMIPSpro did not find __GNUC_MINOR__ definition.\n"; + return false; + } + // Run the compiler with "-v" against an empty input file to get the list // of default include paths used by the compiler: // @@ -2168,3 +2357,20 @@ bool gxConfiguration::FindFlagsBCC55(const char* inBcc32) "-I\""+include3+"\" "; return true; } + +//---------------------------------------------------------------------------- +// Keep this section here (at the bottom of the cxx file) to avoid windows.h +// mangling of #define symbols... +#ifdef _WIN32 +#include +#endif + +//---------------------------------------------------------------------------- +int GetPID() +{ +#ifdef _WIN32 + return (int) GetCurrentProcessId(); +#else + return (int) getpid(); +#endif +} diff --git a/GCC_XML/GXFront/gxConfiguration.h b/GCC_XML/GXFront/gxConfiguration.h index f015c56..2c2af26 100644 --- a/GCC_XML/GXFront/gxConfiguration.h +++ b/GCC_XML/GXFront/gxConfiguration.h @@ -149,9 +149,11 @@ class gxConfiguration // Check if we have a flags setting. If not, find it. bool CheckFlags(); + // Run the compiler to identify it. + std::string GetCompilerId(); + // Find flags based on compiler setting. bool FindFlags(); - bool FindFlagsBuiltIn(); bool FindFlagsGCC(); bool FindFlagsIntel(); bool FindFlagsMIPSpro(); diff --git a/GCC_XML/KWSys/SystemTools.cxx b/GCC_XML/KWSys/SystemTools.cxx index 3548a14..778774c 100644 --- a/GCC_XML/KWSys/SystemTools.cxx +++ b/GCC_XML/KWSys/SystemTools.cxx @@ -455,6 +455,11 @@ void SystemTools::ReplaceString(kwsys_stl::string& source, // perform replacements until done size_t replaceSize = strlen(replace); + // do while hangs if replaceSize is 0 + if(replaceSize == 0) + { + return; + } char *orig = strdup(src); char *currentPos = orig; searchPos = searchPos - src + orig; @@ -1464,7 +1469,8 @@ kwsys_stl::string SystemTools::ConvertToWindowsOutputPath(const char* path) // make it big enough for all of path and double quotes ret.reserve(strlen(path)+3); // put path into the string - ret.insert(0,path); + ret.assign(path); + ret = path; kwsys_stl::string::size_type pos = 0; // first convert all of the slashes while((pos = ret.find('/', pos)) != kwsys_stl::string::npos) @@ -2747,22 +2753,15 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot sameCount++; } -#if 0 - // NOTE: We did this at one time to prevent relative paths to the - // compiler from looking like "../../../../../../../usr/bin/gcc". - // Now however relative paths are only computed for destinations - // inside the build tree so this is not a problem. This is now a - // general-purpose method and should not have this hack. I'm - // leaving it in place in case removing it causes a problem so it is - // easy to restore: - // - // If there is nothing in common but the root directory, then just - // return the full path. - if(sameCount <= 1) + // If there is nothing in common at all then just return the full + // path. This is the case only on windows when the paths have + // different drive letters. On unix two full paths always at least + // have the root "/" in common so we will return a relative path + // that passes through the root directory. + if(sameCount == 0) { return remote; } -#endif // for each entry that is not common in the local path // add a ../ to the finalpath array, this gets us out of the local @@ -2879,6 +2878,14 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p) #ifndef _WIN32 return p; #else + // Check to see if actual case has already been called + // for this path, and the result is stored in the LongPathMap + SystemToolsTranslationMap::iterator i = + SystemTools::LongPathMap->find(p); + if(i != SystemTools::LongPathMap->end()) + { + return i->second; + } kwsys_stl::string shortPath; if(!SystemTools::GetShortPath(p, shortPath)) { @@ -2895,6 +2902,7 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p) { longPath[0] = toupper(longPath[0]); } + (*SystemTools::LongPathMap)[p] = longPath; return longPath; #endif } @@ -3369,7 +3377,7 @@ bool SystemTools::LocateFileInDir(const char *filename, } temp += filename_base; - if (SystemTools::FileExists(filename_found.c_str())) + if (SystemTools::FileExists(temp.c_str())) { res = true; filename_found = temp; @@ -3595,7 +3603,7 @@ kwsys_stl::string SystemTools::MakeCindentifier(const char* s) return str; } -// Due to a buggy stream library on the HP and another on Mac OSX, we +// Due to a buggy stream library on the HP and another on Mac OS X, we // need this very carefully written version of getline. Returns true // if any data were read before the end-of-file was reached. bool SystemTools::GetLineFromStream(kwsys_ios::istream& is, @@ -4192,6 +4200,7 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() // necessary. unsigned int SystemToolsManagerCount; SystemToolsTranslationMap *SystemTools::TranslationMap; +SystemToolsTranslationMap *SystemTools::LongPathMap; // SystemToolsManager manages the SystemTools singleton. // SystemToolsManager should be included in any translation unit @@ -4219,6 +4228,7 @@ void SystemTools::ClassInitialize() { // Allocate the translation map first. SystemTools::TranslationMap = new SystemToolsTranslationMap; + SystemTools::LongPathMap = new SystemToolsTranslationMap; // Add some special translation paths for unix. These are not added // for windows because drive letters need to be maintained. Also, @@ -4274,6 +4284,7 @@ void SystemTools::ClassInitialize() void SystemTools::ClassFinalize() { delete SystemTools::TranslationMap; + delete SystemTools::LongPathMap; } diff --git a/GCC_XML/KWSys/SystemTools.hxx.in b/GCC_XML/KWSys/SystemTools.hxx.in index 4539364..b5b6b52 100644 --- a/GCC_XML/KWSys/SystemTools.hxx.in +++ b/GCC_XML/KWSys/SystemTools.hxx.in @@ -427,7 +427,7 @@ public: /** * Read line from file. Make sure to get everything. Due to a buggy stream - * library on the HP and another on Mac OSX, we need this very carefully + * library on the HP and another on Mac OS X, we need this very carefully * written version of getline. Returns true if any data were read before the * end-of-file was reached. If the has_newline argument is specified, it will * be true when the line read had a newline character. @@ -813,6 +813,7 @@ private: * Each time 'dir' will be found it will be replace by 'refdir' */ static SystemToolsTranslationMap *TranslationMap; + static SystemToolsTranslationMap *LongPathMap; friend class SystemToolsManager; }; diff --git a/GCC_XML/xml.c b/GCC_XML/xml.c deleted file mode 100644 index 392ce50..0000000 --- a/GCC_XML/xml.c +++ /dev/null @@ -1,3738 +0,0 @@ -/*========================================================================= - - Program: GCC-XML - Module: xml.c - Language: C++ - Date: $Date$ - Version: $Revision$ - - Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. - See Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -/* Organization of this source: - The entry point is do_xml_output(), which is called from the end of - finish_translation_unit() in semantics.c. - - xml_output_* functions are called to actually write the XML output. - - xml_print_*_attribute functions are used to write out the XML attributes - for common attribute name/pair values. -*/ - -/* Use GCC_XML_GCC_VERSION to modify code based on the version of GCC - in which we are being built. This is set in the patched version of - cp-tree.h. The format is 0xMMmmpp, where MM is the major version - number, mm is the minor version number, and pp is the patch level. - Examples: gcc 3.0.4 = 0x030004 - gcc 3.2.0 = 0x030200 */ - -#include "config.h" -#include "system.h" -#include "sys/stat.h" - -/* GCC 3.4 and above need these headers here. The GCC-XML patches for - these versions define GCC_XML_GCC_VERSION in config.h instead of - cp-tree.h, so the macro is available here. The patches for older - versions may provide the macro in cp-tree.h, but in that case - we don't need these headers anyway. */ -#if defined(GCC_XML_GCC_VERSION) && (GCC_XML_GCC_VERSION >= 0x030400) -# include "coretypes.h" -# include "tm.h" -#endif - -#include "tree.h" -#include "cp-tree.h" -#include "decl.h" -#include "rtl.h" -#include "varray.h" - -#include "splay-tree.h" - -#include "demangle.h" - -/* Decide how to call cp_error. */ -#if defined(GCC_XML_GCC_VERSION) && (GCC_XML_GCC_VERSION >= 0x030100) -# define XML_CP_ERROR cp_error_at -#else -# define XML_CP_ERROR cp_error -# define XML_HAVE_FAKE_STD_NODE -#endif - -/* Decide how to get the attributes node from a declaration. */ -#if defined(GCC_XML_GCC_VERSION) && (GCC_XML_GCC_VERSION >= 0x030100) -# define GCC_XML_DECL_ATTRIBUTES(n) DECL_ATTRIBUTES(n) -#else -# define GCC_XML_DECL_ATTRIBUTES(n) DECL_MACHINE_ATTRIBUTES(n) -#endif - -/* Decide how to access base classes. */ -#if !defined(GCC_XML_GCC_VERSION) || (GCC_XML_GCC_VERSION < 0x030400) -# define XML_PRE_3_4_TREE_VIA_PUBLIC -#endif - -#define GCC_XML_C_VERSION "$Revision: 1.115 $" - -/*--------------------------------------------------------------------------*/ -/* Data structures for the actual XML dump. */ - -/* A "dump node" corresponding to a particular tree node. */ -typedef struct xml_dump_node -{ - /* The index for the node. */ - unsigned int index; - - /* Whether the node is complete. */ - unsigned int complete; -} *xml_dump_node_p; - -/* A node on the queue of dump nodes. */ -typedef struct xml_dump_queue -{ - /* The queued tree node. */ - tree tree_node; - - /* The corresponding dump node. */ - xml_dump_node_p dump_node; - - /* The next node in the queue. */ - struct xml_dump_queue *next; -} *xml_dump_queue_p; - -/* A node on the queue of file names. */ -typedef struct xml_file_queue -{ - /* The queued file name. */ - splay_tree_node tree_node; - - /* The next node in the queue. */ - struct xml_file_queue *next; -} *xml_file_queue_p; - -/* Dump control structure. A pointer one instance of this is passed - to nearly every function. */ -typedef struct xml_dump_info -{ - /* Output file stream of dump. */ - FILE* file; - - /* Which pass of the loop we are doing (1=complete or 0=incomplete). */ - int require_complete; - - /* Next available index to identify node. */ - unsigned int next_index; - - /* The first node in the queue of complete nodes. */ - xml_dump_queue_p queue; - - /* The last node in the queue of complete nodes. */ - xml_dump_queue_p queue_end; - - /* List of free xml_dump_queue nodes. */ - xml_dump_queue_p queue_free; - - /* All nodes that have been encountered. */ - splay_tree dump_nodes; - - /* Index of the next available file queue position. */ - unsigned int file_index; - - /* The first file in the queue of filenames. */ - xml_file_queue_p file_queue; - - /* The last file in the queue of filenames. */ - xml_file_queue_p file_queue_end; - - /* All files that have been queued. */ - splay_tree file_nodes; -} *xml_dump_info_p; - -/*--------------------------------------------------------------------------*/ -/* Data structures for generating documentation. */ - -typedef struct xml_document_subelement_s xml_document_subelement; -typedef struct xml_document_attribute_s xml_document_attribute; -typedef struct xml_document_element_s xml_document_element; -typedef struct xml_document_info_s xml_document_info; -typedef xml_document_subelement* xml_document_subelement_p; -typedef xml_document_attribute* xml_document_attribute_p; -typedef xml_document_element* xml_document_element_p; -typedef xml_document_info* xml_document_info_p; - -/* Maximum document specification sizes. */ -enum { xml_document_max_elements = 256, - xml_document_max_attributes = 64, - xml_document_max_subelements = 256 }; - -/* Document format types. */ -typedef enum xml_document_format_e -{ xml_document_format_dtd, - xml_document_format_schema -} xml_document_format; - -/* The modes of attribute use. */ -typedef enum xml_document_attribute_use_e -{ xml_document_attribute_use_optional, - xml_document_attribute_use_required -} xml_document_attribute_use; -static const char* xml_document_dtd_uses[] = {"IMPLIED", "REQUIRED"}; -static const char* xml_document_schema_uses[] = {"optional", "required"}; - -/* The set of attribute types. */ -typedef enum xml_document_attribute_type_e -{ xml_document_attribute_type_id, - xml_document_attribute_type_idref, - xml_document_attribute_type_idrefs, - xml_document_attribute_type_integer, - xml_document_attribute_type_boolean, - xml_document_attribute_type_string, - xml_document_attribute_type_enum_access -} xml_document_attribute_type; -static const char* xml_document_dtd_types[] = -{"ID", "IDREF", "IDREFS", "CDATA", "CDATA", "CDATA", - "(public|protected|private)"}; -static const char* xml_document_schema_types[] = -{"xs:ID", "xs:IDREF", "xs:IDREFS", "xs:integer", "xs:boolean", "xs:string", - "????"}; - -/* Represent one element attribute. */ -struct xml_document_attribute_s -{ - /* The name of the attribute. */ - const char* name; - - /* The type of the attribute. */ - xml_document_attribute_type type; - - /* Usage requirements in the containing element (optional, required). */ - xml_document_attribute_use use; - - /* The value of the attribute, if any. When the usage is required - this specifies the required value. When the usage is optional - this specifies the default value. */ - const char* value; -}; - -/* Represent a reference to a nested element. */ -struct xml_document_subelement_s -{ - /* The element that may be nested. */ - xml_document_element_p element; - - /* Whether the subelement is required to be present (at least once). */ - int required; - - /* Whether the subelement is allowed to be repeated (more than once). */ - int repeatable; -}; - -/* Represent an element specification. */ -struct xml_document_element_s -{ - /* The name of the element. */ - const char* name; - - /* The attribute specification. */ - int num_attributes; - xml_document_attribute attributes[xml_document_max_attributes]; - - /* The subelement specification. */ - int num_subelements; - xml_document_subelement subelements[xml_document_max_subelements]; -}; - -/* Represent a full document specification. */ -struct xml_document_info_s -{ - /* The set of allowed elements. The first one is the root which - references the others. */ - int num_elements; - xml_document_element elements[xml_document_max_elements]; - - /* The format of the documentation to be generated. */ - xml_document_format format; - - /* Output file stream for document. */ - FILE* file; -}; - -static void -xml_document_add_attribute(xml_document_element_p element, - const char* name, - xml_document_attribute_type type, - xml_document_attribute_use use, - const char* value) -{ - xml_document_attribute_p attribute = - &element->attributes[element->num_attributes++]; - attribute->name = name; - attribute->type = type; - attribute->use = use; - attribute->value = value; -} - -static xml_document_element_p -xml_document_add_subelement(xml_document_info_p xdi, - xml_document_element_p parent, - int required, int repeatable) -{ - xml_document_element_p element = &xdi->elements[xdi->num_elements++]; - xml_document_subelement_p subelement = - &parent->subelements[parent->num_subelements++]; - subelement->element = element; - subelement->required = required; - subelement->repeatable = repeatable; - return element; -} - -/*--------------------------------------------------------------------------*/ -/* Dump utility declarations. */ - -/* Return non-zero if the given _DECL is an internally generated decl. */ -#define DECL_INTERNAL_P(d) (DECL_SOURCE_LINE(d) == 0) - -void do_xml_output PARAMS ((const char*)); -void do_xml_document PARAMS ((const char*, const char*)); - -static int xml_add_node PARAMS((xml_dump_info_p, tree, int)); -static void xml_dump PARAMS((xml_dump_info_p)); -static int xml_queue_incomplete_dump_nodes PARAMS((splay_tree_node, void*)); -static void xml_dump_tree_node PARAMS((xml_dump_info_p, tree, xml_dump_node_p)); -static void xml_dump_files PARAMS((xml_dump_info_p)); - -static void xml_add_start_nodes PARAMS((xml_dump_info_p, const char*)); - -static const char* xml_get_encoded_string PARAMS ((tree)); -static const char* xml_get_encoded_string_from_string PARAMS ((const char*)); -static tree xml_get_encoded_identifier_from_string PARAMS ((const char*)); -static const char* xml_escape_string PARAMS ((const char* in_str)); - -#if defined(GCC_XML_GCC_VERSION) && (GCC_XML_GCC_VERSION >= 0x030100) -# include "diagnostic.h" -#else -extern int errorcount; -#endif - -/* Switch to 1 to enable debugging of dump node selection. */ -#if 0 -# define xml_add_node(xdi, node, complete) \ - (fprintf(stderr, "Adding node at line %d\n", __LINE__), \ - xml_add_node(xdi, node, complete)) -#endif - -/* Get the revision number of this source file. */ -const char* xml_get_xml_c_version() -{ - const char* revision = GCC_XML_C_VERSION; - char* version = (char*)xmalloc(strlen(revision)+1); - const char* in=revision; - char* out = version; - while(*in && *in != ':') { ++in; } - if(*in) { ++in; } - while(*in && *in == ' ') { ++in; } - while(*in && *in != ' ' && *in != '$') - { - *out++ = *in++; - } - *out = 0; - return version; -} - -/* Main XML output function. Called by parser at the end of a translation - unit. Walk the entire translation unit starting at the global - namespace. Output all declarations. */ -void -do_xml_output (const char* filename) -{ - FILE* file; - struct xml_dump_info xdi; - - /* Do not dump if errors occurred during parsing. */ - if(errorcount) - { - /* Delete any existing output file. */ - unlink(filename); - return; - } - - /* Open the XML output file. */ - file = fopen (filename, "w"); - if (!file) - { - XML_CP_ERROR ("could not open xml-dump file `%s'", filename); - return; - } - - /* Prepare dump. */ - xdi.file = file; - xdi.queue = 0; - xdi.queue_end = 0; - xdi.queue_free = 0; - xdi.next_index = 1; - xdi.dump_nodes = splay_tree_new (splay_tree_compare_pointers, 0, - (splay_tree_delete_value_fn) &free); - xdi.file_queue = 0; - xdi.file_queue_end = 0; - xdi.file_index = 0; - xdi.file_nodes = splay_tree_new (splay_tree_compare_pointers, 0, 0); - xdi.require_complete = 1; - - /* Add the starting nodes for the dump. */ - if (flag_xml_start) - { - /* Use the specified starting locations. */ - xml_add_start_nodes (&xdi, flag_xml_start); - } - else - { - /* No start specified. Use global namespace. */ - xml_add_node (&xdi, global_namespace, 1); - - /* Also add std namespace because it is not always referenced. */ - if(std_node) - { - xml_add_node (&xdi, std_node, 1); - } - } - - /* Start dump. */ - fprintf (file, "\n"); - fprintf (file, "\n"); - - /* Dump the complete nodes. */ - xml_dump (&xdi); - - /* Queue all the incomplete nodes. */ - splay_tree_foreach (xdi.dump_nodes, - &xml_queue_incomplete_dump_nodes, &xdi); - - /* Dump the incomplete nodes. */ - xdi.require_complete = 0; - xml_dump (&xdi); - - /* Dump the filename queue. */ - xml_dump_files (&xdi); - - /* Finish dump. */ - fprintf (file, "\n"); - - /* Clean up. */ - { - xml_dump_queue_p dq = xdi.queue_free; - while(dq) - { - xml_dump_queue_p nq = dq->next; - free(dq); - dq = nq; - } - } - splay_tree_delete (xdi.dump_nodes); - splay_tree_delete (xdi.file_nodes); - fclose (file); -} - -/* Return the xml_dump_node corresponding to tree node T. If none exists, - one will be created with an index of 0. */ -static xml_dump_node_p -xml_get_dump_node(xml_dump_info_p xdi, tree t) -{ - /* See if the node has already been inserted. */ - splay_tree_node n = splay_tree_lookup (xdi->dump_nodes, (splay_tree_key) t); - if(!n) - { - /* Need to add the node, create it. */ - xml_dump_node_p v = - (xml_dump_node_p) xmalloc (sizeof (struct xml_dump_node)); - - /* Initialize it. */ - v->index = 0; - v->complete = 0; - - /* Insert the node. */ - n = splay_tree_insert (xdi->dump_nodes, (splay_tree_key) t, - (splay_tree_value) v); - } - - /* Return a pointer to the dump node. */ - return (xml_dump_node_p)n->value; -} - -/* Queue the given tree node for output as a complete node. */ -static void -xml_queue_node (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - xml_dump_queue_p dq; - - /* Obtain a new queue node. */ - if (xdi->queue_free) - { - dq = xdi->queue_free; - xdi->queue_free = dq->next; - } - else - { - dq = (xml_dump_queue_p) xmalloc (sizeof (struct xml_dump_queue)); - } - - /* Point the queue node at its corresponding tree node and dump node. */ - dq->next = 0; - dq->tree_node = t; - dq->dump_node = dn; - - /* Add it to the end of the queue. */ - if (!xdi->queue_end) - { - xdi->queue = dq; - } - else - { - xdi->queue_end->next = dq; - } - xdi->queue_end = dq; -} - -/* Add tree node N to those encountered. Return its index. */ -static int -xml_add_node_real (xml_dump_info_p xdi, tree n, int complete) -{ - /* Get the dump node for this tree node. */ - xml_dump_node_p dn = xml_get_dump_node (xdi, n); - if (dn->index) - { - /* Node was already encountered. See if it is now complete. */ - if(complete && !dn->complete) - { - /* Node is now complete, but wasn't before. Queue it. */ - dn->complete = 1; - xml_queue_node (xdi, n, dn); - } - /* Return node's index. */ - return dn->index; - } - - /* This is a new node. Assign it an index. */ - dn->index = xdi->next_index++; - dn->complete = complete; - if(complete || !xdi->require_complete) - { - /* Node is complete. Queue it. */ - xml_queue_node (xdi, n, dn); - } - - if(!xdi->require_complete && complete) - { - XML_CP_ERROR ("XML dump bug: complete node added during incomplete phase.\n"); - } - - /* Return node's index. */ - return dn->index; -} - -/* Called for each node in the splay tree of dump nodes. Queues - a dump node if it is incomplete. */ -int xml_queue_incomplete_dump_nodes (splay_tree_node n, void* in_xdi) -{ - tree key = (tree)n->key; - xml_dump_node_p dn = (xml_dump_node_p)n->value; - xml_dump_info_p xdi = (xml_dump_info_p)in_xdi; - if (!dn->complete) - { - xml_queue_node (xdi, key, dn); - } - return 0; -} - -/* The xml dump loop. */ -void -xml_dump (xml_dump_info_p xdi) -{ - /* Dump the complete nodes. */ - while(xdi->queue) - { - /* Get the next queue entry. */ - xml_dump_queue_p dq = xdi->queue; - tree t = dq->tree_node; - xml_dump_node_p dn = dq->dump_node; - - /* Remove the entry from the queue. */ - xdi->queue = dq->next; - if(!xdi->queue) - { - xdi->queue_end = 0; - } - - /* Put the entry on the free list. */ - dq->next = xdi->queue_free; - xdi->queue_free = dq; - - /* Dump the node. */ - xml_dump_tree_node(xdi, t, dn); - } -} - -/* Queue a filename for later output. If the file has already been - queued, it is not queued again. In either case, the queue index - assigned to the file is returned. */ -static unsigned int -xml_queue_file (xml_dump_info_p xdi, const char* filename) -{ - tree t = xml_get_encoded_identifier_from_string (filename); - - /* See if we've already queued this file. */ - splay_tree_node n = splay_tree_lookup (xdi->file_nodes, (splay_tree_key) t); - if (n) - { - /* File was already queued. Return its index. */ - return n->value; - } - else - { - /* File needs to be queued. */ - xml_file_queue_p fq; - - /* Assign the next available index. */ - unsigned int index = xdi->file_index++; - - /* Obtain a new queue node. */ - fq = (xml_file_queue_p) xmalloc (sizeof (struct xml_file_queue)); - - /* Create a new entry in the splay-tree. */ - fq->tree_node = splay_tree_insert (xdi->file_nodes, (splay_tree_key) t, - (splay_tree_value) index); - - /* Add it to the end of the queue. */ - fq->next = 0; - if (!xdi->file_queue_end) - { - xdi->file_queue = fq; - } - else - { - xdi->file_queue_end->next = fq; - } - xdi->file_queue_end = fq; - - /* Return the index. */ - return index; - } -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attributes location="fid:line" file="fid" line="line" - for the given decl. */ -static void -xml_print_location_attribute (xml_dump_info_p xdi, tree d) -{ - unsigned int source_file = xml_queue_file (xdi, DECL_SOURCE_FILE (d)); - unsigned int source_line = DECL_SOURCE_LINE (d); - - fprintf (xdi->file, " location=\"f%d:%d\" file=\"f%d\" line=\"%d\"", - source_file, source_line, source_file, source_line); -} - -static void -xml_document_add_attribute_location(xml_document_element_p element, - xml_document_attribute_use use) -{ - xml_document_add_attribute(element, "location", - xml_document_attribute_type_string, - xml_document_attribute_use_optional, 0); - xml_document_add_attribute(element, "file", - xml_document_attribute_type_string, use, 0); - xml_document_add_attribute(element, "line", - xml_document_attribute_type_integer, use, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute endline="line" for the given COMPOUND_STMT. */ -static void -xml_print_endline_attribute (xml_dump_info_p xdi, tree stmt) -{ - fprintf (xdi->file, " endline=\"%d\"", STMT_LINENO(stmt)); -} - -static void -xml_document_add_attribute_endline(xml_document_element_p element, - xml_document_attribute_use use) -{ - xml_document_add_attribute(element, "endline", - xml_document_attribute_type_integer, use, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute id="..." for the given node. */ -static void -xml_print_id_attribute (xml_dump_info_p xdi, xml_dump_node_p dn) -{ - fprintf (xdi->file, " id=\"_%d\"", dn->index); -} - -static void -xml_document_add_attribute_id(xml_document_element_p element) -{ - xml_document_add_attribute(element, "id", - xml_document_attribute_type_id, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute name="..." for the given node. */ -static void -xml_print_name_attribute (xml_dump_info_p xdi, tree n) -{ - const char* name = xml_get_encoded_string (n); - fprintf (xdi->file, " name=\"%s\"", name); -} - -static void -xml_document_add_attribute_name(xml_document_element_p element, - xml_document_attribute_use use) -{ - xml_document_add_attribute(element, "name", - xml_document_attribute_type_string, use, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute mangled="..." for the given node. */ -static void -xml_print_mangled_attribute (xml_dump_info_p xdi, tree n) -{ - if (DECL_NAME (n) && - DECL_ASSEMBLER_NAME (n) && - DECL_ASSEMBLER_NAME (n) != DECL_NAME (n)) - { - const char* name = xml_get_encoded_string (DECL_ASSEMBLER_NAME (n)); - fprintf (xdi->file, " mangled=\"%s\"", name); - } -} - -static void -xml_document_add_attribute_mangled(xml_document_element_p element) -{ - xml_document_add_attribute(element, "mangled", - xml_document_attribute_type_string, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute demangled="..." for the given node. */ -static void -xml_print_demangled_attribute (xml_dump_info_p xdi, tree n) -{ - if (DECL_NAME (n) && - DECL_ASSEMBLER_NAME (n) && - DECL_ASSEMBLER_NAME (n) != DECL_NAME (n)) - { - const char* INTERNAL = " *INTERNAL* "; - const int demangle_opt = DMGL_STYLE_MASK | DMGL_PARAMS | DMGL_TYPES; - - const char* name = xml_get_encoded_string (DECL_ASSEMBLER_NAME (n)); - /*demangled name*/ - char* dename = 0; - /*duplicated name, used to remove " *INTERNAL* " if found*/ - char* dupl_name = 0; - /*pointer to found " *INTERNAL* " string*/ - char* internal_found = 0; - - dupl_name = (char*)xmalloc(strlen(name)+1); - strcpy(dupl_name, name); - - internal_found = strstr( dupl_name, INTERNAL ); - if(internal_found) - { - *internal_found = '\0'; - } - - dename = cplus_demangle(dupl_name, demangle_opt); - if(dename) - { - const char* encoded_dename = xml_escape_string(dename); - fprintf (xdi->file, " demangled=\"%s\"", encoded_dename); - } - free(dupl_name); - } -} - -static void -xml_document_add_attribute_demangled(xml_document_element_p element) -{ - xml_document_add_attribute(element, "demangled", - xml_document_attribute_type_string, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute mutable="..." for the given node. */ -static void -xml_print_mutable_attribute (xml_dump_info_p xdi, tree n) -{ - if (DECL_MUTABLE_P (n)) - { - fprintf (xdi->file, " mutable=\"1\""); - } -} - -static void -xml_document_add_attribute_mutable(xml_document_element_p element) -{ - xml_document_add_attribute(element, "mutable", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Get the id of the node referenced by the given type after - accounting for the special CvQualifiedType element. This is the id - that should be printed when referencing the type in an IDREF - attribute. The integers to which QC, QV, and QR point are set to 1 - or 0 depending on whether the IDREF should include the const, - volatile, or restrict qualifier. */ -static int -xml_get_idref(xml_dump_info_p xdi, tree t, int complete, - int* qc, int* qv, int* qr) -{ - /* Get the unqualified node for the type. */ - int id = xml_add_node (xdi, TYPE_MAIN_VARIANT(t), complete); - - /* Determine the qualifiers that should be added by the IDREF. */ - *qc = CP_TYPE_CONST_P (t); - *qv = CP_TYPE_VOLATILE_P (t); - *qr = CP_TYPE_RESTRICT_P (t); - - if (TYPE_NAME (t)) - { - /* This type is named by a typedef. */ - int id2 = xml_add_node (xdi, TYPE_NAME(t), complete); - if(id2) - { - /* The IDREF should reference the typedef. */ - id = id2; - - /* The IDREF does not need to include cv-qualifiers that - are contained in the typedef. */ - if(*qc && CP_TYPE_CONST_P (TREE_TYPE (TYPE_NAME (t)))) - { - *qc = 0; - } - if(*qv && CP_TYPE_VOLATILE_P (TREE_TYPE (TYPE_NAME (t)))) - { - *qv = 0; - } - if(*qr && CP_TYPE_RESTRICT_P (TREE_TYPE (TYPE_NAME (t)))) - { - *qr = 0; - } - } - } - return id; -} - -/* Print an attribute value referencing the given type. If the type - has top-level cv-qualifiers, they are appended to the type's id as - single characters (c=const, v=volatile, r=restrict), and a - CvQualifiedType element is generated to create a valid XML - reference. */ -static void -xml_print_type_idref (xml_dump_info_p xdi, tree t, int complete) -{ - /* Add the unqualified node. */ - int qc = 0; - int qv = 0; - int qr = 0; - int id = xml_get_idref(xdi, t, complete, &qc, &qv, &qr); - - /* Check cv-qualificiation. */ - const char* c = qc? "c" : ""; - const char* v = qv? "v" : ""; - const char* r = qr? "r" : ""; - - /* If there are any qualifiers, add the qualified node. */ - if(qc || qv || qr) - { - xml_add_node (xdi, t, complete); - } - - /* Print the reference. */ - fprintf (xdi->file, "_%d%s%s%s", id, c, v, r); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute type="..." for the given type. If the type - has cv-qualifiers, they are appended to the type's id as single - characters (c=const, v=volatile, r=restrict). */ -static void -xml_print_type_attribute (xml_dump_info_p xdi, tree t, int complete) -{ - fprintf (xdi->file, " type=\""); - xml_print_type_idref (xdi, t, complete); - fprintf (xdi->file, "\""); -} - -static void -xml_document_add_attribute_type(xml_document_element_p element) -{ - xml_document_add_attribute(element, "type", - xml_document_attribute_type_idref, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute returns="tid" for the given function type. */ -static void -xml_print_returns_attribute (xml_dump_info_p xdi, tree t, int complete) -{ - fprintf (xdi->file, " returns=\""); - xml_print_type_idref (xdi, t, complete); - fprintf (xdi->file, "\""); -} - -static void -xml_document_add_attribute_returns(xml_document_element_p element) -{ - xml_document_add_attribute(element, "returns", - xml_document_attribute_type_idref, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute basetype="..." with the given type. */ -static void -xml_print_base_type_attribute (xml_dump_info_p xdi, tree t, int complete) -{ - fprintf (xdi->file, " basetype=\"_%d\"", xml_add_node (xdi, t, complete)); -} - -static void -xml_document_add_attribute_base_type(xml_document_element_p element) -{ - xml_document_add_attribute(element, "basetype", - xml_document_attribute_type_idref, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute context="..." for the given node. If the - context is a type also print the XML attribute access="..." for the - given decl. */ -static void -xml_print_context_attribute (xml_dump_info_p xdi, tree n) -{ - if(n != global_namespace) - { - tree context = CP_DECL_CONTEXT (n); - if(context) - { - /* Print the context attribute. */ - fprintf (xdi->file, " context=\"_%d\"", - xml_add_node (xdi, context, 0)); - - /* If the context is a type, print the access attribute. */ - if (TYPE_P(context)) - { - if (TREE_PRIVATE (n)) - { - fprintf (xdi->file, " access=\"private\""); - } - else if (TREE_PROTECTED (n)) - { - fprintf (xdi->file, " access=\"protected\""); - } - else - { - fprintf (xdi->file, " access=\"public\""); - } - } - } - } -} - -static void -xml_document_add_attribute_access(xml_document_element_p element) -{ - xml_document_add_attribute(element, "access", - xml_document_attribute_type_enum_access, - xml_document_attribute_use_optional, "public"); -} - -static void -xml_document_add_attribute_context(xml_document_element_p element, - xml_document_attribute_use use, - int do_access) -{ - xml_document_add_attribute(element, "context", - xml_document_attribute_type_idref, use, 0); - if(do_access) - { - xml_document_add_attribute_access(element); - } -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute explicit="..." for the given decl. */ -static void -xml_print_explicit_attribute (xml_dump_info_p xdi, tree d) -{ - if (DECL_NONCONVERTING_P (d)) - { - fprintf (xdi->file, " explicit=\"1\""); - } -} - -static void -xml_document_add_attribute_explicit(xml_document_element_p element) -{ - xml_document_add_attribute(element, "explicit", - xml_document_attribute_type_integer, - xml_document_attribute_use_optional, "1"); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute size="..." for the given type. */ -static void -xml_print_size_attribute (xml_dump_info_p xdi, tree t) -{ - tree size_tree = TYPE_SIZE (t); - if (size_tree && host_integerp (size_tree, 1)) - { - unsigned HOST_WIDE_INT size = tree_low_cst (size_tree, 1); - fprintf (xdi->file, " size=\"" HOST_WIDE_INT_PRINT_UNSIGNED "\"", size); - } -} - -static void -xml_document_add_attribute_size(xml_document_element_p element) -{ - xml_document_add_attribute(element, "size", - xml_document_attribute_type_integer, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute align="..." for the given type. */ -static void -xml_print_align_attribute (xml_dump_info_p xdi, tree t) -{ - fprintf (xdi->file, " align=\"%d\"", TYPE_ALIGN (t)); -} - -static void -xml_document_add_attribute_align(xml_document_element_p element) -{ - xml_document_add_attribute(element, "align", - xml_document_attribute_type_integer, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute offset="..." for the given decl. */ -static void -xml_print_offset_attribute (xml_dump_info_p xdi, tree d) -{ - tree tree_byte_ofs = DECL_FIELD_OFFSET(d); - tree tree_bit_ofs = DECL_FIELD_BIT_OFFSET(d); - if (tree_byte_ofs && host_integerp(tree_byte_ofs, 1) && - tree_bit_ofs && host_integerp(tree_bit_ofs, 1)) - { - unsigned HOST_WIDE_INT bit_ofs = tree_low_cst (tree_bit_ofs, 1); - unsigned HOST_WIDE_INT byte_ofs = tree_low_cst (tree_byte_ofs, 1); - fprintf(xdi->file, " offset=\"" HOST_WIDE_INT_PRINT_UNSIGNED "\"", - byte_ofs * 8 + bit_ofs); - } -} - -static void -xml_document_add_attribute_offset(xml_document_element_p element) -{ - xml_document_add_attribute(element, "offset", - xml_document_attribute_type_integer, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute const="1" for const methods. */ -static void -xml_print_const_method_attribute (xml_dump_info_p xdi, tree fd) -{ - if (DECL_CONST_MEMFUNC_P (fd)) - { - fprintf (xdi->file, " const=\"1\""); - } -} - -static void -xml_document_add_attribute_const_method(xml_document_element_p element) -{ - xml_document_add_attribute(element, "const", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute static="1" for static methods. */ -static void -xml_print_static_method_attribute (xml_dump_info_p xdi, tree fd) -{ - if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (fd)) - { - fprintf (xdi->file, " static=\"1\""); - } -} - -static void -xml_document_add_attribute_static_method(xml_document_element_p element) -{ - xml_document_add_attribute(element, "static", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attributes virtual="" and pure_virtual="" for a decl. */ -static void -xml_print_virtual_method_attributes (xml_dump_info_p xdi, tree d) -{ - if (DECL_VIRTUAL_P (d)) - { - fprintf (xdi->file, " virtual=\"1\""); - } - - if (DECL_PURE_VIRTUAL_P (d)) - { - fprintf (xdi->file, " pure_virtual=\"1\""); - } -} - -static void -xml_document_add_attribute_virtual_method(xml_document_element_p element) -{ - xml_document_add_attribute(element, "virtual", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); - xml_document_add_attribute(element, "pure_virtual", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute extern="1" if the given decl is external. */ -static void -xml_print_extern_attribute (xml_dump_info_p xdi, tree d) -{ - if (DECL_EXTERNAL (d)) - { - fprintf (xdi->file, " extern=\"1\""); - } -} - -static void -xml_document_add_attribute_extern(xml_document_element_p element) -{ - xml_document_add_attribute(element, "extern", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute inline="1" if the given decl is inline. */ -static void -xml_print_inline_attribute (xml_dump_info_p xdi, tree d) -{ - if (DECL_DECLARED_INLINE_P (d)) - { - fprintf (xdi->file, " inline=\"1\""); - } -} - -static void -xml_document_add_attribute_inline(xml_document_element_p element) -{ - xml_document_add_attribute(element, "inline", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute extern="1" if the given decl is external. */ -static void -xml_print_function_extern_attribute (xml_dump_info_p xdi, tree fd) -{ - if (DECL_REALLY_EXTERN (fd)) - { - fprintf (xdi->file, " extern=\"1\""); - } -} - -static void -xml_document_add_attribute_function_extern(xml_document_element_p element) -{ - xml_document_add_attribute(element, "extern", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute for a default argument. */ -static void -xml_print_default_argument_attribute (xml_dump_info_p xdi, tree t) -{ - const char* value; - - switch (TREE_CODE(t)) - { - case CAST_EXPR: - value = xml_get_encoded_string_from_string (""); - break; - default: - value = xml_get_encoded_string_from_string (expr_as_string (t, 0)); - break; - }; - fprintf (xdi->file, " default=\"%s\"", value); -} - -static void -xml_document_add_attribute_default_argument(xml_document_element_p element, - xml_document_attribute_use use) -{ - xml_document_add_attribute(element, "default", - xml_document_attribute_type_string, use, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute init="..." for a variable initializer. */ -static void -xml_print_init_attribute (xml_dump_info_p xdi, tree t) -{ - const char* value; - - if (!t || (t == error_mark_node)) return; - -#if defined(GCC_XML_GCC_VERSION) && (GCC_XML_GCC_VERSION >= 0x030300) - /* GCC 3.3 uses a constructor to initialize a list of elements. */ - if (TREE_CODE (t) == CONSTRUCTOR) - { - tree elt; - const char* comma = ""; - fprintf (xdi->file, " init=\"{"); - for(elt = CONSTRUCTOR_ELTS (t); elt; elt = TREE_CHAIN (elt)) - { - value = xml_get_encoded_string_from_string ( - expr_as_string (TREE_VALUE(elt), 0)); - fprintf (xdi->file, "%s%s", comma, value); - comma = ", "; - } - fprintf (xdi->file, "}\""); - return; - } -#endif - - value = xml_get_encoded_string_from_string (expr_as_string (t, 0)); - fprintf (xdi->file, " init=\"%s\"", value); -} - -static void -xml_document_add_attribute_init(xml_document_element_p element) -{ - xml_document_add_attribute(element, "init", - xml_document_attribute_type_string, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute incomplete="..." for the given type. */ -static void -xml_print_incomplete_attribute (xml_dump_info_p xdi, tree t) -{ - if (!COMPLETE_TYPE_P (t)) - { - fprintf (xdi->file, " incomplete=\"1\""); - } -} - -static void -xml_document_add_attribute_incomplete(xml_document_element_p element) -{ - xml_document_add_attribute(element, "init", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute abstract="..." for the given type. */ -static void -xml_print_abstract_attribute (xml_dump_info_p xdi, tree t) -{ - if (CLASSTYPE_PURE_VIRTUALS (t) != 0) - { - fprintf (xdi->file, " abstract=\"1\""); - } -} - -static void -xml_document_add_attribute_abstract(xml_document_element_p element) -{ - xml_document_add_attribute(element, "abstract", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML empty tag for an ellipsis at the end of an argument list. */ -static void -xml_output_ellipsis (xml_dump_info_p xdi) -{ - fprintf (xdi->file, - " \n"); -} - -static void -xml_document_add_element_ellipsis (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 0); - e->name = "Ellipsis"; -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attributes min="0" max="..." for an array type. */ -static void -xml_print_array_attributes (xml_dump_info_p xdi, tree at) -{ - const char* length = ""; - - if (TYPE_DOMAIN (at)) - length = xml_get_encoded_string_from_string ( - expr_as_string (TYPE_MAX_VALUE (TYPE_DOMAIN (at)), 0)); - - fprintf (xdi->file, " min=\"0\" max=\"%s\"", length); -} - -static void -xml_document_add_attribute_array(xml_document_element_p element) -{ - xml_document_add_attribute(element, "min", - xml_document_attribute_type_integer, - xml_document_attribute_use_required, "0"); - xml_document_add_attribute(element, "max", - xml_document_attribute_type_integer, - xml_document_attribute_use_required, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute listing types that this type can throw. */ -static void -xml_print_throw_attribute (xml_dump_info_p xdi, tree ft, int complete) -{ - tree raises = TYPE_RAISES_EXCEPTIONS (ft); - if(raises) - { - fprintf (xdi->file, " throw=\""); - if(TREE_VALUE (raises)) - { - for (; - raises != NULL_TREE; raises = TREE_CHAIN (raises)) - { - fprintf (xdi->file, "%s", - (raises == TYPE_RAISES_EXCEPTIONS (ft))?"":" "); - xml_print_type_idref (xdi, TREE_VALUE (raises), complete); - } - } - fprintf (xdi->file, "\""); - } -} - -static void -xml_document_add_attribute_throw(xml_document_element_p element) -{ - xml_document_add_attribute(element, "throw", - xml_document_attribute_type_idrefs, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Given an attribute node, set "arg" to the string value of the first - argument, and return the first argument node. */ -tree xml_get_first_attrib_arg(tree attrib_node, char** arg) -{ - /* This function contributed by Steven Kilthau - May 2004. */ - tree arg_node = TREE_VALUE (attrib_node); - *arg = ""; - if (arg_node && (TREE_CODE (arg_node) == TREE_LIST)) - { - tree cst = TREE_VALUE (arg_node); - if (TREE_CODE (cst) == STRING_CST) - { - *arg = TREE_STRING_POINTER (cst); - } - return arg_node; - } - return 0; -} - -/* Given an argument node, set "arg" to the string value of the next - argument, and return the next argument node. */ -tree xml_get_next_attrib_arg(tree arg_node, char** arg) -{ - /* This function contributed by Steven Kilthau - May 2004. */ - arg_node = TREE_CHAIN (arg_node); - *arg = ""; - if (arg_node && (TREE_CODE (arg_node) == TREE_LIST)) - { - tree cst = TREE_VALUE (arg_node); - if (TREE_CODE (cst) == STRING_CST) - { - *arg = TREE_STRING_POINTER (cst); - } - return arg_node; - } - return 0; -} - -/* Print XML attribute listing the contents of the __attribute__ node - given. */ -static void -xml_print_attributes_attribute (xml_dump_info_p xdi, tree attributes1, - tree attributes2) -{ - if(attributes1 || attributes2) - { - const char* space = ""; - tree attribute; - tree arg_node; - char* arg; - fprintf(xdi->file, " attributes=\""); - for(attribute = attributes1; attribute; - attribute = TREE_CHAIN(attribute)) - { - fprintf(xdi->file, "%s%s", space, - xml_get_encoded_string(TREE_PURPOSE (attribute))); - space = " "; - - /* Format and print the string arguments to the attribute - (contributed by Steven Kilthau - May 2004). */ - if ((arg_node = xml_get_first_attrib_arg(attribute, &arg)) != 0) - { - fprintf(xdi->file, "(%s", xml_get_encoded_string_from_string(arg)); - while((arg_node = xml_get_next_attrib_arg(arg_node, &arg)) != 0) - { - fprintf(xdi->file, ",%s", xml_get_encoded_string_from_string(arg)); - } - fprintf(xdi->file, ")"); - } - } - for(attribute = attributes2; attribute; - attribute = TREE_CHAIN(attribute)) - { - fprintf(xdi->file, "%s%s", space, - xml_get_encoded_string(TREE_PURPOSE (attribute))); - space = " "; - - /* Format and print the string arguments to the attribute - (contributed by Steven Kilthau - May 2004). */ - if ((arg_node = xml_get_first_attrib_arg(attribute, &arg)) != 0) - { - fprintf(xdi->file, "(%s", xml_get_encoded_string_from_string(arg)); - while((arg_node = xml_get_next_attrib_arg(arg_node, &arg)) != 0) - { - fprintf(xdi->file, ",%s", xml_get_encoded_string_from_string(arg)); - } - fprintf(xdi->file, ")"); - } - } - fprintf(xdi->file, "\""); - } -} - -static void -xml_document_add_attribute_attributes(xml_document_element_p element) -{ - xml_document_add_attribute(element, "attributes", - xml_document_attribute_type_string, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML attribute artificial="1" for compiler generated methods. */ -static void -xml_print_artificial_attribute(xml_dump_info_p xdi, tree d) -{ - if (DECL_ARTIFICIAL (d)) - { - fprintf (xdi->file, " artificial=\"1\""); - } -} - -static void -xml_document_add_attribute_artificial(xml_document_element_p element) -{ - xml_document_add_attribute(element, "artificial", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute bits="..." for a bitfield. */ -static void -xml_print_bits_attribute (xml_dump_info_p xdi, tree d) -{ - if (DECL_BIT_FIELD_TYPE (d)) - { - tree size_tree = DECL_SIZE (d); - - if (size_tree && host_integerp (size_tree, 1)) - { - unsigned HOST_WIDE_INT bits = tree_low_cst(size_tree, 1); - fprintf (xdi->file, " bits=\"" HOST_WIDE_INT_PRINT_UNSIGNED "\"", bits); - } - } -} - -static void -xml_document_add_attribute_bits(xml_document_element_p element) -{ - xml_document_add_attribute(element, "bits", - xml_document_attribute_type_integer, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print the XML attribute befriending="..." for a function or class. */ -static void -xml_print_befriending_attribute (xml_dump_info_p xdi, tree befriending) -{ - int have_befriending = 0; - tree frnd; - for (frnd = befriending ; frnd && !have_befriending ; - frnd = TREE_CHAIN (frnd)) - { - if(TREE_CODE (TREE_VALUE (frnd)) != TEMPLATE_DECL) - { - have_befriending = 1; - } - } - if(have_befriending) - { - const char* sep = ""; - fprintf (xdi->file, " befriending=\""); - for (frnd = befriending ; frnd ; frnd = TREE_CHAIN (frnd)) - { - if(TREE_CODE (TREE_VALUE (frnd)) != TEMPLATE_DECL) - { - fprintf (xdi->file, - "%s_%d", sep, xml_add_node (xdi, TREE_VALUE (frnd), 0)); - sep = " "; - } - } - fprintf (xdi->file, "\""); - } -} - -static void -xml_document_add_attribute_befriending(xml_document_element_p element) -{ - xml_document_add_attribute(element, "befriending", - xml_document_attribute_type_idrefs, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ -/* Print XML empty tag describing an unimplemented TREE_CODE that has been - encountered. */ -static void -xml_output_unimplemented (xml_dump_info_p xdi, tree t, xml_dump_node_p dn, - const char* where) -{ - int tree_code = TREE_CODE (t); - fprintf (xdi->file, " file, " id=\"_%d\"", dn->index); - } - fprintf (xdi->file, " tree_code=\"%d\" tree_code_name=\"%s\" node=\"%p\"", - tree_code, tree_code_name [tree_code], t); - if (where) - { - fprintf (xdi->file, " function=\"%s\"", where); - } - fprintf (xdi->file, "/>\n"); -} - -static void -xml_document_add_element_unimplemented (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Unimplemented"; - xml_document_add_attribute_id(e); - xml_document_add_attribute(e, "tree_code", - xml_document_attribute_type_integer, - xml_document_attribute_use_required, 0); - xml_document_add_attribute(e, "tree_code_name", - xml_document_attribute_type_string, - xml_document_attribute_use_required, 0); - xml_document_add_attribute(e, "node", - xml_document_attribute_type_string, - xml_document_attribute_use_required, 0); - xml_document_add_attribute(e, "function", - xml_document_attribute_type_string, - xml_document_attribute_use_optional, 0); -} - -/*--------------------------------------------------------------------------*/ - -/* Dump a NAMESPACE_DECL. */ -static void -xml_output_namespace_decl (xml_dump_info_p xdi, tree ns, xml_dump_node_p dn) -{ - /* Only walk a real namespace. */ - if (!DECL_NAMESPACE_ALIAS (ns)) - { - fprintf (xdi->file, " complete) - { - tree cur_decl; - fprintf (xdi->file, " members=\""); - for (cur_decl = cp_namespace_decls(ns); cur_decl; - cur_decl = TREE_CHAIN (cur_decl)) - { - if (!DECL_INTERNAL_P (cur_decl)) - { - int id = xml_add_node (xdi, cur_decl, 1); - if (id) - { - fprintf (xdi->file, "_%d ", id); - } - } - } -#if defined(GCC_XML_GCC_VERSION) && (GCC_XML_GCC_VERSION >= 0x030300) - /* Add child namespaces. */ - for (cur_decl = cp_namespace_namespaces(ns); cur_decl; - cur_decl = TREE_CHAIN (cur_decl)) - { - if (!DECL_INTERNAL_P (cur_decl)) - { - int id = xml_add_node (xdi, cur_decl, 1); - if (id) - { - fprintf (xdi->file, "_%d ", id); - } - } - } -#endif - - fprintf (xdi->file, "\""); - } - - xml_print_mangled_attribute (xdi, ns); - xml_print_demangled_attribute (xdi, ns); - fprintf (xdi->file, "/>\n"); - } - /* If it is a namespace alias, just indicate that. */ - else - { - tree real_ns = ns; - /* Find the real namespace. */ - while (DECL_NAMESPACE_ALIAS (real_ns)) - { - real_ns = DECL_NAMESPACE_ALIAS (real_ns); - } - - fprintf (xdi->file, " file, " namespace=\"_%d\"", - xml_add_node (xdi, real_ns, 0)); - xml_print_mangled_attribute (xdi, ns); - xml_print_demangled_attribute (xdi, ns ); - fprintf (xdi->file, "/>\n"); - } -} - -static void -xml_document_add_element_namespace_decl (xml_document_info_p xdi, - xml_document_element_p parent) -{ - { - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Namespace"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 0); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute(e, "members", - xml_document_attribute_type_idrefs, - xml_document_attribute_use_optional, 0); - xml_document_add_attribute_mangled(e); - xml_document_add_attribute_demangled(e); - } - { - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "NamespaceAlias"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 0); - xml_document_add_attribute(e, "namespace", - xml_document_attribute_type_idref, - xml_document_attribute_use_required, 0); - xml_document_add_attribute_mangled(e); - xml_document_add_attribute_demangled(e); - } -} - -/*--------------------------------------------------------------------------*/ -/* Output for a typedef. The name and associated type are output. */ -static void -xml_output_typedef (xml_dump_info_p xdi, tree td, xml_dump_node_p dn) -{ - fprintf (xdi->file, " complete); - } - else - { - xml_print_type_attribute (xdi, TREE_TYPE (td), dn->complete); - } - - xml_print_context_attribute (xdi, td); - xml_print_location_attribute (xdi, td); - - /* Output typedef attributes (contributed by Steven Kilthau - May 2004). */ - if (td) - { - xml_print_attributes_attribute (xdi, GCC_XML_DECL_ATTRIBUTES(td), 0); - } - - fprintf (xdi->file, "/>\n"); -} - -static void -xml_document_add_element_typedef (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Typedef"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_type(e); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 1); - xml_document_add_attribute_location(e, xml_document_attribute_use_required); - xml_document_add_attribute_attributes(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a PARM_DECL / TREE_LIST corresponding to a function argument. */ -static void -xml_output_argument (xml_dump_info_p xdi, tree pd, tree tl, int complete) -{ - /* Don't process any compiler-generated arguments. These occur for - things like constructors of classes with virtual inheritance. */ - if (pd && DECL_ARTIFICIAL (pd)) return; - - fprintf (xdi->file, " file, "/>\n"); -} - -static void -xml_document_add_element_argument (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Argument"; - xml_document_add_attribute_name(e, xml_document_attribute_use_optional); - xml_document_add_attribute_type(e); - xml_document_add_attribute_location(e, xml_document_attribute_use_optional); - xml_document_add_attribute_default_argument( - e, xml_document_attribute_use_optional); - xml_document_add_attribute_attributes(e); -} - -/*--------------------------------------------------------------------------*/ -/* Lookup the real name of an operator whose ansi_opname or ansi_assopname - is NAME. */ -static tree -xml_reverse_opname_lookup (tree name) -{ - static const char* unknown_operator = "{unknown operator}"; - int i; - - /* Make sure we know about this internal name. */ - if (!IDENTIFIER_OPNAME_P (name)) - return get_identifier (unknown_operator); - - /* Search the list of internal anmes */ - for (i=0; i < LAST_CPLUS_TREE_CODE ; ++i) - { - if (ansi_opname(i) == name) - return get_identifier (operator_name_info[i].name); - else if (ansi_assopname(i) == name) - return get_identifier (assignment_operator_name_info[i].name); - } - - return get_identifier (unknown_operator); -} - -/* Output for a FUNCTION_DECL. */ -static void -xml_output_function_decl (xml_dump_info_p xdi, tree fd, xml_dump_node_p dn) -{ - tree arg; - tree arg_type; - const char* tag; - tree name = DECL_NAME (fd); - tree body = DECL_SAVED_TREE(fd); - int do_name = 1; - int do_returns = 0; - int do_const = 0; - int do_virtual = 0; - int do_static = 0; - int do_artificial = 0; - int do_explicit = 0; - - /* Print out the begin tag for this type of function. */ - if (DECL_CONSTRUCTOR_P (fd)) - { - /* A class constructor. */ - tag = "Constructor"; do_artificial = 1; - do_explicit = 1; - if(TYPE_ANONYMOUS_P (DECL_CONTEXT (fd))) - { - do_name = 0; - } - } - else if (DECL_DESTRUCTOR_P (fd)) - { - /* A class destructor. */ - tag = "Destructor"; do_virtual = 1; do_artificial = 1; - } - else if (DECL_OVERLOADED_OPERATOR_P (fd)) - { - if (DECL_CONV_FN_P (fd)) - { - /* A type-conversion operator in a class. */ - tag = "Converter"; - do_returns = 1; do_const = 1; do_virtual = 1; - } - else - { - if (DECL_FUNCTION_MEMBER_P (fd)) - { - /* An operator in a class. */ - tag = "OperatorMethod"; - name = xml_reverse_opname_lookup (DECL_NAME (fd)); - do_returns = 1; do_const = 1; do_virtual = 1; - do_static = 1; - } - else - { - /* An operator in a namespace. */ - tag = "OperatorFunction"; - name = xml_reverse_opname_lookup (DECL_NAME (fd)); - do_returns = 1; - } - } - } - else - { - if (DECL_FUNCTION_MEMBER_P (fd)) - { - /* A member of a class. */ - tag = "Method"; do_returns = 1; do_const = 1; - do_virtual = 1; do_static = 1; - } - else - { - /* A member of a namespace. */ - tag = "Function"; do_returns = 1; - } - } - - fprintf (xdi->file, " <%s", tag); - xml_print_id_attribute (xdi, dn); - if(do_name) - { - xml_print_name_attribute (xdi, name); - } - - if(do_returns) - { - xml_print_returns_attribute (xdi, TREE_TYPE (TREE_TYPE (fd)), dn->complete); - } - if(do_explicit) xml_print_explicit_attribute (xdi, fd); - if(do_const) xml_print_const_method_attribute (xdi, fd); - if(do_virtual) xml_print_virtual_method_attributes (xdi, fd); - if(do_static) xml_print_static_method_attribute (xdi, fd); - if(do_artificial) xml_print_artificial_attribute (xdi, fd); - xml_print_throw_attribute (xdi, TREE_TYPE (fd), dn->complete); - xml_print_context_attribute (xdi, fd); - xml_print_mangled_attribute (xdi, fd); - xml_print_demangled_attribute (xdi, fd); - xml_print_location_attribute (xdi, fd); - if(body) - { - xml_print_endline_attribute (xdi, body); - } - xml_print_function_extern_attribute (xdi, fd); - xml_print_inline_attribute (xdi, fd); - xml_print_attributes_attribute (xdi, GCC_XML_DECL_ATTRIBUTES(fd), - TYPE_ATTRIBUTES(TREE_TYPE(fd))); - xml_print_befriending_attribute (xdi, DECL_BEFRIENDING_CLASSES (fd)); - - /* Prepare to iterator through argument list. */ - arg = DECL_ARGUMENTS (fd); - arg_type = TYPE_ARG_TYPES (TREE_TYPE (fd)); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fd)) - { - /* Skip "this" argument. */ - if(arg) arg = TREE_CHAIN (arg); - arg_type = TREE_CHAIN (arg_type); - } - - /* If there are no arguments, finish the element. */ - if (arg_type == void_list_node) - { - fprintf (xdi->file, "/>\n"); - return; - } - else - { - fprintf (xdi->file, ">\n"); - } - - /* Print out the argument list for this function. */ - while (arg_type && (arg_type != void_list_node)) - { - xml_output_argument (xdi, arg, arg_type, dn->complete); - if(arg) arg = TREE_CHAIN (arg); - arg_type = TREE_CHAIN (arg_type); - } - - if(!arg_type) - { - /* Function has variable number of arguments. Print ellipsis. */ - xml_output_ellipsis (xdi); - } - - fprintf (xdi->file, " \n", tag); -} - -static void -xml_document_add_element_function_helper (xml_document_info_p xdi, - xml_document_element_p parent, - const char* tag, - int do_returns, - int do_access, - int do_const, - int do_virtual, - int do_static, - int do_artificial, - int do_explicit, - int allow_arguments, - int allow_ellipsis) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = tag; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - if(do_returns) - { - xml_document_add_attribute_returns(e); - } - if(do_const) - { - xml_document_add_attribute_const_method(e); - } - if(do_virtual) - { - xml_document_add_attribute_virtual_method(e); - } - if(do_static) - { - xml_document_add_attribute_static_method(e); - } - if(do_artificial) - { - xml_document_add_attribute_artificial(e); - } - if(do_explicit) - { - xml_document_add_attribute_explicit(e); - } - xml_document_add_attribute_throw(e); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - do_access); - xml_document_add_attribute_mangled(e); - xml_document_add_attribute_demangled(e); - xml_document_add_attribute_location(e, xml_document_attribute_use_required); - xml_document_add_attribute_endline(e, xml_document_attribute_use_optional); - xml_document_add_attribute_extern(e); - xml_document_add_attribute_inline(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_befriending(e); - if(allow_arguments) - { - xml_document_add_element_argument (xdi, e); - } - if(allow_ellipsis) - { - xml_document_add_element_ellipsis (xdi, e); - } -} - -static void -xml_document_add_element_function (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_add_element_function_helper( - xdi, parent, "Constructor", /*do_returns*/ 0, /*do_access*/ 1, - /*do_const*/ 0, /*do_virtual*/ 0, /*do_static*/ 0, /*do_artificial*/ 1, - /*do_explicit*/ 1, /*allow_arguments*/ 1, /*allow_ellipsis*/ 1); - xml_document_add_element_function_helper( - xdi, parent, "Destructor", /*do_returns*/ 0, /*do_access*/ 1, - /*do_const*/ 0, /*do_virtual*/ 1, /*do_static*/ 0, /*do_artificial*/ 1, - /*do_explicit*/ 0, /*allow_arguments*/ 0, /*allow_ellipsis*/ 0); - xml_document_add_element_function_helper( - xdi, parent, "Converter", /*do_returns*/ 1, /*do_access*/ 1, - /*do_const*/ 1, /*do_virtual*/ 1, /*do_static*/ 0, /*do_artificial*/ 0, - /*do_explicit*/ 0, /*allow_arguments*/ 0, /*allow_ellipsis*/ 0); - xml_document_add_element_function_helper( - xdi, parent, "OperatorMethod", /*do_returns*/ 1, /*do_access*/ 1, - /*do_const*/ 1, /*do_virtual*/ 1, /*do_static*/ 1, /*do_artificial*/ 0, - /*do_explicit*/ 0, /*allow_arguments*/ 1, /*allow_ellipsis*/ 0); - xml_document_add_element_function_helper( - xdi, parent, "OperatorFunction", /*do_returns*/ 1, /*do_access*/ 0, - /*do_const*/ 0, /*do_virtual*/ 0, /*do_static*/ 0, /*do_artificial*/ 0, - /*do_explicit*/ 0, /*allow_arguments*/ 1, /*allow_ellipsis*/ 0); - xml_document_add_element_function_helper( - xdi, parent, "Method", /*do_returns*/ 1, /*do_access*/ 1, - /*do_const*/ 1, /*do_virtual*/ 1, /*do_static*/ 1, /*do_artificial*/ 0, - /*do_explicit*/ 0, /*allow_arguments*/ 1, /*allow_ellipsis*/ 1); - xml_document_add_element_function_helper( - xdi, parent, "Function", /*do_returns*/ 1, /*do_access*/ 0, - /*do_const*/ 0, /*do_virtual*/ 0, /*do_static*/ 0, /*do_artificial*/ 0, - /*do_explicit*/ 0, /*allow_arguments*/ 1, /*allow_ellipsis*/ 1); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a VAR_DECL. The name and type of the variable are output, - as well as the initializer if it exists. */ -static void -xml_output_var_decl (xml_dump_info_p xdi, tree vd, xml_dump_node_p dn) -{ - tree type = TREE_TYPE (vd); - fprintf (xdi->file, " complete); - xml_print_init_attribute (xdi, DECL_INITIAL (vd)); - xml_print_context_attribute (xdi, vd); - xml_print_mangled_attribute (xdi, vd); - xml_print_demangled_attribute (xdi, vd ); - xml_print_location_attribute (xdi, vd); - xml_print_extern_attribute (xdi, vd); - xml_print_artificial_attribute (xdi, vd); - xml_print_attributes_attribute (xdi, GCC_XML_DECL_ATTRIBUTES(vd), 0); - fprintf (xdi->file, "/>\n"); -} - -static void -xml_document_add_element_var_decl (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Variable"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_type(e); - xml_document_add_attribute_init(e); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 1); - xml_document_add_attribute_mangled(e); - xml_document_add_attribute_demangled(e); - xml_document_add_attribute_location(e, xml_document_attribute_use_required); - xml_document_add_attribute_extern(e); - xml_document_add_attribute_artificial(e); - xml_document_add_attribute_attributes(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a FIELD_DECL. The name and type of the variable are output, - as well as the initializer if it exists. */ -static void -xml_output_field_decl (xml_dump_info_p xdi, tree fd, xml_dump_node_p dn) -{ - fprintf (xdi->file, " complete); - } - else - { - xml_print_type_attribute (xdi, TREE_TYPE (fd), dn->complete); - } - xml_print_offset_attribute (xdi, fd); - xml_print_context_attribute (xdi, fd); - xml_print_mangled_attribute (xdi, fd); - xml_print_demangled_attribute (xdi, fd); - xml_print_mutable_attribute(xdi, fd); - xml_print_location_attribute (xdi, fd); - xml_print_attributes_attribute (xdi, GCC_XML_DECL_ATTRIBUTES(fd), 0); - fprintf (xdi->file, "/>\n"); -} - -static void -xml_document_add_element_field_decl (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Field"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_bits(e); - xml_document_add_attribute_type(e); - xml_document_add_attribute_offset(e); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 1); - xml_document_add_attribute_mangled(e); - xml_document_add_attribute_demangled(e); - xml_document_add_attribute_mutable(e); - xml_document_add_attribute_location(e, xml_document_attribute_use_required); - xml_document_add_attribute_attributes(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output a RECORD_TYPE that is not a pointer-to-member-function. - Prints beginning and ending tags, and all class member declarations - between. Also handles a UNION_TYPE. */ -static void -xml_output_record_type (xml_dump_info_p xdi, tree rt, xml_dump_node_p dn) -{ - int has_bases = 0; - tree field; - tree func; - const char* tag; - - if (TREE_CODE(rt) == RECORD_TYPE) - { - if (CLASSTYPE_DECLARED_CLASS (rt)) { tag = "Class"; } - else { tag = "Struct"; } - } - else { tag = "Union"; } - - fprintf (xdi->file, " <%s", tag); - xml_print_id_attribute (xdi, dn); - if(!TYPE_ANONYMOUS_P (rt)) - { - xml_print_name_attribute (xdi, DECL_NAME (TYPE_NAME (rt))); - } - xml_print_context_attribute (xdi, TYPE_NAME (rt)); - xml_print_abstract_attribute (xdi, rt); - xml_print_incomplete_attribute (xdi, rt); - xml_print_mangled_attribute (xdi, TYPE_NAME (rt)); - xml_print_demangled_attribute (xdi, TYPE_NAME (rt)); - xml_print_location_attribute (xdi, TYPE_NAME (rt)); - xml_print_artificial_attribute (xdi, TYPE_NAME (rt)); - xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(rt), 0); - xml_print_size_attribute (xdi, rt); - xml_print_align_attribute (xdi, rt); - xml_print_befriending_attribute (xdi, CLASSTYPE_BEFRIENDING_CLASSES (rt)); - - if (dn->complete && COMPLETE_TYPE_P (rt)) - { - fprintf (xdi->file, " members=\""); - /* Output all the non-method declarations in the class. */ - for (field = TYPE_FIELDS (rt) ; field ; field = TREE_CHAIN (field)) - { - /* Don't process any internally generated declarations. */ - if (DECL_INTERNAL_P (field)) continue; - - /* Don't process any compiler-generated fields. */ - if (DECL_ARTIFICIAL(field) && !DECL_IMPLICIT_TYPEDEF_P(field)) continue; - - /* A class or struct internally typedefs itself. Don't - output this extra typedef. */ - if (!((TREE_CODE (field) == TYPE_DECL) - && (TREE_TYPE (field) == rt))) - { - int id = xml_add_node (xdi, field, 1); - if (id) - { - fprintf (xdi->file, "_%d ", id); - } - } - } - - /* Output all the method declarations in the class. */ - for (func = TYPE_METHODS (rt) ; func ; func = TREE_CHAIN (func)) - { - int id; - - /* Don't process any internally generated declarations. */ - if (DECL_INTERNAL_P (func)) continue; - - /* Don't process any compiler-generated functions except constructors - and destructors. */ - if (DECL_ARTIFICIAL(func) - && !DECL_CONSTRUCTOR_P (func) - && !DECL_DESTRUCTOR_P (func)) continue; - - /* Don't output the cloned functions. */ - if (DECL_CLONED_FUNCTION_P (func)) continue; - - id = xml_add_node (xdi, func, 1); - if(id) - { - fprintf (xdi->file, "_%d ", id); - } - } - - /* TODO: List member template instantiations as members. */ - - fprintf (xdi->file, "\""); - } - - /* Output all the base classes (compatibility with gccxml 0.6). */ - if (dn->complete && COMPLETE_TYPE_P (rt)) - { - tree binfo = TYPE_BINFO (rt); - tree binfos = BINFO_BASETYPES (binfo); - int n_baselinks = binfos? TREE_VEC_LENGTH (binfos) : 0; -#if !defined (XML_PRE_3_4_TREE_VIA_PUBLIC) - tree accesses = BINFO_BASEACCESSES (binfo); -#endif - int i; - - has_bases = (n_baselinks > 0)? 1:0; - fprintf (xdi->file, " bases=\""); - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (base_binfo) - { - /* Output this base class. Default is public access. */ -#if defined (XML_PRE_3_4_TREE_VIA_PUBLIC) - const char* access = 0; - if (TREE_VIA_PUBLIC (base_binfo)) { access = ""; } - else if (TREE_VIA_PROTECTED (base_binfo)) { access = "protected:"; } - else { access="private:"; } -#else - tree n_access = (accesses ? TREE_VEC_ELT (accesses, i) - : access_public_node); - const char* access = ""; - if (n_access == access_protected_node) { access = "protected:"; } - else if (n_access == access_private_node) { access = "private:"; } -#endif - - fprintf (xdi->file, "%s_%d ", access, - xml_add_node (xdi, BINFO_TYPE (base_binfo), 1)); - } - } - fprintf (xdi->file, "\""); - } - - /* If there were no base classes, end the element now. */ - if(!has_bases) - { - fprintf (xdi->file, "/>\n"); - return; - } - - /* There are base classes. Open the element for nested elements. */ - fprintf (xdi->file, ">\n"); - - /* Output all the base classes. */ - if (dn->complete && COMPLETE_TYPE_P (rt)) - { - tree binfo = TYPE_BINFO (rt); - tree binfos = BINFO_BASETYPES (binfo); - int n_baselinks = binfos? TREE_VEC_LENGTH (binfos) : 0; -#if !defined (XML_PRE_3_4_TREE_VIA_PUBLIC) - tree accesses = BINFO_BASEACCESSES (binfo); -#endif - int i; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (base_binfo) - { - /* Output this base class. Default is public access. */ -#if defined (XML_PRE_3_4_TREE_VIA_PUBLIC) - int is_virtual = TREE_VIA_VIRTUAL (base_binfo)? 1:0; - const char* access = "private"; - if (TREE_VIA_PUBLIC (base_binfo)) { access = "public"; } - else if (TREE_VIA_PROTECTED (base_binfo)) { access = "protected"; } -#else - tree n_access = (accesses ? TREE_VEC_ELT (accesses, i) - : access_public_node); - int is_virtual = 0; - const char* access = "public"; - if (n_access == access_protected_node) { access = "protected"; } - else if (n_access == access_private_node) { access = "private"; } - else if (n_access == access_public_virtual_node) { is_virtual = 1; } - else if (n_access == access_protected_virtual_node) - { access = "protected"; is_virtual = 1; } - else if (n_access == access_private_virtual_node) - { access = "private"; is_virtual = 1; } -#endif - - fprintf (xdi->file, - " \n", - xml_add_node (xdi, BINFO_TYPE (base_binfo), 1), - access, is_virtual, - tree_low_cst (BINFO_OFFSET (base_binfo), 0)); - } - } - } - - fprintf (xdi->file, " \n", tag); -} - -static void -xml_document_add_element_record_type_base (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Base"; - xml_document_add_attribute_type(e); - xml_document_add_attribute_access(e); - xml_document_add_attribute(e, "virtual", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); - xml_document_add_attribute(e, "offset", - xml_document_attribute_type_integer, - xml_document_attribute_use_optional, "0"); -} - -static void -xml_document_add_element_record_type_helper (xml_document_info_p xdi, - xml_document_element_p parent, - const char* tag) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = tag; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_optional); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 1); - xml_document_add_attribute_abstract(e); - xml_document_add_attribute_incomplete(e); - xml_document_add_attribute_mangled(e); - xml_document_add_attribute_demangled(e); - xml_document_add_attribute_location(e, xml_document_attribute_use_required); - xml_document_add_attribute_artificial(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); - xml_document_add_attribute_befriending(e); - xml_document_add_attribute(e, "members", - xml_document_attribute_type_idrefs, - xml_document_attribute_use_optional, 0); - xml_document_add_attribute(e, "bases", - xml_document_attribute_type_string, - xml_document_attribute_use_optional, 0); - xml_document_add_element_record_type_base(xdi, e); -} - -static void -xml_document_add_element_record_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_add_element_record_type_helper(xdi, parent, "Class"); - xml_document_add_element_record_type_helper(xdi, parent, "Struct"); - xml_document_add_element_record_type_helper(xdi, parent, "Union"); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a fundamental type. */ -static void -xml_output_fundamental_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - fprintf (xdi->file, " file, "/>\n"); -} - -static void -xml_document_add_element_fundamental_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "FundamentalType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a FUNCTION_TYPE. */ -static void -xml_output_function_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - tree arg_type; - - fprintf (xdi->file, " complete); - xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(t), 0); - fprintf (xdi->file, ">\n"); - - /* Prepare to iterator through argument list. */ - arg_type = TYPE_ARG_TYPES (t); - - /* Print out the argument list for this function. */ - while (arg_type && (arg_type != void_list_node)) - { - xml_output_argument (xdi, NULL, arg_type, dn->complete); - arg_type = TREE_CHAIN (arg_type); - } - - if(arg_type != void_list_node) - { - /* Function has variable number of arguments. */ - xml_output_ellipsis (xdi); - } - - fprintf (xdi->file, " \n"); -} - -static void -xml_document_add_element_function_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "FunctionType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_returns(e); - xml_document_add_attribute_attributes(e); - xml_document_add_element_argument(xdi, e); - xml_document_add_element_ellipsis(xdi, e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a METHOD_TYPE. */ -static void -xml_output_method_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - tree arg_type; - tree this_type; - - fprintf (xdi->file, " complete); - xml_print_returns_attribute (xdi, TREE_TYPE (t), dn->complete); - xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(t), 0); - - /* Prepare to iterator through argument list. */ - arg_type = TYPE_ARG_TYPES (t); - - /* We need to find out if the implicit argument points to a CV - qualified type. */ - this_type = TREE_TYPE(TREE_VALUE (arg_type)); - if (this_type) - { - if (TYPE_READONLY (this_type)) - { - fprintf (xdi->file, " const=\"1\""); - } - if (TYPE_VOLATILE (this_type)) - { - fprintf (xdi->file, " volatile=\"1\""); - } - } - - fprintf (xdi->file, ">\n"); - - /* Skip "this" argument. */ - arg_type = TREE_CHAIN (arg_type); - - /* Print out the argument list for this method. */ - while (arg_type && (arg_type != void_list_node)) - { - xml_output_argument (xdi, NULL, arg_type, dn->complete); - arg_type = TREE_CHAIN (arg_type); - } - - if(arg_type != void_list_node) - { - /* Method has variable number of arguments. */ - xml_output_ellipsis (xdi); - } - - fprintf (xdi->file, " \n"); -} - -static void -xml_document_add_element_method_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "MethodType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_base_type(e); - xml_document_add_attribute_returns(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute(e, "const", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); - xml_document_add_attribute(e, "volatile", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); - xml_document_add_element_argument(xdi, e); - xml_document_add_element_ellipsis(xdi, e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a POINTER_TYPE. */ -static void -xml_output_pointer_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - fprintf (xdi->file, " file, "/>\n"); -} - -static void -xml_document_add_element_pointer_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "PointerType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_type(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a REFERENCE_TYPE. */ -static void -xml_output_reference_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - fprintf (xdi->file, " file, "/>\n"); -} - -static void -xml_document_add_element_reference_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "ReferenceType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_type(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for an OFFSET_TYPE. */ -static void -xml_output_offset_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - fprintf (xdi->file, " complete); - xml_print_type_attribute (xdi, TREE_TYPE (t), dn->complete); - xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(t), 0); - xml_print_size_attribute (xdi, t); - xml_print_align_attribute (xdi, t); - fprintf (xdi->file, "/>\n"); -} - -static void -xml_document_add_element_offset_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "OffsetType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_base_type(e); - xml_document_add_attribute_type(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for an ARRAY_TYPE. */ -static void -xml_output_array_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - fprintf (xdi->file, " complete); - xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(t), 0); - xml_print_size_attribute (xdi, t); - xml_print_align_attribute (xdi, t); - fprintf (xdi->file, "/>\n"); -} - -static void -xml_document_add_element_array_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "ArrayType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_array(e); - xml_document_add_attribute_type(e); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for an ENUMERAL_TYPE. */ -static void -xml_output_enumeral_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - tree tv; - - fprintf (xdi->file, " file, ">\n"); - - /* Output the list of possible values for the enumeration type. */ - for (tv = TYPE_VALUES (t); tv ; tv = TREE_CHAIN (tv)) - { - if(TREE_CODE (TREE_VALUE (tv)) == INTEGER_CST) - { - int value = TREE_INT_CST_LOW (TREE_VALUE (tv)); - fprintf (xdi->file, - " \n", - xml_get_encoded_string ( TREE_PURPOSE(tv)), value); - } - else - { - fprintf (xdi->file, " "); - xml_output_unimplemented (xdi, TREE_VALUE (tv), 0, - "xml_output_enumeral_type"); - } - } - - fprintf (xdi->file, " \n"); -} - -static void -xml_document_add_element_enum_value (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "EnumValue"; - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_init(e); -} - -static void -xml_document_add_element_enumeral_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "Enumeration"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_name(e, xml_document_attribute_use_required); - xml_document_add_attribute_context(e, xml_document_attribute_use_required, - 1); - xml_document_add_attribute_location(e, xml_document_attribute_use_required); - xml_document_add_attribute_attributes(e); - xml_document_add_attribute_artificial(e); - xml_document_add_attribute_size(e); - xml_document_add_attribute_align(e); - xml_document_add_element_enum_value(xdi, e); - xml_document_add_element_unimplemented(xdi, e); -} - -/*--------------------------------------------------------------------------*/ -/* Output for a cv-qualified type. */ -static void -xml_output_cv_qualified_type (xml_dump_info_p xdi, tree t, xml_dump_node_p dn) -{ - if (t == TYPE_MAIN_VARIANT(t)) - { - switch (TREE_CODE(t)) - { - case UNION_TYPE: - case RECORD_TYPE: - xml_output_record_type (xdi, t, dn); - break; - case ARRAY_TYPE: - xml_output_array_type (xdi, t, dn); - break; - case POINTER_TYPE: - xml_output_pointer_type (xdi, t, dn); - break; - case REFERENCE_TYPE: - xml_output_reference_type (xdi, t, dn); - break; - case FUNCTION_TYPE: - xml_output_function_type (xdi, t, dn); - break; - case METHOD_TYPE: - xml_output_method_type (xdi, t, dn); - break; - case OFFSET_TYPE: - xml_output_offset_type (xdi, t, dn); - break; - case ENUMERAL_TYPE: - xml_output_enumeral_type (xdi, t, dn); - break; - case LANG_TYPE: - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case REAL_TYPE: - case VOID_TYPE: - case COMPLEX_TYPE: - xml_output_fundamental_type (xdi, t, dn); - break; - default: - break; - } - } - else - { - /* Ignore the real index of this node and use the index of the - unqualified version of the node with the extra characters. */ - int qc = 0; - int qv = 0; - int qr = 0; - int id = xml_get_idref(xdi, t, dn->complete, &qc, &qv, &qr); - - const char* c = qc? "c" : ""; - const char* v = qv? "v" : ""; - const char* r = qr? "r" : ""; - - /* If for some reason there are no cv-qualifiers then just do not - output the type. Any reference to it will skip to the - unqualified type anyway. */ - if(!(qc||qv||qr)) - { - return; - } - - /* Create a special CvQualifiedType element to hold top-level - cv-qualifiers for a real type node. */ - fprintf (xdi->file, " file, " id=\"_%d%s%s%s\"", id, c, v, r); - - /* Refer to the unqualified type. */ - fprintf (xdi->file, " type=\"_%d\"", id); - - /* Add the cv-qualification attributes. */ - if (qc) - { - fprintf (xdi->file, " const=\"1\""); - } - if (qv) - { - fprintf (xdi->file, " volatile=\"1\""); - } - if (qr) - { - fprintf (xdi->file, " restrict=\"1\""); - } - fprintf (xdi->file, "/>\n"); - } -} - -static void -xml_document_add_element_cv_qualified_type (xml_document_info_p xdi, - xml_document_element_p parent) -{ - xml_document_element_p e = xml_document_add_subelement(xdi, parent, 0, 1); - e->name = "CvQualifiedType"; - xml_document_add_attribute_id(e); - xml_document_add_attribute_type(e); - xml_document_add_attribute(e, "const", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); - xml_document_add_attribute(e, "volatile", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); - xml_document_add_attribute(e, "restrict", - xml_document_attribute_type_boolean, - xml_document_attribute_use_optional, "0"); -} - -/*--------------------------------------------------------------------------*/ - -/* When a class, struct, or union type is defined, it is automatically - given a member typedef to itself. Given a RECORD_TYPE or - UNION_TYPE, this returns that field's name. Although this should - never happen, 0 is returned when the field cannot be found. */ -static tree -xml_find_self_typedef_name (tree rt) -{ - tree field; - for (field = TYPE_FIELDS (rt) ; field ; field = TREE_CHAIN (field)) - { - /* The field must be artificial because someone could have written - their own typedef of the class's name. */ - if ((TREE_CODE (field) == TYPE_DECL) - && (TREE_TYPE (field) == rt) - && DECL_ARTIFICIAL (field)) - { - return DECL_NAME (field); - } - } - - return 0; -} - -/* Add the given typedef if it really came from user code. */ -static int -xml_add_typedef (xml_dump_info_p xdi, tree td, int complete) -{ - tree t; - - /* If the typedef points to its own name in the same context, ignore - it. */ - if(!DECL_ORIGINAL_TYPE (td) - && TREE_TYPE (td) && TYPE_NAME (TREE_TYPE (td)) - && (DECL_NAME (td) == DECL_NAME (TYPE_NAME (TREE_TYPE (td)))) - && (DECL_CONTEXT (td) == DECL_CONTEXT (TYPE_NAME (TREE_TYPE (td))))) - { - /* Add the node that the typedef references instead. */ - xml_add_node(xdi, TREE_TYPE (td), complete); - return 0; - } - - /* Find the typedef's real target type. */ - if (DECL_ORIGINAL_TYPE (td)) - { - t = DECL_ORIGINAL_TYPE (td); - } - else - { - t = TREE_TYPE (td); - } - - if (TYPE_MAIN_VARIANT (t)) - { - t = TYPE_MAIN_VARIANT (t); - } - - /* Only add the typedef if its target will be dumped. */ - if (xml_add_node (xdi, t, complete)) - { - return xml_add_node_real (xdi, td, complete); - } - else - { - return 0; - } -} - -/* Dispatch output of a TYPE_DECL. This is either a typedef, or a new - type (class/struct/union) definition. */ -static int -xml_add_type_decl (xml_dump_info_p xdi, tree td, int complete) -{ - /* Get the type from the TYPE_DECL. We don't want to use complete_type - because it may modify something. We are doing a read-only dump. */ - tree t = TREE_TYPE (td); - - switch (TREE_CODE (t)) - { - case ARRAY_TYPE: - case LANG_TYPE: - case POINTER_TYPE: - case REFERENCE_TYPE: - case INTEGER_TYPE: - case VOID_TYPE: - case BOOLEAN_TYPE: - case REAL_TYPE: - case COMPLEX_TYPE: - case FUNCTION_TYPE: - case TYPENAME_TYPE: - case TEMPLATE_TYPE_PARM: - /* A typedef to a predefined type. */ - return xml_add_typedef (xdi, td, complete); - break; - case ENUMERAL_TYPE: - case UNION_TYPE: - case RECORD_TYPE: - if ((TREE_CODE (t) == RECORD_TYPE) && TYPE_PTRMEMFUNC_P (t)) - { - /* A typedef to a pointer to member. */ - return xml_add_typedef (xdi, td, complete); - } - /* This is a complicated test to tell apart a real class declaration - or definition from a typedef to it. This must be able to detect - the difference for the following cases: - - Code: Meaning: - 1. struct A {}; "struct A" - 2. struct A {}; typedef A B; "struct A" "typedef A B" - 3. typedef struct {} A; "struct A" - 4. typedef struct A {} B; "struct A" "typedef A B" - 5. typedef struct A {} A; "struct A" - 6. struct A {}; typedef struct A A; "struct A" - - DECL_IMPLICIT_TYPEDEF_P will recognize the TYPE_DECL that - points to the real class definition for cases 1, 2, 3, and 4, - and is sufficient to make the decision. - - For cases 5 and 6, the second test makes sure the context of - the TYPE_DECL matches the context of the RECORD_TYPE, which - can only happen for a TYPE_DECL in the same scope as the - class. It then looks at the RECORD_TYPE to find its - artificial member that is a typedef to its own class. The - name of this field is compared to the name of the original - TYPE_DECL. If it matches and the type's TYPE_NAME node is - this TYPE_DECL, then we have found the class's definition. - Otherwise, it is assumed that it is simply a typedef. */ - else if (DECL_IMPLICIT_TYPEDEF_P (td) - || (((DECL_CONTEXT (td) == TYPE_CONTEXT (t)) - && (xml_find_self_typedef_name (t) == DECL_NAME (td)) - && (TYPE_NAME (t) == td)))) - { - /* This is a new class or enumeration type. */ - return xml_add_node (xdi, t, complete); - } - else - { - /* A typedef to an existing class or enumeration type. */ - return xml_add_typedef (xdi, td, complete); - } - break; - default: - { - /* Add the node even though it is unimplemented. */ - return xml_add_node_real (xdi, td, complete); - } - } - return 0; -} - -/* Dump for an OVERLOAD. Dump all the functions in the overload list. */ -static int -xml_add_overload (xml_dump_info_p xdi, tree o, int complete) -{ - tree cur_overload = o; - while (cur_overload) - { - xml_add_node (xdi, OVL_CURRENT (cur_overload), complete); - cur_overload = OVL_NEXT (cur_overload); - } - return 0; -} - -/* Recursively search a type node for template parameters. */ -static int -xml_find_template_parm (tree t) -{ - if(!t) - { - return 0; - } - - switch (TREE_CODE (t)) - { - /* A vector of template arguments on an instantiation. */ - case TREE_VEC: - { - int i; - for(i=0; i < TREE_VEC_LENGTH (t); ++i) - { - if(xml_find_template_parm (TREE_VEC_ELT (t, i))) - { - return 1; - } - } - } break; - - /* A type list has nested types. */ - case TREE_LIST: - { - if(xml_find_template_parm (TREE_PURPOSE (t))) - { - return 1; - } - return xml_find_template_parm (TREE_VALUE (t)); - } break; - - /* Template parameter types. */ - case TEMPLATE_TYPE_PARM: return 1; - case TEMPLATE_TEMPLATE_PARM: return 1; - case TEMPLATE_PARM_INDEX: return 1; - case TYPENAME_TYPE: return 1; - case BOUND_TEMPLATE_TEMPLATE_PARM: return 1; - - /* A constant or variable declaration is encountered when a - template instantiates another template using an enum or static - const value that is not known until the outer template is - instantiated. */ - case CONST_DECL: return 1; - case VAR_DECL: return 1; - case FUNCTION_DECL: return 1; - - /* A template deferred lookup expression. */ - case LOOKUP_EXPR: return 1; - - /* A template deferred scoped lookup. */ - case SCOPE_REF: return 1; - - /* A cast of a dependent expression. */ - case CAST_EXPR: return 1; - - /* Types with nested types. */ - case METHOD_TYPE: - case FUNCTION_TYPE: - { - tree arg_type = TYPE_ARG_TYPES (t); - if(xml_find_template_parm (TREE_TYPE (t))) - { - return 1; - } - while (arg_type && (arg_type != void_list_node)) - { - if(xml_find_template_parm (arg_type)) - { - return 1; - } - arg_type = TREE_CHAIN (arg_type); - } - } break; - case UNION_TYPE: - case RECORD_TYPE: - { - if ((TREE_CODE (t) == RECORD_TYPE) && TYPE_PTRMEMFUNC_P (t)) - { - return xml_find_template_parm(TYPE_PTRMEMFUNC_FN_TYPE (t)); - } - if (CLASSTYPE_TEMPLATE_INFO (t)) - { - return xml_find_template_parm (CLASSTYPE_TI_ARGS (t)); - } - } - case REFERENCE_TYPE: return xml_find_template_parm (TREE_TYPE (t)); - case POINTER_TYPE: return xml_find_template_parm (TREE_TYPE (t)); - case ARRAY_TYPE: return xml_find_template_parm (TREE_TYPE (t)); - case OFFSET_TYPE: - { - return (xml_find_template_parm(TYPE_OFFSET_BASETYPE (t)) || - xml_find_template_parm (TREE_TYPE (t))); - } - case PTRMEM_CST: - { - return (xml_find_template_parm(PTRMEM_CST_CLASS (t)) || - xml_find_template_parm(PTRMEM_CST_MEMBER(t))); - } - - /* Fundamental types have no nested types. */ - case BOOLEAN_TYPE: return 0; - case COMPLEX_TYPE: return 0; - case ENUMERAL_TYPE: return 0; - case INTEGER_TYPE: return 0; - case LANG_TYPE: return 0; - case REAL_TYPE: return 0; - case VOID_TYPE: return 0; - - /* Template declarations are part of instantiations of template - template parameters. */ - case TEMPLATE_DECL: return 0; - - /* Other types that have no nested types. */ - case INTEGER_CST: return 0; - case SIZEOF_EXPR: return 0; - case ADDR_EXPR: return 0; - case BIT_AND_EXPR: return 0; - case BIT_IOR_EXPR: return 0; - case BIT_NOT_EXPR: return 0; - case BIT_XOR_EXPR: return 0; - case COMPOUND_EXPR: return 0; - case COND_EXPR: return 0; - case CONVERT_EXPR: return 0; - case EQ_EXPR: return 0; - case GE_EXPR: return 0; - case GT_EXPR: return 0; - case LE_EXPR: return 0; - case LSHIFT_EXPR: return 0; - case LT_EXPR: return 0; - case MAX_EXPR: return 0; - case MINUS_EXPR: return 0; - case MIN_EXPR: return 0; - case MODIFY_EXPR: return 0; - case MULT_EXPR: return 0; - case NEGATE_EXPR: return 0; - case NE_EXPR: return 0; - case NOP_EXPR: return 0; - case PLUS_EXPR: return 0; - case POSTDECREMENT_EXPR: return 0; - case POSTINCREMENT_EXPR: return 0; - case PREDECREMENT_EXPR: return 0; - case PREINCREMENT_EXPR: return 0; - case RSHIFT_EXPR: return 0; - case TRUNC_DIV_EXPR: return 0; - case TRUNC_MOD_EXPR: return 0; - case TRUTH_ANDIF_EXPR: return 0; - case TRUTH_NOT_EXPR: return 0; - case TRUTH_ORIF_EXPR: return 0; - case STATIC_CAST_EXPR: return 0; - default: - fprintf(stderr, "xml_find_template_parm encountered unsupported type %s\n", - tree_code_name[TREE_CODE (t)]); - } - return 0; -} - -/* Dump for a TEMPLATE_DECL. The set of specializations (including - instantiations) is dumped. */ -static int -xml_add_template_decl (xml_dump_info_p xdi, tree td, int complete) -{ - tree tl; - - /* Dump the template specializations. */ - for (tl = DECL_TEMPLATE_SPECIALIZATIONS (td); - tl ; tl = TREE_CHAIN (tl)) - { - tree ts = TREE_VALUE (tl); - switch (TREE_CODE (ts)) - { - case FUNCTION_DECL: - xml_add_node (xdi, ts, complete); - break; - case TEMPLATE_DECL: - break; - default: - /* xml_output_unimplemented (xdi, ts, 0, - "xml_dump_template_decl SPECIALIZATIONS"); */ - break; - } - } - - /* Dump the template instantiations. */ - for (tl = DECL_TEMPLATE_INSTANTIATIONS (td); - tl ; tl = TREE_CHAIN (tl)) - { - tree ts = TYPE_NAME (TREE_VALUE (tl)); - switch (TREE_CODE (ts)) - { - case TYPE_DECL: - /* Add the instantiation only if it is real. */ - if (!xml_find_template_parm (TYPE_TI_ARGS(TREE_TYPE(ts)))) - { - xml_add_node (xdi, ts, complete); - } - break; - default: - /* xml_output_unimplemented (xdi, ts, 0, - "xml_dump_template_decl INSTANTIATIONS"); */ - break; - } - } - - /* Dump any member template instantiations. */ - if (complete) - { - for (tl = TYPE_FIELDS (TREE_TYPE (td)); tl; tl = TREE_CHAIN (tl)) - { - if (TREE_CODE (tl) == TEMPLATE_DECL) - { - xml_add_template_decl (xdi, tl, 1); - } - } - } - - return 0; -} - -/* Dump the given tree node. */ -void -xml_dump_tree_node (xml_dump_info_p xdi, tree n, xml_dump_node_p dn) -{ - switch (TREE_CODE (n)) - { - case NAMESPACE_DECL: - xml_output_namespace_decl (xdi, n, dn); - break; - case TYPE_DECL: - xml_output_typedef (xdi, n, dn); - break; - case FUNCTION_DECL: - xml_output_function_decl (xdi, n, dn); - break; - case VAR_DECL: - xml_output_var_decl (xdi, n, dn); - break; - case FIELD_DECL: - xml_output_field_decl (xdi, n, dn); - break; - case UNION_TYPE: - case RECORD_TYPE: - case ARRAY_TYPE: - case POINTER_TYPE: - case REFERENCE_TYPE: - case FUNCTION_TYPE: - case METHOD_TYPE: - case OFFSET_TYPE: - case ENUMERAL_TYPE: - case LANG_TYPE: - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case REAL_TYPE: - case VOID_TYPE: - case COMPLEX_TYPE: - xml_output_cv_qualified_type (xdi, n, dn); - break; - - /* Let the following fall through to unimplemented for now. */ - case RESULT_DECL: - case USING_DECL: - /* case THUNK_DECL: */ - /* This is compiler-generated. Just ignore it. */ - /* break; */ - case SCOPE_REF: - case TEMPLATE_PARM_INDEX: - case INTEGER_CST: - case TYPENAME_TYPE: - case TEMPLATE_TYPE_PARM: - default: - xml_output_unimplemented (xdi, n, dn, 0); - } -} - -/* If we enabled xml dump debugging, undefine the macro. */ -#if defined(xml_add_node) -# undef xml_add_node -#endif - -/* Add tree node N to those encountered. Return its index. */ -int -xml_add_node (xml_dump_info_p xdi, tree n, int complete) -{ - /* Some nodes don't need to be dumped and just refer to other nodes. - These nodes should can have index zero because they should never - be referenced. */ - switch (TREE_CODE (n)) - { - case NAMESPACE_DECL: -#if defined(XML_HAVE_FAKE_STD_NODE) - if(n != fake_std_node) -#endif - { - return xml_add_node_real (xdi, n, complete); - } - break; - case TYPE_DECL: - return xml_add_type_decl(xdi, n, complete); - break; - case TREE_LIST: - return xml_add_overload (xdi, TREE_VALUE (n), complete); - break; - case OVERLOAD: - return xml_add_overload (xdi, n, complete); - break; - case TEMPLATE_DECL: - return xml_add_template_decl (xdi, n, complete); - break; - case UNION_TYPE: - case RECORD_TYPE: - if ((TREE_CODE (n) == RECORD_TYPE) && TYPE_PTRMEMFUNC_P (n)) - { - /* Pointer-to-member-functions are stored in a RECORD_TYPE. */ - return xml_add_node (xdi, TYPE_PTRMEMFUNC_FN_TYPE (n), complete); - } - else if (!CLASSTYPE_IS_TEMPLATE (n)) - { - /* This is a struct or class type. */ - return xml_add_node_real (xdi, n, complete); - } - else - { - /* This is a class template. We don't want to dump it. */ - return 0; - } - break; - case CONST_DECL: - /* Enumeration value constant. Dumped by the enumeration type. */ - return 0; - break; - default: - /* This node must really be added. */ - return xml_add_node_real (xdi, n, complete); - } - - return 0; -} - -/* Dump the queue of file names. */ -void xml_dump_files (xml_dump_info_p xdi) -{ - xml_file_queue_p fq; - xml_file_queue_p next_fq; - for(fq = xdi->file_queue; fq ; fq = next_fq) - { - fprintf (xdi->file, " \n", - (unsigned int) fq->tree_node->value, - IDENTIFIER_POINTER ((tree) fq->tree_node->key)); - next_fq = fq->next; - free (fq); - } -} - -/*--------------------------------------------------------------------------*/ - -/* Starting in the given scope, look for the qualified name. */ -static tree -xml_lookup_start_node (tree scope, const char* qualified_name) -{ - tree node = 0; - char* name = 0; - int pos = 0; - tree id; - - /* Parse off the first qualifier. */ - while (qualified_name[pos] && (qualified_name[pos] != ':')) { ++pos; } - name = xmalloc(pos+1); - strncpy (name, qualified_name, pos); - name[pos] = 0; - id = get_identifier (name); - free (name); - - /* Lookup the first qualifier. */ - if (TREE_CODE (scope) == NAMESPACE_DECL) - { - node = lookup_namespace_name (scope, id); - } - else if ((TREE_CODE (scope) == TYPE_DECL) - && (TREE_CODE (TREE_TYPE (scope)) == RECORD_TYPE)) - { - node = lookup_member (TREE_TYPE (scope), id, 2, 0); - } - - if (!node) { return 0; } - - /* Find the start of the next qualifier, if any. */ - while (qualified_name[pos] && (qualified_name[pos] == ':')) { ++pos; } - - /* If that was not the last qualifier, lookup the rest recursively. */ - if (qualified_name[pos]) - { - return xml_lookup_start_node (node, qualified_name+pos); - } - else - { - return node; - } -} - -/* Add the given node as a starting node. */ -static void -xml_add_start_node (xml_dump_info_p xdi, tree n) -{ - /* If a list was returned (from lookup_member), add all - candidates. */ - if ((TREE_CODE (n) == TREE_LIST) - && (TREE_TYPE (n) == error_mark_node)) - { - tree l = n; - while (l) - { - xml_add_node (xdi, TREE_VALUE (l), 1); - l = TREE_CHAIN (l); - } - } - else - { - xml_add_node (xdi, n, 1); - } -} - -/* Parse the comma-separated list of start nodes. Lookup and add each - one. */ -void -xml_add_start_nodes (xml_dump_info_p xdi, const char* in_start_list) -{ - size_t len = strlen(in_start_list); - int pos=0; - char* start_list = (char*)xmalloc(len+1); - char* cur_start = start_list; - tree node = 0; - strcpy(start_list, in_start_list); - - /* Parse out the comma-separated list. */ - while (start_list[pos]) - { - /* Split the list at each comma. */ - if (start_list[pos] == ',') - { - start_list[pos] = 0; - - /* Add the node for this list entry. */ - node = xml_lookup_start_node (global_namespace, cur_start); - if (node) - { - xml_add_start_node (xdi, node); - } - - /* Start the next list entry. */ - cur_start = start_list+pos+1; - } - ++pos; - } - - /* Add the node for the last list entry. */ - node = xml_lookup_start_node (global_namespace, cur_start); - if (node) - { - xml_add_start_node (xdi, node); - } - - free (start_list); -} - -/*--------------------------------------------------------------------------*/ - -/* Convert the identifier IN_ID to an XML encoded form by passing its string - to xml_get_encoded_string_from_string(). */ -const char* -xml_get_encoded_string (tree in_id) -{ - if(in_id) - return xml_get_encoded_string_from_string (IDENTIFIER_POINTER (in_id)); - else - return ""; -} - -#define XML_AMPERSAND "&" -#define XML_LESS_THAN "<" -#define XML_GREATER_THAN ">" -#define XML_SINGLE_QUOTE "'" -#define XML_DOUBLE_QUOTE """ - -const char* -xml_get_encoded_string_from_string (const char* in_str) -{ - return IDENTIFIER_POINTER (xml_get_encoded_identifier_from_string (in_str)); -} - -/* Convert the name IN_STR to an XML encoded form. - This replaces '&', '<', and '>' - with their corresponding unicode character references. */ -const char* -xml_escape_string(const char* in_str) -{ - int length_increase = 0; - const char* inCh; - char* outCh; - char* newStr; - - /* Count special characters and calculate extra length needed for encoded - form of string. */ - for(inCh = in_str; *inCh != '\0' ; ++inCh) - { - switch (*inCh) - { - case '&': length_increase += strlen(XML_AMPERSAND)-1; break; - case '<': length_increase += strlen(XML_LESS_THAN)-1; break; - case '>': length_increase += strlen(XML_GREATER_THAN)-1; break; - case '\'': length_increase += strlen(XML_SINGLE_QUOTE)-1; break; - case '"': length_increase += strlen(XML_DOUBLE_QUOTE)-1; break; - } - } - - newStr = (char*) xmalloc (strlen (in_str) + length_increase + 1); - outCh = newStr; - - /* Create encoded form of string. */ - for(inCh = in_str ; *inCh != '\0' ; ++inCh) - { - switch (*inCh) - { - case '&': strcpy (outCh, XML_AMPERSAND); outCh += strlen(XML_AMPERSAND); break; - case '<': strcpy (outCh, XML_LESS_THAN); outCh += strlen(XML_LESS_THAN); break; - case '>': strcpy (outCh, XML_GREATER_THAN); outCh += strlen(XML_GREATER_THAN); break; - case '\'': strcpy (outCh, XML_SINGLE_QUOTE); outCh += strlen(XML_SINGLE_QUOTE); break; - case '"': strcpy (outCh, XML_DOUBLE_QUOTE); outCh += strlen(XML_DOUBLE_QUOTE); break; - default: *outCh++ = *inCh; - } - } - - *outCh = '\0'; - - return newStr; -} - -/* Convert the name IN_STR to an XML encoded form. - This replaces '&', '<', and '>' - with their corresponding unicode character references. */ -tree -xml_get_encoded_identifier_from_string (const char* in_str) -{ - char* newStr = xml_escape_string( in_str ); - tree id; - - /* Ask for "identifier" of this string and free our own copy of the - memory. */ - id = get_identifier(newStr); - free(newStr); - return id; -} - -#undef XML_AMPERSAND -#undef XML_LESS_THAN -#undef XML_GREATER_THAN -#undef XML_SINGLE_QUOTE -#undef XML_DOUBLE_QUOTE - -/*--------------------------------------------------------------------------*/ -/* Check at - -http://tools.decisionsoft.com/schemaValidate.html -http://www.xmlfiles.com/dtd/dtd_attributes.asp -http://www.w3schools.com/schema/schema_complex_subst.asp - -*/ -/* - - - - - - - - - - - - - - - - - -*/ - -static void -xml_document_generate_indent(xml_document_info_p xdi, int indent) -{ - int i; - for (i=0; i < indent; ++i) - { - fprintf (xdi->file, " "); - } -} - -static void -xml_document_generate_attribute(xml_document_info_p xdi, - xml_document_element_p element, - xml_document_attribute_p attribute, - int indent) -{ - if(xdi->format == xml_document_format_dtd) - { - fprintf (xdi->file, "\n", - element->name, attribute->name, - xml_document_dtd_types[attribute->type], - xml_document_dtd_uses[attribute->use]); - } - else if(xdi->format == xml_document_format_schema) - { - xml_document_generate_indent(xdi, indent); - fprintf (xdi->file, "", - attribute->name, - xml_document_schema_types[attribute->type], - xml_document_schema_uses[attribute->use]); - } -} - -static void -xml_document_generate_element(xml_document_info_p xdi, - xml_document_element_p element, int indent) -{ - int i; - if(xdi->format == xml_document_format_dtd) - { - fprintf (xdi->file, "name); - if(element->num_subelements > 0) - { - char next[] = ",\n "; - const char* pnext = ""; - next[strlen(element->name) + 12 + 2] = '\0'; - for(i=0; i < element->num_subelements; ++i) - { - fprintf (xdi->file, "%s%s", pnext, - element->subelements[i].element->name); - if(element->subelements[i].required && - element->subelements[i].repeatable) - { - fprintf (xdi->file, "+"); - } - else if(element->subelements[i].repeatable) - { - fprintf (xdi->file, "*"); - } - else if(!element->subelements[i].required) - { - fprintf (xdi->file, "?"); - } - pnext = next; - } - } - else - { - fprintf (xdi->file, "EMPTY", element); - } - fprintf (xdi->file, ")>\n"); - } - else if(xdi->format == xml_document_format_schema) - { - xml_document_generate_indent(xdi, indent); - fprintf (xdi->file, "\n", element); - xml_document_generate_indent(xdi, indent); - fprintf (xdi->file, " \n"); - } - - for(i=0; i < element->num_attributes; ++i) - { - xml_document_generate_attribute(xdi, element, &element->attributes[i], - indent+3); - } - - for(i=0; i < element->num_subelements; ++i) - { - xml_document_generate_element(xdi, element->subelements[i].element, - indent+3); - } - - if(xdi->format == xml_document_format_schema) - { - xml_document_generate_indent(xdi, indent); - fprintf (xdi->file, " \n"); - xml_document_generate_indent(xdi, indent); - fprintf (xdi->file, "\n"); - } -} - -/* Main XML documentation generation function. */ -void -do_xml_document (const char* dtd_name, const char* schema_name) -{ - /* Record the documentation specification. */ - xml_document_info xdi; - xml_document_element_p element; - xml_document_subelement_p subelement; - memset(&xdi, 0, sizeof(xdi)); - - element = &xdi.elements[xdi.num_elements++]; - element->name = "GCC-XML"; - xml_document_add_element_fundamental_type (&xdi, element); - xml_document_add_element_unimplemented (&xdi, element); - xml_document_add_element_namespace_decl (&xdi, element); - xml_document_add_element_typedef (&xdi, element); - xml_document_add_element_function (&xdi, element); - xml_document_add_element_var_decl (&xdi, element); - xml_document_add_element_field_decl (&xdi, element); - xml_document_add_element_record_type (&xdi, element); - xml_document_add_element_fundamental_type (&xdi, element); - xml_document_add_element_function_type (&xdi, element); - xml_document_add_element_method_type (&xdi, element); - xml_document_add_element_pointer_type (&xdi, element); - xml_document_add_element_reference_type (&xdi, element); - xml_document_add_element_offset_type (&xdi, element); - xml_document_add_element_array_type (&xdi, element); - xml_document_add_element_enumeral_type (&xdi, element); - xml_document_add_element_cv_qualified_type (&xdi, element); - - if(dtd_name) - { - /* Generate the DTD file. */ - xdi.file = fopen (dtd_name, "w"); - xdi.format = xml_document_format_dtd; - if (xdi.file) - { - xml_document_generate_element(&xdi, &xdi.elements[0], 0); - } - else - { - XML_CP_ERROR ("could not open xml-dtd file `%s'", dtd_name); - } - } -}