Skip to content

Commit 295172e

Browse files
committed
[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
1 parent 6c0af92 commit 295172e

File tree

12 files changed

+62
-8
lines changed

12 files changed

+62
-8
lines changed

llvm/include/llvm/AsmParser/LLLexer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace llvm {
3737
lltok::Kind CurKind;
3838
std::string StrVal;
3939
unsigned UIntVal;
40-
Type *TyVal;
40+
Type *TyVal = nullptr;
4141
APFloat APFloatVal;
4242
APSInt APSIntVal;
4343

llvm/include/llvm/AsmParser/LLParser.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ namespace llvm {
9595
typedef LLLexer::LocTy LocTy;
9696
private:
9797
LLVMContext &Context;
98+
// Lexer to determine whether to use opaque pointers or not.
99+
LLLexer OPLex;
98100
LLLexer Lex;
99101
// Module being parsed, null if we are only parsing summary index.
100102
Module *M;
@@ -157,8 +159,9 @@ namespace llvm {
157159
LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M,
158160
ModuleSummaryIndex *Index, LLVMContext &Context,
159161
SlotMapping *Slots = nullptr)
160-
: Context(Context), Lex(F, SM, Err, Context), M(M), Index(Index),
161-
Slots(Slots), BlockAddressPFS(nullptr) {}
162+
: Context(Context), OPLex(F, SM, Err, Context),
163+
Lex(F, SM, Err, Context), M(M), Index(Index), Slots(Slots),
164+
BlockAddressPFS(nullptr) {}
162165
bool Run(
163166
bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback =
164167
[](StringRef) { return None; });

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ class LLVMContext {
305305
/// LLVMContext is used by compilation.
306306
void setOptPassGate(OptPassGate&);
307307

308+
/// Whether we've decided on using opaque pointers or typed pointers yet.
309+
bool hasSetOpaquePointersValue() const;
310+
308311
/// Enable opaque pointers. Can only be called before creating the first
309312
/// pointer type.
310313
void enableOpaquePointers() const;

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,10 @@ lltok::Kind LLLexer::LexIdentifier() {
860860
TYPEKEYWORD("token", Type::getTokenTy(Context));
861861

862862
if (Keyword == "ptr") {
863-
if (Context.supportsTypedPointers()) {
863+
// enableOpaquePointers() must be called before creating any pointer types.
864+
if (!Context.hasSetOpaquePointersValue()) {
865+
Context.enableOpaquePointers();
866+
} else if (Context.supportsTypedPointers()) {
864867
Warning("ptr type is only supported in -opaque-pointers mode");
865868
return lltok::Error;
866869
}

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,29 @@ static std::string getTypeString(Type *T) {
5959
return Tmp.str();
6060
}
6161

62+
static void setContextOpaquePointers(LLLexer &L, LLVMContext &C) {
63+
while (true) {
64+
lltok::Kind K = L.Lex();
65+
// LLLexer will set the opaque pointers option in LLVMContext if it sees an
66+
// explicit "ptr".
67+
if (K == lltok::star || K == lltok::Error || K == lltok::Eof ||
68+
isa_and_nonnull<PointerType>(L.getTyVal())) {
69+
return;
70+
}
71+
}
72+
}
73+
6274
/// Run: module ::= toplevelentity*
6375
bool LLParser::Run(bool UpgradeDebugInfo,
6476
DataLayoutCallbackTy DataLayoutCallback) {
77+
// If we haven't decided on whether or not we're using opaque pointers, do a
78+
// quick lex over the tokens to see if we explicitly construct any typed or
79+
// opaque pointer types.
80+
// Don't bail out on an error so we do the same work in the parsing below
81+
// regardless of if --opaque-pointers is set.
82+
if (!Context.hasSetOpaquePointersValue())
83+
setContextOpaquePointers(OPLex, Context);
84+
6585
// Prime the lexer.
6686
Lex.Lex();
6787

llvm/lib/IR/LLVMContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
351351
return std::move(pImpl->DiagHandler);
352352
}
353353

354+
bool LLVMContext::hasSetOpaquePointersValue() const {
355+
return pImpl->hasOpaquePointersValue();
356+
}
357+
354358
void LLVMContext::enableOpaquePointers() const {
355359
assert(pImpl->PointerTypes.empty() && pImpl->ASPointerTypes.empty() &&
356360
"Must be called before creating any pointer types");

llvm/lib/IR/LLVMContextImpl.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
4747
X86_FP80Ty(C, Type::X86_FP80TyID), FP128Ty(C, Type::FP128TyID),
4848
PPC_FP128Ty(C, Type::PPC_FP128TyID), X86_MMXTy(C, Type::X86_MMXTyID),
4949
X86_AMXTy(C, Type::X86_AMXTyID), Int1Ty(C, 1), Int8Ty(C, 8),
50-
Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {}
50+
Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), Int128Ty(C, 128) {
51+
if (OpaquePointersCL.getNumOccurrences()) {
52+
OpaquePointers = OpaquePointersCL;
53+
}
54+
}
5155

5256
LLVMContextImpl::~LLVMContextImpl() {
5357
// NOTE: We need to delete the contents of OwnedModules, but Module's dtor
@@ -245,9 +249,13 @@ void LLVMContextImpl::setOptPassGate(OptPassGate& OPG) {
245249
this->OPG = &OPG;
246250
}
247251

252+
bool LLVMContextImpl::hasOpaquePointersValue() {
253+
return OpaquePointers.hasValue();
254+
}
255+
248256
bool LLVMContextImpl::getOpaquePointers() {
249257
if (LLVM_UNLIKELY(!(OpaquePointers.hasValue())))
250-
OpaquePointers = OpaquePointersCL;
258+
OpaquePointers = false;
251259
return *OpaquePointers;
252260
}
253261

llvm/lib/IR/LLVMContextImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,7 @@ class LLVMContextImpl {
15551555
// TODO: clean up the following after we no longer support non-opaque pointer
15561556
// types.
15571557
bool getOpaquePointers();
1558+
bool hasOpaquePointersValue();
15581559
void setOpaquePointers(bool OP);
15591560

15601561
private:

llvm/test/Assembler/ptr-outside-opaque-pointers-mode.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
1+
; RUN: not llvm-as < %s -disable-output --opaque-pointers=0 2>&1 | FileCheck %s
22

33
; CHECK: warning: ptr type is only supported in -opaque-pointers mode
44
; CHECK: error: expected type

llvm/test/Other/force-opaque-ptrs-typed-dis.ll renamed to llvm/test/Bitcode/opaque-ptr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llvm-as --opaque-pointers < %s | not llvm-dis 2>&1 | FileCheck %s
1+
; RUN: llvm-as --opaque-pointers < %s | not llvm-dis --opaque-pointers=0 2>&1 | FileCheck %s
22

33
; CHECK: error: Opaque pointers are only supported in -opaque-pointers mode
44

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
; RUN: llvm-as -disable-output %s 2>&1
2+
; FIXME: this should err out saying not to mix `ptr` and `foo*`
3+
define void @f(ptr) {
4+
%a = alloca i32*
5+
ret void
6+
}

llvm/test/Other/mixed-opaque-ptrs.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
; RUN: not llvm-as -disable-output %s 2>&1 | FileCheck %s
2+
; CHECK: ptr type is only supported in -opaque-pointers mode
3+
define void @f(i32*) {
4+
%a = alloca ptr
5+
ret void
6+
}

0 commit comments

Comments
 (0)