aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2009-06-08 23:05:37 +0000
committerDavid Greene <greened@obbligato.org>2009-06-08 23:05:37 +0000
commit0d973999f3a7973e680e12acdf6def9d769911b6 (patch)
treed26340225fa5c4ca70833825a305da557017db5e /utils
parent2e7ccfce98b925d07788fdd08cccc9ddb3d7004b (diff)
downloadexternal_llvm-0d973999f3a7973e680e12acdf6def9d769911b6.zip
external_llvm-0d973999f3a7973e680e12acdf6def9d769911b6.tar.gz
external_llvm-0d973999f3a7973e680e12acdf6def9d769911b6.tar.bz2
Add a !patsubst operator. Use on string types.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73099 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp2
-rw-r--r--utils/TableGen/Record.cpp65
-rw-r--r--utils/TableGen/Record.h2
-rw-r--r--utils/TableGen/TGLexer.cpp1
-rw-r--r--utils/TableGen/TGLexer.h2
-rw-r--r--utils/TableGen/TGParser.cpp9
6 files changed, 78 insertions, 3 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 05bbc0a..e668468 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2025,7 +2025,7 @@ void CodeGenDAGPatterns::ParsePatterns() {
}
}
else {
- ListTy - TArg->getType();
+ ListTy = TArg->getType();
}
}
ListInit *LI = new ListInit(Values, new ListRecTy(ListTy));
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index fa10799..2f500ae 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -18,6 +18,7 @@
#include <ios>
#include <sys/types.h>
#include <regex.h>
+#include <sstream>
using namespace llvm;
@@ -1034,6 +1035,69 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
}
break;
}
+
+ case PATSUBST: {
+ StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+ StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
+ StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+
+ if (LHSs && MHSs && RHSs) {
+ regex_t compiled;
+ int err = regcomp (&compiled, LHSs->getValue().c_str(), REG_EXTENDED);
+ if (err != 0) {
+ size_t length = regerror (err, &compiled, NULL, 0);
+ char *buffer = new char[length];
+ (void) regerror (err, &compiled, buffer, length);
+ std::string errmsg = buffer;
+ delete[] buffer;
+ regfree(&compiled);
+ throw errmsg;
+ }
+ regmatch_t matches[10];
+ int result = regexec(&compiled, RHSs->getValue().c_str(), 10, matches, 0);
+ if (result == REG_ESPACE) {
+ size_t length = regerror (err, &compiled, NULL, 0);
+ char *buffer = new char[length];
+ (void) regerror (err, &compiled, buffer, length);
+ std::string errmsg = buffer;
+ delete[] buffer;
+ regfree(&compiled);
+ throw errmsg;
+ }
+ regfree(&compiled);
+ if (result == 0) {
+ // Parse the substitution string looking for $1, $2, etc. and
+ // substitute strings. If there are no $1, etc. just replace
+ // the whole string.
+ std::string replacement = MHSs->getValue();
+ size_t pos = replacement.find("$");
+ while (pos != std::string::npos && pos+1 < replacement.size()) {
+ if (std::isdigit(replacement[pos+1])) {
+ std::string sidx(&replacement[pos+1], 1);
+ std::istringstream str(sidx);
+ int idx;
+ if (str >> idx) {
+ replacement.replace(pos, 2, RHSs->getValue(), matches[idx].rm_so,
+ matches[idx].rm_eo - matches[idx].rm_so);
+ }
+ else {
+ throw "unexpected failure in patsubst index calculation";
+ }
+ }
+ else if (replacement[pos+1] == '$') {
+ replacement.replace(pos, 2, "$");
+ }
+ pos = replacement.find("$", pos+1);
+ }
+ return new StringInit(replacement);
+ }
+ else {
+ // No match, just pass the string through
+ return RHSs;
+ }
+ }
+ break;
+ }
}
return this;
@@ -1069,6 +1133,7 @@ std::string TernOpInit::getAsString() const {
std::string Result;
switch (Opc) {
case SUBST: Result = "!subst"; break;
+ case PATSUBST: Result = "!patsubst"; break;
case FOREACH: Result = "!foreach"; break;
case IF: Result = "!if"; break;
}
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 8ef833d..d8e4fb3 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -885,7 +885,7 @@ public:
///
class TernOpInit : public OpInit {
public:
- enum TernaryOp { SUBST, FOREACH, IF };
+ enum TernaryOp { SUBST, FOREACH, IF, PATSUBST };
private:
TernaryOp Opc;
Init *LHS, *MHS, *RHS;
diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp
index 378bffb..930d9db 100644
--- a/utils/TableGen/TGLexer.cpp
+++ b/utils/TableGen/TGLexer.cpp
@@ -449,6 +449,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
if (Len == 8 && !memcmp(Start, "regmatch", 8)) return tgtok::XRegMatch;
if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
+ if (Len == 8 && !memcmp(Start, "patsubst", 8)) return tgtok::XPatSubst;
if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
if (Len == 3 && !memcmp(Start, "car", 3)) return tgtok::XCar;
diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h
index 06f6535..fef10f0 100644
--- a/utils/TableGen/TGLexer.h
+++ b/utils/TableGen/TGLexer.h
@@ -46,7 +46,7 @@ namespace tgtok {
// !keywords.
XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
- XForEach, XCar, XCdr, XNull, XIf, XRegMatch,
+ XForEach, XCar, XCdr, XNull, XIf, XRegMatch, XPatSubst,
// Integer value.
IntVal,
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index 7d3d1b3..d2bc6b8 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -878,6 +878,7 @@ Init *TGParser::ParseOperation(Record *CurRec) {
case tgtok::XIf:
case tgtok::XForEach:
+ case tgtok::XPatSubst:
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
TernOpInit::TernaryOp Code;
RecTy *Type = 0;
@@ -896,6 +897,9 @@ Init *TGParser::ParseOperation(Record *CurRec) {
case tgtok::XSubst:
Code = TernOpInit::SUBST;
break;
+ case tgtok::XPatSubst:
+ Code = TernOpInit::PATSUBST;
+ break;
}
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after ternary operator");
@@ -969,6 +973,10 @@ Init *TGParser::ParseOperation(Record *CurRec) {
Type = RHSt->getType();
break;
}
+ case tgtok::XPatSubst: {
+ Type = new StringRecTy;
+ break;
+ }
}
return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
}
@@ -1277,6 +1285,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
case tgtok::XNameConcat: // Value ::= !binop '(' Value ',' Value ')'
case tgtok::XIf:
case tgtok::XForEach:
+ case tgtok::XPatSubst:
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
return ParseOperation(CurRec);
break;