mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-17 11:39:11 +00:00
Add a DIModule metadata node to the IR.
It is meant to be used to record modules @imported by the current compile unit, so a debugger an import the same modules to replicate this environment before dropping into the expression evaluator. DIModule is a sibling to DINamespace and behaves quite similarly. In addition to the name of the module it also records the module configuration details that are necessary to uniquely identify the module. This includes the configuration macros (e.g., -DNDEBUG), the include path where the module.map file is to be found, and the isysroot. The idea is that the backend will turn this into a DW_TAG_module. http://reviews.llvm.org/D9614 rdar://problem/20965932 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241017 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
88f33c9916
commit
717764717b
@ -167,6 +167,7 @@ namespace bitc {
|
|||||||
METADATA_EXPRESSION = 29, // [distinct, n x element]
|
METADATA_EXPRESSION = 29, // [distinct, n x element]
|
||||||
METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...]
|
METADATA_OBJC_PROPERTY = 30, // [distinct, name, file, line, ...]
|
||||||
METADATA_IMPORTED_ENTITY=31, // [distinct, tag, scope, entity, line, name]
|
METADATA_IMPORTED_ENTITY=31, // [distinct, tag, scope, entity, line, name]
|
||||||
|
METADATA_MODULE=32, // [distinct, scope, name, ...]
|
||||||
};
|
};
|
||||||
|
|
||||||
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
|
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
|
||||||
|
@ -566,6 +566,20 @@ namespace llvm {
|
|||||||
DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
|
DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File,
|
||||||
unsigned LineNo);
|
unsigned LineNo);
|
||||||
|
|
||||||
|
/// createModule - This creates new descriptor for a module
|
||||||
|
/// with the specified parent scope.
|
||||||
|
/// @param Scope Parent scope
|
||||||
|
/// @param Name Name of this module
|
||||||
|
/// @param ConfigurationMacros
|
||||||
|
/// A space-separated shell-quoted list of -D macro
|
||||||
|
/// definitions as they would appear on a command line.
|
||||||
|
/// @param IncludePath The path to the module map file.
|
||||||
|
/// @param ISysRoot The clang system root (value of -isysroot).
|
||||||
|
DIModule *createModule(DIScope *Scope, StringRef Name,
|
||||||
|
StringRef ConfigurationMacros,
|
||||||
|
StringRef IncludePath,
|
||||||
|
StringRef ISysRoot);
|
||||||
|
|
||||||
/// createLexicalBlockFile - This creates a descriptor for a lexical
|
/// createLexicalBlockFile - This creates a descriptor for a lexical
|
||||||
/// block with a new file attached. This merely extends the existing
|
/// block with a new file attached. This merely extends the existing
|
||||||
/// lexical block as it crosses a file.
|
/// lexical block as it crosses a file.
|
||||||
@ -598,6 +612,13 @@ namespace llvm {
|
|||||||
DIImportedEntity *createImportedModule(DIScope *Context,
|
DIImportedEntity *createImportedModule(DIScope *Context,
|
||||||
DIImportedEntity *NS, unsigned Line);
|
DIImportedEntity *NS, unsigned Line);
|
||||||
|
|
||||||
|
/// \brief Create a descriptor for an imported module.
|
||||||
|
/// @param Context The scope this module is imported into
|
||||||
|
/// @param M The module being imported here
|
||||||
|
/// @param Line Line number
|
||||||
|
DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M,
|
||||||
|
unsigned Line);
|
||||||
|
|
||||||
/// \brief Create a descriptor for an imported function.
|
/// \brief Create a descriptor for an imported function.
|
||||||
/// @param Context The scope this module is imported into
|
/// @param Context The scope this module is imported into
|
||||||
/// @param Decl The declaration (or definition) of a function, type, or
|
/// @param Decl The declaration (or definition) of a function, type, or
|
||||||
|
@ -218,6 +218,7 @@ public:
|
|||||||
case DILocalVariableKind:
|
case DILocalVariableKind:
|
||||||
case DIObjCPropertyKind:
|
case DIObjCPropertyKind:
|
||||||
case DIImportedEntityKind:
|
case DIImportedEntityKind:
|
||||||
|
case DIModuleKind:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,6 +444,7 @@ public:
|
|||||||
case DILexicalBlockKind:
|
case DILexicalBlockKind:
|
||||||
case DILexicalBlockFileKind:
|
case DILexicalBlockFileKind:
|
||||||
case DINamespaceKind:
|
case DINamespaceKind:
|
||||||
|
case DIModuleKind:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1623,6 +1625,66 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief A (clang) module that has been imported by the compile unit.
|
||||||
|
///
|
||||||
|
class DIModule : public DIScope {
|
||||||
|
friend class LLVMContextImpl;
|
||||||
|
friend class MDNode;
|
||||||
|
|
||||||
|
DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
|
||||||
|
: DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
|
||||||
|
~DIModule() {}
|
||||||
|
|
||||||
|
static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
|
||||||
|
StringRef Name, StringRef ConfigurationMacros,
|
||||||
|
StringRef IncludePath, StringRef ISysRoot,
|
||||||
|
StorageType Storage, bool ShouldCreate = true) {
|
||||||
|
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
|
||||||
|
getCanonicalMDString(Context, ConfigurationMacros),
|
||||||
|
getCanonicalMDString(Context, IncludePath),
|
||||||
|
getCanonicalMDString(Context, ISysRoot),
|
||||||
|
Storage, ShouldCreate);
|
||||||
|
}
|
||||||
|
static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
|
||||||
|
MDString *Name, MDString *ConfigurationMacros,
|
||||||
|
MDString *IncludePath, MDString *ISysRoot,
|
||||||
|
StorageType Storage, bool ShouldCreate = true);
|
||||||
|
|
||||||
|
TempDIModule cloneImpl() const {
|
||||||
|
return getTemporary(getContext(), getScope(), getName(),
|
||||||
|
getConfigurationMacros(), getIncludePath(),
|
||||||
|
getISysRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
|
||||||
|
StringRef ConfigurationMacros, StringRef IncludePath,
|
||||||
|
StringRef ISysRoot),
|
||||||
|
(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
|
||||||
|
DEFINE_MDNODE_GET(DIModule,
|
||||||
|
(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
|
||||||
|
MDString *IncludePath, MDString *ISysRoot),
|
||||||
|
(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot))
|
||||||
|
|
||||||
|
TempDIModule clone() const { return cloneImpl(); }
|
||||||
|
|
||||||
|
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
|
||||||
|
StringRef getName() const { return getStringOperand(1); }
|
||||||
|
StringRef getConfigurationMacros() const { return getStringOperand(2); }
|
||||||
|
StringRef getIncludePath() const { return getStringOperand(3); }
|
||||||
|
StringRef getISysRoot() const { return getStringOperand(4); }
|
||||||
|
|
||||||
|
Metadata *getRawScope() const { return getOperand(0); }
|
||||||
|
MDString *getRawName() const { return getOperandAs<MDString>(1); }
|
||||||
|
MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
|
||||||
|
MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
|
||||||
|
MDString *getRawISysRoot() const { return getOperandAs<MDString>(4); }
|
||||||
|
|
||||||
|
static bool classof(const Metadata *MD) {
|
||||||
|
return MD->getMetadataID() == DIModuleKind;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief Base class for template parameters.
|
/// \brief Base class for template parameters.
|
||||||
class DITemplateParameter : public DINode {
|
class DITemplateParameter : public DINode {
|
||||||
protected:
|
protected:
|
||||||
|
@ -82,6 +82,7 @@ HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase)
|
|||||||
HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlock)
|
HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlock)
|
||||||
HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlockFile)
|
HANDLE_SPECIALIZED_MDNODE_LEAF(DILexicalBlockFile)
|
||||||
HANDLE_SPECIALIZED_MDNODE_LEAF(DINamespace)
|
HANDLE_SPECIALIZED_MDNODE_LEAF(DINamespace)
|
||||||
|
HANDLE_SPECIALIZED_MDNODE_LEAF(DIModule)
|
||||||
HANDLE_SPECIALIZED_MDNODE_BRANCH(DITemplateParameter)
|
HANDLE_SPECIALIZED_MDNODE_BRANCH(DITemplateParameter)
|
||||||
HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateTypeParameter)
|
HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateTypeParameter)
|
||||||
HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateValueParameter)
|
HANDLE_SPECIALIZED_MDNODE_LEAF(DITemplateValueParameter)
|
||||||
|
@ -76,6 +76,7 @@ public:
|
|||||||
DILexicalBlockKind,
|
DILexicalBlockKind,
|
||||||
DILexicalBlockFileKind,
|
DILexicalBlockFileKind,
|
||||||
DINamespaceKind,
|
DINamespaceKind,
|
||||||
|
DIModuleKind,
|
||||||
DITemplateTypeParameterKind,
|
DITemplateTypeParameterKind,
|
||||||
DITemplateValueParameterKind,
|
DITemplateValueParameterKind,
|
||||||
DIGlobalVariableKind,
|
DIGlobalVariableKind,
|
||||||
|
@ -3676,6 +3676,24 @@ bool LLParser::ParseDINamespace(MDNode *&Result, bool IsDistinct) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ParseDIModule:
|
||||||
|
/// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: "-DNDEBUG",
|
||||||
|
/// includePath: "/usr/include", isysroot: "/")
|
||||||
|
bool LLParser::ParseDIModule(MDNode *&Result, bool IsDistinct) {
|
||||||
|
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
|
||||||
|
REQUIRED(scope, MDField, ); \
|
||||||
|
REQUIRED(name, MDStringField, ); \
|
||||||
|
OPTIONAL(configMacros, MDStringField, ); \
|
||||||
|
OPTIONAL(includePath, MDStringField, ); \
|
||||||
|
OPTIONAL(isysroot, MDStringField, );
|
||||||
|
PARSE_MD_FIELDS();
|
||||||
|
#undef VISIT_MD_FIELDS
|
||||||
|
|
||||||
|
Result = GET_OR_DISTINCT(DIModule, (Context, scope.Val, name.Val,
|
||||||
|
configMacros.Val, includePath.Val, isysroot.Val));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// ParseDITemplateTypeParameter:
|
/// ParseDITemplateTypeParameter:
|
||||||
/// ::= !DITemplateTypeParameter(name: "Ty", type: !1)
|
/// ::= !DITemplateTypeParameter(name: "Ty", type: !1)
|
||||||
bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
|
bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
|
||||||
|
@ -1827,6 +1827,20 @@ std::error_code BitcodeReader::parseMetadata() {
|
|||||||
NextMDValueNo++);
|
NextMDValueNo++);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case bitc::METADATA_MODULE: {
|
||||||
|
if (Record.size() != 6)
|
||||||
|
return error("Invalid record");
|
||||||
|
|
||||||
|
MDValueList.assignValue(
|
||||||
|
GET_OR_DISTINCT(DIModule, Record[0],
|
||||||
|
(Context, getMDOrNull(Record[1]),
|
||||||
|
getMDString(Record[2]), getMDString(Record[3]),
|
||||||
|
getMDString(Record[4]), getMDString(Record[5]))),
|
||||||
|
NextMDValueNo++);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case bitc::METADATA_FILE: {
|
case bitc::METADATA_FILE: {
|
||||||
if (Record.size() != 3)
|
if (Record.size() != 3)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
@ -1032,6 +1032,17 @@ static void WriteDINamespace(const DINamespace *N, const ValueEnumerator &VE,
|
|||||||
Record.clear();
|
Record.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WriteDIModule(const DIModule *N, const ValueEnumerator &VE,
|
||||||
|
BitstreamWriter &Stream,
|
||||||
|
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) {
|
||||||
|
Record.push_back(N->isDistinct());
|
||||||
|
for (auto &I : N->operands())
|
||||||
|
Record.push_back(VE.getMetadataOrNullID(I));
|
||||||
|
|
||||||
|
Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev);
|
||||||
|
Record.clear();
|
||||||
|
}
|
||||||
|
|
||||||
static void WriteDITemplateTypeParameter(const DITemplateTypeParameter *N,
|
static void WriteDITemplateTypeParameter(const DITemplateTypeParameter *N,
|
||||||
const ValueEnumerator &VE,
|
const ValueEnumerator &VE,
|
||||||
BitstreamWriter &Stream,
|
BitstreamWriter &Stream,
|
||||||
|
@ -1723,6 +1723,20 @@ static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
|
|||||||
Out << ")";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void writeDIModule(raw_ostream &Out, const DIModule *N,
|
||||||
|
TypePrinting *TypePrinter, SlotTracker *Machine,
|
||||||
|
const Module *Context) {
|
||||||
|
Out << "!DIModule(";
|
||||||
|
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
|
||||||
|
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
|
||||||
|
Printer.printString("name", N->getName());
|
||||||
|
Printer.printString("configMacros", N->getConfigurationMacros());
|
||||||
|
Printer.printString("includePath", N->getIncludePath());
|
||||||
|
Printer.printString("isysroot", N->getISysRoot());
|
||||||
|
Out << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void writeDITemplateTypeParameter(raw_ostream &Out,
|
static void writeDITemplateTypeParameter(raw_ostream &Out,
|
||||||
const DITemplateTypeParameter *N,
|
const DITemplateTypeParameter *N,
|
||||||
TypePrinting *TypePrinter,
|
TypePrinting *TypePrinter,
|
||||||
|
@ -186,6 +186,12 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
|
|||||||
Context, NS, Line, StringRef(), AllImportedModules);
|
Context, NS, Line, StringRef(), AllImportedModules);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,
|
||||||
|
unsigned Line) {
|
||||||
|
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
|
||||||
|
Context, M, Line, StringRef(), AllImportedModules);
|
||||||
|
}
|
||||||
|
|
||||||
DIImportedEntity *DIBuilder::createImportedDeclaration(DIScope *Context,
|
DIImportedEntity *DIBuilder::createImportedDeclaration(DIScope *Context,
|
||||||
DINode *Decl,
|
DINode *Decl,
|
||||||
unsigned Line,
|
unsigned Line,
|
||||||
@ -703,6 +709,14 @@ DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name,
|
|||||||
LineNo);
|
LineNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name,
|
||||||
|
StringRef ConfigurationMacros,
|
||||||
|
StringRef IncludePath,
|
||||||
|
StringRef ISysRoot) {
|
||||||
|
return DIModule::get(VMContext, getNonCompileUnitScope(Scope), Name,
|
||||||
|
ConfigurationMacros, IncludePath, ISysRoot);
|
||||||
|
}
|
||||||
|
|
||||||
DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,
|
DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,
|
||||||
DIFile *File,
|
DIFile *File,
|
||||||
unsigned Discriminator) {
|
unsigned Discriminator) {
|
||||||
|
@ -145,6 +145,8 @@ void DebugInfoFinder::processModule(const Module &M) {
|
|||||||
processSubprogram(SP);
|
processSubprogram(SP);
|
||||||
else if (auto *NS = dyn_cast<DINamespace>(Entity))
|
else if (auto *NS = dyn_cast<DINamespace>(Entity))
|
||||||
processScope(NS->getScope());
|
processScope(NS->getScope());
|
||||||
|
else if (auto *M = dyn_cast<DIModule>(Entity))
|
||||||
|
processScope(M->getScope());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,6 +203,8 @@ void DebugInfoFinder::processScope(DIScope *Scope) {
|
|||||||
processScope(LB->getScope());
|
processScope(LB->getScope());
|
||||||
} else if (auto *NS = dyn_cast<DINamespace>(Scope)) {
|
} else if (auto *NS = dyn_cast<DINamespace>(Scope)) {
|
||||||
processScope(NS->getScope());
|
processScope(NS->getScope());
|
||||||
|
} else if (auto *M = dyn_cast<DIModule>(Scope)) {
|
||||||
|
processScope(M->getScope());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,9 @@ DIScopeRef DIScope::getScope() const {
|
|||||||
if (auto *NS = dyn_cast<DINamespace>(this))
|
if (auto *NS = dyn_cast<DINamespace>(this))
|
||||||
return DIScopeRef(NS->getScope());
|
return DIScopeRef(NS->getScope());
|
||||||
|
|
||||||
|
if (auto *M = dyn_cast<DIModule>(this))
|
||||||
|
return DIScopeRef(M->getScope());
|
||||||
|
|
||||||
assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
|
assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
|
||||||
"Unhandled type of scope.");
|
"Unhandled type of scope.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -150,6 +153,8 @@ StringRef DIScope::getName() const {
|
|||||||
return SP->getName();
|
return SP->getName();
|
||||||
if (auto *NS = dyn_cast<DINamespace>(this))
|
if (auto *NS = dyn_cast<DINamespace>(this))
|
||||||
return NS->getName();
|
return NS->getName();
|
||||||
|
if (auto *M = dyn_cast<DIModule>(this))
|
||||||
|
return M->getName();
|
||||||
assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
|
assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
|
||||||
isa<DICompileUnit>(this)) &&
|
isa<DICompileUnit>(this)) &&
|
||||||
"Unhandled type of scope.");
|
"Unhandled type of scope.");
|
||||||
@ -410,6 +415,18 @@ DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
|
|||||||
DEFINE_GETIMPL_STORE(DINamespace, (Line), Ops);
|
DEFINE_GETIMPL_STORE(DINamespace, (Line), Ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope,
|
||||||
|
MDString *Name, MDString *ConfigurationMacros,
|
||||||
|
MDString *IncludePath, MDString *ISysRoot,
|
||||||
|
StorageType Storage, bool ShouldCreate) {
|
||||||
|
assert(isCanonical(Name) && "Expected canonical MDString");
|
||||||
|
DEFINE_GETIMPL_LOOKUP(DIModule,
|
||||||
|
(Scope, getString(Name), getString(ConfigurationMacros),
|
||||||
|
getString(IncludePath), getString(ISysRoot)));
|
||||||
|
Metadata *Ops[] = {Scope, Name, ConfigurationMacros, IncludePath, ISysRoot};
|
||||||
|
DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIModule, Ops);
|
||||||
|
}
|
||||||
|
|
||||||
DITemplateTypeParameter *DITemplateTypeParameter::getImpl(LLVMContext &Context,
|
DITemplateTypeParameter *DITemplateTypeParameter::getImpl(LLVMContext &Context,
|
||||||
MDString *Name,
|
MDString *Name,
|
||||||
Metadata *Type,
|
Metadata *Type,
|
||||||
|
@ -651,6 +651,35 @@ template <> struct MDNodeKeyImpl<DINamespace> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> struct MDNodeKeyImpl<DIModule> {
|
||||||
|
Metadata *Scope;
|
||||||
|
StringRef Name;
|
||||||
|
StringRef ConfigurationMacros;
|
||||||
|
StringRef IncludePath;
|
||||||
|
StringRef ISysRoot;
|
||||||
|
MDNodeKeyImpl(Metadata *Scope, StringRef Name,
|
||||||
|
StringRef ConfigurationMacros,
|
||||||
|
StringRef IncludePath,
|
||||||
|
StringRef ISysRoot)
|
||||||
|
: Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros),
|
||||||
|
IncludePath(IncludePath), ISysRoot(ISysRoot) {}
|
||||||
|
MDNodeKeyImpl(const DIModule *N)
|
||||||
|
: Scope(N->getRawScope()), Name(N->getName()),
|
||||||
|
ConfigurationMacros(N->getConfigurationMacros()),
|
||||||
|
IncludePath(N->getIncludePath()), ISysRoot(N->getISysRoot()) {}
|
||||||
|
|
||||||
|
bool isKeyOf(const DIModule *RHS) const {
|
||||||
|
return Scope == RHS->getRawScope() && Name == RHS->getName() &&
|
||||||
|
ConfigurationMacros == RHS->getConfigurationMacros() &&
|
||||||
|
IncludePath == RHS->getIncludePath() &&
|
||||||
|
ISysRoot == RHS->getISysRoot();
|
||||||
|
}
|
||||||
|
unsigned getHashValue() const {
|
||||||
|
return hash_combine(Scope, Name,
|
||||||
|
ConfigurationMacros, IncludePath, ISysRoot);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <> struct MDNodeKeyImpl<DITemplateTypeParameter> {
|
template <> struct MDNodeKeyImpl<DITemplateTypeParameter> {
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
Metadata *Type;
|
Metadata *Type;
|
||||||
|
@ -1017,6 +1017,11 @@ void Verifier::visitDINamespace(const DINamespace &N) {
|
|||||||
Assert(isa<DIScope>(S), "invalid scope ref", &N, S);
|
Assert(isa<DIScope>(S), "invalid scope ref", &N, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Verifier::visitDIModule(const DIModule &N) {
|
||||||
|
Assert(N.getTag() == dwarf::DW_TAG_module, "invalid tag", &N);
|
||||||
|
Assert(!N.getName().empty(), "anonymous module", &N);
|
||||||
|
}
|
||||||
|
|
||||||
void Verifier::visitDITemplateParameter(const DITemplateParameter &N) {
|
void Verifier::visitDITemplateParameter(const DITemplateParameter &N) {
|
||||||
Assert(isTypeRef(N, N.getType()), "invalid type ref", &N, N.getType());
|
Assert(isTypeRef(N, N.getType()), "invalid type ref", &N, N.getType());
|
||||||
}
|
}
|
||||||
|
15
test/Assembler/dimodule.ll
Normal file
15
test/Assembler/dimodule.ll
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||||
|
; RUN: verify-uselistorder %s
|
||||||
|
|
||||||
|
; CHECK: !named = !{!0, !1, !2, !1}
|
||||||
|
!named = !{!0, !1, !2, !3}
|
||||||
|
|
||||||
|
!0 = distinct !{}
|
||||||
|
|
||||||
|
; CHECK: !1 = !DIModule(scope: !0, name: "Module")
|
||||||
|
!1 = !DIModule(scope: !0, name: "Module")
|
||||||
|
|
||||||
|
; CHECK: !2 = !DIModule(scope: !0, name: "Module", configMacros: "-DNDEBUG", includePath: "/usr/include", isysroot: "/")
|
||||||
|
!2 = !DIModule(scope: !0, name: "Module", configMacros: "-DNDEBUG", includePath: "/usr/include", isysroot: "/")
|
||||||
|
|
||||||
|
!3 = !DIModule(scope: !0, name: "Module", configMacros: "")
|
@ -1704,6 +1704,40 @@ TEST_F(DINamespaceTest, get) {
|
|||||||
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
|
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef MetadataTest DIModuleTest;
|
||||||
|
|
||||||
|
TEST_F(DIModuleTest, get) {
|
||||||
|
DIScope *Scope = getFile();
|
||||||
|
StringRef Name = "module";
|
||||||
|
StringRef ConfigMacro = "-DNDEBUG";
|
||||||
|
StringRef Includes = "-I.";
|
||||||
|
StringRef Sysroot = "/";
|
||||||
|
|
||||||
|
auto *N = DIModule::get(Context, Scope, Name, ConfigMacro, Includes, Sysroot);
|
||||||
|
|
||||||
|
EXPECT_EQ(dwarf::DW_TAG_module, N->getTag());
|
||||||
|
EXPECT_EQ(Scope, N->getScope());
|
||||||
|
EXPECT_EQ(Name, N->getName());
|
||||||
|
EXPECT_EQ(ConfigMacro, N->getConfigurationMacros());
|
||||||
|
EXPECT_EQ(Includes, N->getIncludePath());
|
||||||
|
EXPECT_EQ(Sysroot, N->getISysRoot());
|
||||||
|
EXPECT_EQ(N, DIModule::get(Context, Scope, Name,
|
||||||
|
ConfigMacro, Includes, Sysroot));
|
||||||
|
EXPECT_NE(N, DIModule::get(Context, getFile(), Name,
|
||||||
|
ConfigMacro, Includes, Sysroot));
|
||||||
|
EXPECT_NE(N, DIModule::get(Context, Scope, "other",
|
||||||
|
ConfigMacro, Includes, Sysroot));
|
||||||
|
EXPECT_NE(N, DIModule::get(Context, Scope, Name,
|
||||||
|
"other", Includes, Sysroot));
|
||||||
|
EXPECT_NE(N, DIModule::get(Context, Scope, Name,
|
||||||
|
ConfigMacro, "other", Sysroot));
|
||||||
|
EXPECT_NE(N, DIModule::get(Context, Scope, Name,
|
||||||
|
ConfigMacro, Includes, "other"));
|
||||||
|
|
||||||
|
TempDIModule Temp = N->clone();
|
||||||
|
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
|
||||||
|
}
|
||||||
|
|
||||||
typedef MetadataTest DITemplateTypeParameterTest;
|
typedef MetadataTest DITemplateTypeParameterTest;
|
||||||
|
|
||||||
TEST_F(DITemplateTypeParameterTest, get) {
|
TEST_F(DITemplateTypeParameterTest, get) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user