From cee93e95a4bb45e44d6029404fc47084e48b7775 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Sat, 21 Dec 2013 18:51:00 +0000 Subject: TableGen: Generate valid identifiers for anonymous records Backends like OptParserEmitter assume that record names can be used as valid identifiers. The period '.' in generated anonymous names broke that assumption, causing a build-time error and in practice forcing all records to be named. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197869 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/TableGen/TGParser.cpp | 12 +++++------- lib/TableGen/TGParser.h | 8 ++++++-- test/TableGen/ValidIdentifiers.td | 13 +++++++++++++ 3 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 test/TableGen/ValidIdentifiers.td diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index daac5747d3..38ab71184a 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -380,10 +380,11 @@ static bool isObjectStart(tgtok::TokKind K) { K == tgtok::MultiClass || K == tgtok::Foreach; } -static std::string GetNewAnonymousName() { - static unsigned AnonCounter = 0; +/// GetNewAnonymousName - Generate a unique anonymous name that can be used as +/// an identifier. +std::string TGParser::GetNewAnonymousName() { unsigned Tmp = AnonCounter++; // MSVC2012 ICEs without this. - return "anonymous." + utostr(Tmp); + return "anonymous_" + utostr(Tmp); } /// ParseObjectName - If an object name is specified, return it. Otherwise, @@ -1215,10 +1216,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, SMLoc EndLoc = Lex.getLoc(); // Create the new record, set it as CurRec temporarily. - static unsigned AnonCounter = 0; - Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++), - NameLoc, - Records, + Record *NewRec = new Record(GetNewAnonymousName(), NameLoc, Records, /*IsAnonymous=*/true); SubClassReference SCRef; SCRef.RefRange = SMRange(NameLoc, EndLoc); diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h index 044e3a02ba..a575345810 100644 --- a/lib/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -69,6 +69,8 @@ class TGParser { // Record tracker RecordKeeper &Records; + unsigned AnonCounter; + // A "named boolean" indicating how to parse identifiers. Usually // identifiers map to some existing object but in special cases // (e.g. parsing def names) no such object exists yet because we are @@ -82,8 +84,8 @@ class TGParser { }; public: - TGParser(SourceMgr &SrcMgr, RecordKeeper &records) : - Lex(SrcMgr), CurMultiClass(0), Records(records) {} + TGParser(SourceMgr &SrcMgr, RecordKeeper &records) + : Lex(SrcMgr), CurMultiClass(0), Records(records), AnonCounter(0) {} /// ParseFile - Main entrypoint for parsing a tblgen file. These parser /// routines return true on error, or false on success. @@ -112,6 +114,8 @@ private: // Semantic analysis methods. bool AddSubMultiClass(MultiClass *CurMC, SubMultiClassReference &SubMultiClass); + std::string GetNewAnonymousName(); + // IterRecord: Map an iterator name to a value. struct IterRecord { VarInit *IterVar; diff --git a/test/TableGen/ValidIdentifiers.td b/test/TableGen/ValidIdentifiers.td new file mode 100644 index 0000000000..899ae0e386 --- /dev/null +++ b/test/TableGen/ValidIdentifiers.td @@ -0,0 +1,13 @@ +// Ensure that anonymous names are valid identifiers via the ctags index +// RUN: llvm-tblgen -gen-ctags %s | grep -v '^!' | not grep -viE '^[a-z_][a-z0-9_]*\t' +// Test validation +// RUN: llvm-tblgen -gen-ctags %s | grep '^anonymous' > /dev/null +// XFAIL: vg_leak + +class foo { int THEVAL = X; } + +def : foo<2>; + +def X { + foo Y = foo<1>; +} -- cgit v1.2.3