aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR
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
commit8dd938ed179267b2a3a5206c78e89530967f45a5 (patch)
tree717822f5eb6bb4634de0aa27f376262b71d85bae /lib/IR
parent096d617796228293810cb0443c6617b33c5afdc5 (diff)
downloadexternal_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.cpp57
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,