forked from OSchip/llvm-project
[OpaquePtr][LLParser] Automatically detect opaque pointers in .ll files
This allows us to not have to specify -opaque-pointers when updating IR tests from typed pointers to opaque pointers. We detect opaque pointers in .ll files by looking for relevant tokens, either "ptr" or "*". Reviewed By: #opaque-pointers, nikic Differential Revision: https://reviews.llvm.org/D119482
This commit is contained in:
parent
6c0af92612
commit
295172ef51
|
@ -37,7 +37,7 @@ namespace llvm {
|
||||||
lltok::Kind CurKind;
|
lltok::Kind CurKind;
|
||||||
std::string StrVal;
|
std::string StrVal;
|
||||||
unsigned UIntVal;
|
unsigned UIntVal;
|
||||||
Type *TyVal;
|
Type *TyVal = nullptr;
|
||||||
APFloat APFloatVal;
|
APFloat APFloatVal;
|
||||||
APSInt APSIntVal;
|
APSInt APSIntVal;
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,8 @@ namespace llvm {
|
||||||
typedef LLLexer::LocTy LocTy;
|
typedef LLLexer::LocTy LocTy;
|
||||||
private:
|
private:
|
||||||
LLVMContext &Context;
|
LLVMContext &Context;
|
||||||
|
// Lexer to determine whether to use opaque pointers or not.
|
||||||
|
LLLexer OPLex;
|
||||||
LLLexer Lex;
|
LLLexer Lex;
|
||||||
// Module being parsed, null if we are only parsing summary index.
|
// Module being parsed, null if we are only parsing summary index.
|
||||||
Module *M;
|
Module *M;
|
||||||
|
@ -157,8 +159,9 @@ namespace llvm {
|
||||||
LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M,
|
LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M,
|
||||||
ModuleSummaryIndex *Index, LLVMContext &Context,
|
ModuleSummaryIndex *Index, LLVMContext &Context,
|
||||||
SlotMapping *Slots = nullptr)
|
SlotMapping *Slots = nullptr)
|
||||||
: Context(Context), Lex(F, SM, Err, Context), M(M), Index(Index),
|
: Context(Context), OPLex(F, SM, Err, Context),
|
||||||
Slots(Slots), BlockAddressPFS(nullptr) {}
|
Lex(F, SM, Err, Context), M(M), Index(Index), Slots(Slots),
|
||||||
|
BlockAddressPFS(nullptr) {}
|
||||||
bool Run(
|
bool Run(
|
||||||
bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback =
|
bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback =
|
||||||
[](StringRef) { return None; });
|
[](StringRef) { return None; });
|
||||||
|
|
|
@ -305,6 +305,9 @@ public:
|
||||||
/// LLVMContext is used by compilation.
|
/// LLVMContext is used by compilation.
|
||||||
void setOptPassGate(OptPassGate&);
|
void setOptPassGate(OptPassGate&);
|
||||||
|
|
||||||
|
/// Whether we've decided on using opaque pointers or typed pointers yet.
|
||||||
|
bool hasSetOpaquePointersValue() const;
|
||||||
|
|
||||||
/// Enable opaque pointers. Can only be called before creating the first
|
/// Enable opaque pointers. Can only be called before creating the first
|
||||||
/// pointer type.
|
/// pointer type.
|
||||||
void enableOpaquePointers() const;
|
void enableOpaquePointers() const;
|
||||||
|
|
|
@ -860,7 +860,10 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||||
TYPEKEYWORD("token", Type::getTokenTy(Context));
|
TYPEKEYWORD("token", Type::getTokenTy(Context));
|
||||||
|
|
||||||
if (Keyword == "ptr") {
|
if (Keyword == "ptr") {
|
||||||
if (Context.supportsTypedPointers()) {
|
// enableOpaquePointers() must be called before creating any pointer types.
|
||||||
|
if (!Context.hasSetOpaquePointersValue()) {
|
||||||
|
Context.enableOpaquePointers();
|
||||||
|
} else if (Context.supportsTypedPointers()) {
|
||||||
Warning("ptr type is only supported in -opaque-pointers mode");
|
Warning("ptr type is only supported in -opaque-pointers mode");
|
||||||
return lltok::Error;
|
return lltok::Error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,9 +59,29 @@ static std::string getTypeString(Type *T) {
|
||||||
return Tmp.str();
|
return Tmp.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setContextOpaquePointers(LLLexer &L, LLVMContext &C) {
|
||||||
|
while (true) {
|
||||||
|
lltok::Kind K = L.Lex();
|
||||||
|
// LLLexer will set the opaque pointers option in LLVMContext if it sees an
|
||||||
|
// explicit "ptr".
|
||||||
|
if (K == lltok::star || K == lltok::Error || K == lltok::Eof ||
|
||||||
|
isa_and_nonnull<PointerType>(L.getTyVal())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run: module ::= toplevelentity*
|
/// Run: module ::= toplevelentity*
|
||||||
bool LLParser::Run(bool UpgradeDebugInfo,
|
bool LLParser::Run(bool UpgradeDebugInfo,
|
||||||
DataLayoutCallbackTy DataLayoutCallback) {
|
DataLayoutCallbackTy DataLayoutCallback) {
|
||||||
|
// If we haven't decided on whether or not we're using opaque pointers, do a
|
||||||
|
// quick lex over the tokens to see if we explicitly construct any typed or
|
||||||
|
// opaque pointer types.
|
||||||
|
// Don't bail out on an error so we do the same work in the parsing below
|
||||||
|
// regardless of if --opaque-pointers is set.
|
||||||
|
if (!Context.hasSetOpaquePointersValue())
|
||||||
|
setContextOpaquePointers(OPLex, Context);
|
||||||
|
|
||||||
// Prime the lexer.
|
// Prime the lexer.
|
||||||
Lex.Lex();
|
Lex.Lex();
|
||||||
|
|
||||||
|
|
|
@ -351,6 +351,10 @@ std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
|
||||||
return std::move(pImpl->DiagHandler);
|
return std::move(pImpl->DiagHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LLVMContext::hasSetOpaquePointersValue() const {
|
||||||
|
return pImpl->hasOpaquePointersValue();
|
||||||
|
}
|
||||||
|
|
||||||
void LLVMContext::enableOpaquePointers() const {
|
void LLVMContext::enableOpaquePointers() const {
|
||||||
assert(pImpl->PointerTypes.empty() && pImpl->ASPointerTypes.empty() &&
|
assert(pImpl->PointerTypes.empty() && pImpl->ASPointerTypes.empty() &&
|
||||||
"Must be called before creating any pointer types");
|
"Must be called before creating any pointer types");
|
||||||
|
|
|
@ -47,7 +47,11 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
|
||||||
X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),
|
X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),
|
||||||
PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID),
|
PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID),
|
||||||
X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8),
|
X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8),
|
||||||
Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {}
|
Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {
|
||||||
|
if (OpaquePointersCL.getNumOccurrences()) {
|
||||||
|
OpaquePointers = OpaquePointersCL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LLVMContextImpl::~LLVMContextImpl() {
|
LLVMContextImpl::~LLVMContextImpl() {
|
||||||
// NOTE: We need to delete the contents of OwnedModules, but Module's dtor
|
// NOTE: We need to delete the contents of OwnedModules, but Module's dtor
|
||||||
|
@ -245,9 +249,13 @@ void LLVMContextImpl::setOptPassGate(OptPassGate& OPG) {
|
||||||
this->OPG = &OPG;
|
this->OPG = &OPG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LLVMContextImpl::hasOpaquePointersValue() {
|
||||||
|
return OpaquePointers.hasValue();
|
||||||
|
}
|
||||||
|
|
||||||
bool LLVMContextImpl::getOpaquePointers() {
|
bool LLVMContextImpl::getOpaquePointers() {
|
||||||
if (LLVM_UNLIKELY(!(OpaquePointers.hasValue())))
|
if (LLVM_UNLIKELY(!(OpaquePointers.hasValue())))
|
||||||
OpaquePointers = OpaquePointersCL;
|
OpaquePointers = false;
|
||||||
return *OpaquePointers;
|
return *OpaquePointers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1555,6 +1555,7 @@ public:
|
||||||
// TODO: clean up the following after we no longer support non-opaque pointer
|
// TODO: clean up the following after we no longer support non-opaque pointer
|
||||||
// types.
|
// types.
|
||||||
bool getOpaquePointers();
|
bool getOpaquePointers();
|
||||||
|
bool hasOpaquePointersValue();
|
||||||
void setOpaquePointers(bool OP);
|
void setOpaquePointers(bool OP);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
; RUN: not llvm-as < %s -disable-output --opaque-pointers=0 2>&1 | FileCheck %s
|
||||||
|
|
||||||
; CHECK: warning: ptr type is only supported in -opaque-pointers mode
|
; CHECK: warning: ptr type is only supported in -opaque-pointers mode
|
||||||
; CHECK: error: expected type
|
; CHECK: error: expected type
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llvm-as --opaque-pointers < %s | not llvm-dis 2>&1 | FileCheck %s
|
; RUN: llvm-as --opaque-pointers < %s | not llvm-dis --opaque-pointers=0 2>&1 | FileCheck %s
|
||||||
|
|
||||||
; CHECK: error: Opaque pointers are only supported in -opaque-pointers mode
|
; CHECK: error: Opaque pointers are only supported in -opaque-pointers mode
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
; RUN: llvm-as -disable-output %s 2>&1
|
||||||
|
; FIXME: this should err out saying not to mix `ptr` and `foo*`
|
||||||
|
define void @f(ptr) {
|
||||||
|
%a = alloca i32*
|
||||||
|
ret void
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
|
||||||
|
; CHECK: ptr type is only supported in -opaque-pointers mode
|
||||||
|
define void @f(i32*) {
|
||||||
|
%a = alloca ptr
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue