namespace llvm {
+class LLVMContext;
class Module;
+struct SlotMapping;
class SMDiagnostic;
-class LLVMContext;
/// 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
/// Module (intermediate representation) with the corresponding features. Note
/// that this does not verify that the generated Module is valid, so you should
/// run the verifier after parsing the file to check that it is okay.
-/// @brief Parse LLVM Assembly from a file
-/// @param Filename The name of the file to parse
-/// @param Error Error result info.
-/// @param Context Context in which to allocate globals info.
+/// \brief Parse LLVM Assembly from a file
+/// \param Filename The name of the file to parse
+/// \param Error Error result info.
+/// \param Context Context in which to allocate globals info.
+/// \param Slots The optional slot mapping that will be initialized during
+/// parsing.
std::unique_ptr<Module> parseAssemblyFile(StringRef Filename,
SMDiagnostic &Error,
- LLVMContext &Context);
+ LLVMContext &Context,
+ SlotMapping *Slots = nullptr);
/// The function is a secondary interface to the LLVM Assembly Parser. It parses
/// an ASCII string that (presumably) contains LLVM Assembly code. It returns a
/// Module (intermediate representation) with the corresponding features. Note
/// that this does not verify that the generated Module is valid, so you should
/// run the verifier after parsing the file to check that it is okay.
-/// @brief Parse LLVM Assembly from a string
-/// @param AsmString The string containing assembly
-/// @param Error Error result info.
-/// @param Context Context in which to allocate globals info.
+/// \brief Parse LLVM Assembly from a string
+/// \param AsmString The string containing assembly
+/// \param Error Error result info.
+/// \param Context Context in which to allocate globals info.
+/// \param Slots The optional slot mapping that will be initialized during
+/// parsing.
std::unique_ptr<Module> parseAssemblyString(StringRef AsmString,
SMDiagnostic &Error,
- LLVMContext &Context);
+ LLVMContext &Context,
+ SlotMapping *Slots = nullptr);
/// parseAssemblyFile and parseAssemblyString are wrappers around this function.
-/// @brief Parse LLVM Assembly from a MemoryBuffer.
-/// @param F The MemoryBuffer containing assembly
-/// @param Err Error result info.
-/// @param Context Context in which to allocate globals info.
+/// \brief Parse LLVM Assembly from a MemoryBuffer.
+/// \param F The MemoryBuffer containing assembly
+/// \param Err Error result info.
+/// \param Slots The optional slot mapping that will be initialized during
+/// parsing.
std::unique_ptr<Module> parseAssembly(MemoryBufferRef F, SMDiagnostic &Err,
- LLVMContext &Context);
+ LLVMContext &Context,
+ SlotMapping *Slots = nullptr);
/// This function is the low-level interface to the LLVM Assembly Parser.
/// This is kept as an independent function instead of being inlined into
/// parseAssembly for the convenience of interactive users that want to add
/// recently parsed bits to an existing module.
///
-/// @param F The MemoryBuffer containing assembly
-/// @param M The module to add data to.
-/// @param Err Error result info.
-/// @return true on error.
-bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err);
+/// \param F The MemoryBuffer containing assembly
+/// \param M The module to add data to.
+/// \param Err Error result info.
+/// \param Slots The optional slot mapping that will be initialized during
+/// parsing.
+/// \return true on error.
+bool parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err,
+ SlotMapping *Slots = nullptr);
} // End llvm namespace
--- /dev/null
+//===-- SlotMapping.h - Slot number mapping for unnamed values --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the SlotMapping struct.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASMPARSER_SLOTMAPPING_H
+#define LLVM_ASMPARSER_SLOTMAPPING_H
+
+#include "llvm/IR/TrackingMDRef.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+class GlobalValue;
+
+/// This struct contains the mapping from the slot numbers to unnamed metadata
+/// nodes and global values.
+struct SlotMapping {
+ std::vector<GlobalValue *> GlobalValues;
+ std::map<unsigned, TrackingMDNodeRef> MetadataNodes;
+};
+
+} // end namespace llvm
+
+#endif
#include "LLParser.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
UpgradeDebugInfo(*M);
+ if (!Slots)
+ return false;
+ // Initialize the slot mapping.
+ // Because by this point we've parsed and validated everything, we can "steal"
+ // the mapping from LLParser as it doesn't need it anymore.
+ Slots->GlobalValues = std::move(NumberedVals);
+ Slots->MetadataNodes = std::move(NumberedMetadata);
+
return false;
}
class Comdat;
class MDString;
class MDNode;
+ struct SlotMapping;
class StructType;
/// ValID - Represents a reference of a definition of some sort with no type.
LLVMContext &Context;
LLLexer Lex;
Module *M;
+ SlotMapping *Slots;
// Instruction metadata resolution. Each instruction can have a list of
// MDRef info associated with them.
std::map<unsigned, AttrBuilder> NumberedAttrBuilders;
public:
- LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *m)
- : Context(m->getContext()), Lex(F, SM, Err, m->getContext()), M(m),
- BlockAddressPFS(nullptr) {}
+ LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M,
+ SlotMapping *Slots = nullptr)
+ : Context(M->getContext()), Lex(F, SM, Err, M->getContext()), M(M),
+ Slots(Slots), BlockAddressPFS(nullptr) {}
bool Run();
LLVMContext &getContext() { return Context; }
#include <system_error>
using namespace llvm;
-bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err) {
+bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err,
+ SlotMapping *Slots) {
SourceMgr SM;
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F);
SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
- return LLParser(F.getBuffer(), SM, Err, &M).Run();
+ return LLParser(F.getBuffer(), SM, Err, &M, Slots).Run();
}
std::unique_ptr<Module> llvm::parseAssembly(MemoryBufferRef F,
SMDiagnostic &Err,
- LLVMContext &Context) {
+ LLVMContext &Context,
+ SlotMapping *Slots) {
std::unique_ptr<Module> M =
make_unique<Module>(F.getBufferIdentifier(), Context);
- if (parseAssemblyInto(F, *M, Err))
+ if (parseAssemblyInto(F, *M, Err, Slots))
return nullptr;
return M;
std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename,
SMDiagnostic &Err,
- LLVMContext &Context) {
+ LLVMContext &Context,
+ SlotMapping *Slots) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = FileOrErr.getError()) {
return nullptr;
}
- return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context);
+ return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots);
}
std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
SMDiagnostic &Err,
- LLVMContext &Context) {
+ LLVMContext &Context,
+ SlotMapping *Slots) {
MemoryBufferRef F(AsmString, "<string>");
- return parseAssembly(F, Err, Context);
+ return parseAssembly(F, Err, Context, Slots);
}
#include "llvm/ADT/StringRef.h"
#include "llvm/AsmParser/Parser.h"
+#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#endif
#endif
+TEST(AsmParserTest, SlotMappingTest) {
+ LLVMContext &Ctx = getGlobalContext();
+ StringRef Source = "@0 = global i32 0\n !0 = !{}\n !42 = !{i32 42}";
+ SMDiagnostic Error;
+ SlotMapping Mapping;
+ auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
+
+ EXPECT_TRUE(Mod != nullptr);
+ EXPECT_TRUE(Error.getMessage().empty());
+
+ ASSERT_EQ(Mapping.GlobalValues.size(), 1u);
+ EXPECT_TRUE(isa<GlobalVariable>(Mapping.GlobalValues[0]));
+
+ EXPECT_EQ(Mapping.MetadataNodes.size(), 2u);
+ EXPECT_EQ(Mapping.MetadataNodes.count(0), 1u);
+ EXPECT_EQ(Mapping.MetadataNodes.count(42), 1u);
+ EXPECT_EQ(Mapping.MetadataNodes.count(1), 0u);
+}
+
} // end anonymous namespace