[llvm] r262868 - [AsmParser] Add a function to parse a standalone type.

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 7 14:09:06 PST 2016


Author: qcolombet
Date: Mon Mar  7 16:09:05 2016
New Revision: 262868

URL: http://llvm.org/viewvc/llvm-project?rev=262868&view=rev
Log:
[AsmParser] Add a function to parse a standalone type.

This is useful for MIR serialization. Indeed generic machine instructions
must have a type and we don't want to duplicate the logic in the MIParser.

Modified:
    llvm/trunk/include/llvm/AsmParser/Parser.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/AsmParser/Parser.cpp
    llvm/trunk/unittests/AsmParser/AsmParserTest.cpp

Modified: llvm/trunk/include/llvm/AsmParser/Parser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/AsmParser/Parser.h?rev=262868&r1=262867&r2=262868&view=diff
==============================================================================
--- llvm/trunk/include/llvm/AsmParser/Parser.h (original)
+++ llvm/trunk/include/llvm/AsmParser/Parser.h Mon Mar  7 16:09:05 2016
@@ -23,6 +23,7 @@ class LLVMContext;
 class Module;
 struct SlotMapping;
 class SMDiagnostic;
+class Type;
 
 /// This function is the main interface to the LLVM Assembly Parser. It parses
 /// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
@@ -91,6 +92,14 @@ bool parseAssemblyInto(MemoryBufferRef F
 Constant *parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M,
                              const SlotMapping *Slots = nullptr);
 
+/// Parse a type in the given string.
+///
+/// \param Slots The optional slot mapping that will restore the parsing state
+/// of the module.
+/// \return null on error.
+Type *parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
+                const SlotMapping *Slots = nullptr);
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=262868&r1=262867&r2=262868&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Mar  7 16:09:05 2016
@@ -63,6 +63,18 @@ bool LLParser::parseStandaloneConstantVa
   return false;
 }
 
+bool LLParser::parseStandaloneType(Type *&Ty, const SlotMapping *Slots) {
+  restoreParsingState(Slots);
+  Lex.Lex();
+
+  Ty = nullptr;
+  if (ParseType(Ty))
+    return true;
+  if (Lex.getKind() != lltok::Eof)
+    return Error(Lex.getLoc(), "expected end of string");
+  return false;
+}
+
 void LLParser::restoreParsingState(const SlotMapping *Slots) {
   if (!Slots)
     return;

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=262868&r1=262867&r2=262868&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Mon Mar  7 16:09:05 2016
@@ -148,6 +148,8 @@ namespace llvm {
 
     bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
 
+    bool parseStandaloneType(Type *&Ty, const SlotMapping *Slots);
+
     LLVMContext &getContext() { return Context; }
 
   private:

Modified: llvm/trunk/lib/AsmParser/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Parser.cpp?rev=262868&r1=262867&r2=262868&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/Parser.cpp (original)
+++ llvm/trunk/lib/AsmParser/Parser.cpp Mon Mar  7 16:09:05 2016
@@ -78,3 +78,15 @@ Constant *llvm::parseConstantValue(Strin
     return nullptr;
   return C;
 }
+
+Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
+                      const SlotMapping *Slots) {
+  SourceMgr SM;
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
+  SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
+  Type *Ty;
+  if (LLParser(Asm, SM, Err, const_cast<Module *>(&M))
+          .parseStandaloneType(Ty, Slots))
+    return nullptr;
+  return Ty;
+}

Modified: llvm/trunk/unittests/AsmParser/AsmParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/AsmParser/AsmParserTest.cpp?rev=262868&r1=262867&r2=262868&view=diff
==============================================================================
--- llvm/trunk/unittests/AsmParser/AsmParserTest.cpp (original)
+++ llvm/trunk/unittests/AsmParser/AsmParserTest.cpp Mon Mar  7 16:09:05 2016
@@ -152,4 +152,124 @@ TEST(AsmParserTest, TypeAndConstantValue
   ASSERT_TRUE(isa<ConstantExpr>(V));
 }
 
+TEST(AsmParserTest, TypeWithSlotMappingParsing) {
+  LLVMContext &Ctx = getGlobalContext();
+  SMDiagnostic Error;
+  StringRef Source =
+      "%st = type { i32, i32 }\n"
+      "@v = common global [50 x %st] zeroinitializer, align 16\n"
+      "%0 = type { i32, i32, i32, i32 }\n"
+      "@g = common global [50 x %0] zeroinitializer, align 16\n"
+      "define void @marker4(i64 %d) {\n"
+      "entry:\n"
+      "  %conv = trunc i64 %d to i32\n"
+      "  store i32 %conv, i32* getelementptr inbounds "
+      "    ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n"
+      "  store i32 %conv, i32* getelementptr inbounds "
+      "    ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n"
+      "  ret void\n"
+      "}";
+  SlotMapping Mapping;
+  auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
+  ASSERT_TRUE(Mod != nullptr);
+  auto &M = *Mod;
+
+  // Check we properly parse integer types.
+  Type *Ty;
+  Ty = parseType("i32", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isIntegerTy());
+  ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
+
+  // Check we properly parse integer types with exotic size.
+  Ty = parseType("i13", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isIntegerTy());
+  ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 13);
+
+  // Check we properly parse floating point types.
+  Ty = parseType("float", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isFloatTy());
+
+  Ty = parseType("double", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isDoubleTy());
+
+  // Check we properly parse struct types.
+  // Named struct.
+  Ty = parseType("%st", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isStructTy());
+
+  // Check the details of the struct.
+  StructType *ST = cast<StructType>(Ty);
+  ASSERT_TRUE(ST->getNumElements() == 2);
+  for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
+    Ty = ST->getElementType(i);
+    ASSERT_TRUE(Ty->isIntegerTy());
+    ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
+  }
+
+  // Anonymous struct.
+  Ty = parseType("%0", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isStructTy());
+
+  // Check the details of the struct.
+  ST = cast<StructType>(Ty);
+  ASSERT_TRUE(ST->getNumElements() == 4);
+  for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
+    Ty = ST->getElementType(i);
+    ASSERT_TRUE(Ty->isIntegerTy());
+    ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
+  }
+
+  // Check we properly parse vector types.
+  Ty = parseType("<5 x i32>", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isVectorTy());
+
+  // Check the details of the vector.
+  VectorType *VT = cast<VectorType>(Ty);
+  ASSERT_TRUE(VT->getNumElements() == 5);
+  ASSERT_TRUE(VT->getBitWidth() == 160);
+  Ty = VT->getElementType();
+  ASSERT_TRUE(Ty->isIntegerTy());
+  ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
+
+  // Opaque struct.
+  Ty = parseType("%opaque", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isStructTy());
+
+  ST = cast<StructType>(Ty);
+  ASSERT_TRUE(ST->isOpaque());
+
+  // Check we properly parse pointer types.
+  // One indirection.
+  Ty = parseType("i32*", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isPointerTy());
+
+  PointerType *PT = cast<PointerType>(Ty);
+  Ty = PT->getElementType();
+  ASSERT_TRUE(Ty->isIntegerTy());
+  ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
+
+  // Two indirections.
+  Ty = parseType("i32**", Error, M, &Mapping);
+  ASSERT_TRUE(Ty);
+  ASSERT_TRUE(Ty->isPointerTy());
+
+  PT = cast<PointerType>(Ty);
+  Ty = PT->getElementType();
+  ASSERT_TRUE(Ty->isPointerTy());
+
+  PT = cast<PointerType>(Ty);
+  Ty = PT->getElementType();
+  ASSERT_TRUE(Ty->isIntegerTy());
+  ASSERT_TRUE(Ty->getPrimitiveSizeInBits() == 32);
+}
+
 } // end anonymous namespace




More information about the llvm-commits mailing list