Index: include/llvm/IR/Module.h =================================================================== --- include/llvm/IR/Module.h +++ include/llvm/IR/Module.h @@ -23,6 +23,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/DataTypes.h" #include @@ -634,6 +635,14 @@ unsigned getDwarfVersion() const; /// @} +/// @name Utility functions for querying and setting PIC level +/// @{ + + /// \brief Returns the PIC level (small or large model) + PICLevel::Level getPICLevel() const; + + /// \brief Set the PIC level (small or large model) + void setPICLevel(PICLevel::Level PL); }; /// An raw_ostream inserter for modules. Index: include/llvm/Support/CodeGen.h =================================================================== --- include/llvm/Support/CodeGen.h +++ include/llvm/Support/CodeGen.h @@ -30,6 +30,10 @@ enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; } + namespace PICLevel { + enum Level { Default=0, Small=1, Large=2 }; + } + // TLS models. namespace TLSModel { enum Model { Index: lib/IR/Module.cpp =================================================================== --- lib/IR/Module.cpp +++ lib/IR/Module.cpp @@ -458,3 +458,16 @@ Entry.second.Name = &Entry; return &Entry.second; } + +PICLevel::Level Module::getPICLevel() const { + Value *Val = getModuleFlag("flag_pic"); + + if (Val == NULL) + return PICLevel::Default; + + return static_cast(cast(Val)->getZExtValue()); +} + +void Module::setPICLevel(PICLevel::Level PL) { + addModuleFlag(ModFlagBehavior::Error, "flag_pic", PL); +} Index: test/Linker/Inputs/module-flags-pic-1-b.ll =================================================================== --- /dev/null +++ test/Linker/Inputs/module-flags-pic-1-b.ll @@ -0,0 +1 @@ + Index: test/Linker/Inputs/module-flags-pic-2-b.ll =================================================================== --- /dev/null +++ test/Linker/Inputs/module-flags-pic-2-b.ll @@ -0,0 +1,3 @@ +!0 = metadata !{ i32 1, metadata !"flag_pic", i32 2 } + +!llvm.module.flags = !{!0} Index: test/Linker/module-flags-pic-1-a.ll =================================================================== --- /dev/null +++ test/Linker/module-flags-pic-1-a.ll @@ -0,0 +1,9 @@ +; RUN: llvm-link %s %p/Inputs/module-flags-pic-1-b.ll -S -o - | FileCheck %s + +; test linking modules with specified and default PIC levels + +!0 = metadata !{ i32 1, metadata !"flag_pic", i32 1 } + +!llvm.module.flags = !{!0} +; CHECK: !llvm.module.flags = !{!0} +; CHECK: !0 = metadata !{i32 1, metadata !"flag_pic", i32 1} Index: test/Linker/module-flags-pic-2-a.ll =================================================================== --- /dev/null +++ test/Linker/module-flags-pic-2-a.ll @@ -0,0 +1,10 @@ +; RUN: not llvm-link %s %p/Inputs/module-flags-pic-2-b.ll -S -o - 2> %t +; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s + +; test linking modules with two different PIC levels + +!0 = metadata !{ i32 1, metadata !"flag_pic", i32 1 } + +!llvm.module.flags = !{!0} + +; CHECK-ERRORS: ERROR: WARNING: linking module flags 'flag_pic': IDs have conflicting values