summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2013-01-15 01:22:53 +0000
committerDaniel Dunbar <daniel@zuster.org>2013-01-15 01:22:53 +0000
commit25c4b5718bb665a0161bb06694fb9bbe4562d621 (patch)
treef176d3c87ce14ca8e42dc485c20e3c5376cc84e1 /llvm/lib/IR/Verifier.cpp
parent5f15a351144753c39ceedfde595d45c923772f50 (diff)
downloadbcm5719-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.cpp57
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,
OpenPOWER on IntegriCloud