diff options
author | Daniel Dunbar <daniel@zuster.org> | 2013-01-15 01:22:53 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2013-01-15 01:22:53 +0000 |
commit | 25c4b5718bb665a0161bb06694fb9bbe4562d621 (patch) | |
tree | f176d3c87ce14ca8e42dc485c20e3c5376cc84e1 /llvm/lib/IR/Verifier.cpp | |
parent | 5f15a351144753c39ceedfde595d45c923772f50 (diff) | |
download | bcm5719-llvm-25c4b5718bb665a0161bb06694fb9bbe4562d621.tar.gz bcm5719-llvm-25c4b5718bb665a0161bb06694fb9bbe4562d621.zip |
[IR] Add verifier support for llvm.module.flags.
- Also, update the LangRef documentation on module flags to match the
implementation.
llvm-svn: 172498
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 4252764f7a0..5a4a5a790ed 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -200,6 +200,8 @@ namespace { E = M.named_metadata_end(); I != E; ++I) visitNamedMDNode(*I); + visitModuleFlags(M); + // If the module is broken, abort at this time. return abortIfBroken(); } @@ -240,6 +242,8 @@ namespace { void visitGlobalAlias(GlobalAlias &GA); void visitNamedMDNode(NamedMDNode &NMD); void visitMDNode(MDNode &MD, Function *F); + void visitModuleFlags(Module &M); + void visitModuleFlag(MDNode *Op, SmallSetVector<MDString*, 16> &SeenIDs); void visitFunction(Function &F); void visitBasicBlock(BasicBlock &BB); using InstVisitor<Verifier>::visit; @@ -521,6 +525,59 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } +void Verifier::visitModuleFlags(Module &M) { + const NamedMDNode *Flags = M.getModuleFlagsMetadata(); + if (!Flags) return; + + // Scan each flag. + SmallSetVector<MDString*, 16> SeenIDs; + for (unsigned I = 0, E = Flags->getNumOperands(); I != E; ++I) { + visitModuleFlag(Flags->getOperand(I), SeenIDs); + } +} + +void Verifier::visitModuleFlag(MDNode *Op, + SmallSetVector<MDString*, 16> &SeenIDs) { + // Each module flag should have three arguments, the merge behavior (a + // constant int), the flag ID (an MDString), and the value. + Assert1(Op->getNumOperands() == 3, + "incorrect number of operands in module flag", Op); + ConstantInt *Behavior = dyn_cast<ConstantInt>(Op->getOperand(0)); + MDString *ID = dyn_cast<MDString>(Op->getOperand(1)); + Assert1(Behavior, + "invalid behavior operand in module flag (expected constant integer)", + Op->getOperand(0)); + unsigned BehaviorValue = Behavior->getZExtValue(); + Assert1((Module::Error <= BehaviorValue && + BehaviorValue <= Module::Override), + "invalid behavior operand in module flag (unexpected constant)", + Op->getOperand(0)); + Assert1(ID, + "invalid ID operand in module flag (expected metadata string)", + Op->getOperand(1)); + + // Unless this is a "requires" flag, check the ID is unique. + if (BehaviorValue != Module::Require) { + Assert1(SeenIDs.insert(ID), + "module flag identifiers must be unique (or of 'require' type)", + ID); + } + + // If this is a "requires" flag, sanity check the value. + if (BehaviorValue == Module::Require) { + // The value should itself be an MDNode with two operands, a flag ID (an + // MDString), and a value. + MDNode *Value = dyn_cast<MDNode>(Op->getOperand(2)); + Assert1(Value && Value->getNumOperands() == 2, + "invalid value for 'require' module flag (expected metadata pair)", + Op->getOperand(2)); + Assert1(isa<MDString>(Value->getOperand(0)), + ("invalid value for 'require' module flag " + "(first value operand should be a string)"), + Value->getOperand(0)); + } +} + // VerifyParameterAttrs - Check the given attributes for an argument or return // value of the specified type. The value V is printed in error messages. void Verifier::VerifyParameterAttrs(Attribute Attrs, Type *Ty, |