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 | 8dd938ed179267b2a3a5206c78e89530967f45a5 (patch) | |
tree | 717822f5eb6bb4634de0aa27f376262b71d85bae /lib/IR | |
parent | 096d617796228293810cb0443c6617b33c5afdc5 (diff) | |
download | external_llvm-8dd938ed179267b2a3a5206c78e89530967f45a5.zip external_llvm-8dd938ed179267b2a3a5206c78e89530967f45a5.tar.gz external_llvm-8dd938ed179267b2a3a5206c78e89530967f45a5.tar.bz2 |
[IR] Add verifier support for llvm.module.flags.
- Also, update the LangRef documentation on module flags to match the
implementation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172498 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/Verifier.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 4252764..5a4a5a7 100644 --- a/lib/IR/Verifier.cpp +++ b/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, |