-/// EmitBuiltinComparisons - Emit comparisons to determine whether the specified
-/// sorted range of builtin names is equal to the current builtin. This breaks
-/// it down into a simple tree.
-///
-/// At this point, we know that all the builtins in the range have the same name
-/// for the first 'CharStart' characters. Only the end of the name needs to be
-/// discriminated.
-typedef std::map<std::string, std::string>::const_iterator StrMapIterator;
-static void EmitBuiltinComparisons(StrMapIterator Start, StrMapIterator End,
- unsigned CharStart, unsigned Indent,
- std::string TargetPrefix, std::ostream &OS) {
- if (Start == End) return; // empty range.
-
- // Determine what, if anything, is the same about all these strings.
- std::string CommonString = Start->first;
- unsigned NumInRange = 0;
- for (StrMapIterator I = Start; I != End; ++I, ++NumInRange) {
- // Find the first character that doesn't match.
- const std::string &ThisStr = I->first;
- unsigned NonMatchChar = CharStart;
- while (NonMatchChar < CommonString.size() &&
- NonMatchChar < ThisStr.size() &&
- CommonString[NonMatchChar] == ThisStr[NonMatchChar])
- ++NonMatchChar;
- // Truncate off pieces that don't match.
- CommonString.resize(NonMatchChar);
- }
-
- // Just compare the rest of the string.
- if (NumInRange == 1) {
- if (CharStart != CommonString.size()) {
- OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName";
- if (CharStart) OS << "+" << CharStart;
- OS << ", \"" << (CommonString.c_str()+CharStart) << "\", ";
- OS << CommonString.size() - CharStart << "))\n";
- ++Indent;
- }
- OS << std::string(Indent*2, ' ') << "IntrinsicID = " << TargetPrefix
- << "Intrinsic::";
- OS << Start->second << ";\n";
- return;
- }
-
- // At this point, we potentially have a common prefix for these builtins, emit
- // a check for this common prefix.
- if (CommonString.size() != CharStart) {
- OS << std::string(Indent*2, ' ') << "if (!memcmp(BuiltinName";
- if (CharStart) OS << "+" << CharStart;
- OS << ", \"" << (CommonString.c_str()+CharStart) << "\", ";
- OS << CommonString.size()-CharStart << ")) {\n";
-
- EmitBuiltinComparisons(Start, End, CommonString.size(), Indent+1,
- TargetPrefix, OS);
- OS << std::string(Indent*2, ' ') << "}\n";
- return;
- }
-
- // Output a switch on the character that differs across the set.
- OS << std::string(Indent*2, ' ') << "switch (BuiltinName[" << CharStart
- << "]) {";
- if (CharStart)
- OS << " // \"" << std::string(Start->first.begin(),
- Start->first.begin()+CharStart) << "\"";
- OS << "\n";
-
- for (StrMapIterator I = Start; I != End; ) {
- char ThisChar = I->first[CharStart];
- OS << std::string(Indent*2, ' ') << "case '" << ThisChar << "':\n";
- // Figure out the range that has this common character.
- StrMapIterator NextChar = I;
- for (++NextChar; NextChar != End && NextChar->first[CharStart] == ThisChar;
- ++NextChar)
- /*empty*/;
- EmitBuiltinComparisons(I, NextChar, CharStart+1, Indent+1, TargetPrefix,OS);
- OS << std::string(Indent*2, ' ') << " break;\n";
- I = NextChar;
- }
- OS << std::string(Indent*2, ' ') << "}\n";
-}
-