Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -93,6 +93,7 @@ uint64_t parseExpr(ArrayRef &Tokens); uint64_t parsePrimary(ArrayRef &Tokens); uint64_t parseExpr1(ArrayRef &Tokens, uint64_t Lhs, int MinPrec); + uint64_t parseTernary(ArrayRef &Tokens, uint64_t Cond); typename ELFT::uint Dot; }; Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -97,6 +97,17 @@ return getInteger(Tok); } +template +uint64_t LinkerScript::parseTernary(ArrayRef &Tokens, + uint64_t Cond) { + next(Tokens); + uint64_t V = parseExpr(Tokens, Dot); + if (!expect(Tokens, ":")) + return 0; + uint64_t W = parseExpr(Tokens, Dot); + return Cond ? V : W; +} + static uint64_t apply(StringRef Op, uint64_t L, uint64_t R) { if (Op == "+") return L + R; @@ -126,6 +137,9 @@ while (!Tokens.empty()) { // Read an operator and an expression. StringRef Op1 = Tokens.front(); + if (Op1 == "?") + return parseTernary(Tokens, Lhs, Dot); + if (precedence(Op1) < MinPrec) return Lhs; next(Tokens); Index: lld/trunk/test/ELF/linkerscript-locationcounter.s =================================================================== --- lld/trunk/test/ELF/linkerscript-locationcounter.s +++ lld/trunk/test/ELF/linkerscript-locationcounter.s @@ -14,6 +14,10 @@ # RUN: .bracket : { *(.bracket) } \ # RUN: . = 0x17000 & 0x15000; \ # RUN: .and : { *(.and) } \ +# RUN: . = 0x1 ? 0x16000 : 0x999999; \ +# RUN: .ternary1 : { *(.ternary1) } \ +# RUN: . = 0x0 ? 0x999999 : 0x17000; \ +# RUN: .ternary2 : { *(.ternary2) } \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-readobj -s %t2 | FileCheck %s @@ -108,6 +112,36 @@ # CHECK-NEXT: AddressAlignment: # CHECK-NEXT: EntrySize: # CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .ternary1 +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x16000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .ternary2 +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x17000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } ## Mailformed number error. # RUN: echo "SECTIONS { \ @@ -149,6 +183,14 @@ # RUN: FileCheck --check-prefix=DIVZERO %s # DIVZERO: division by zero +## Broken ternary operator expression. +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1 ? 0x2; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=TERNERR %s +# TERNERR: : expected + .globl _start; _start: nop @@ -170,3 +212,9 @@ .section .and, "a" .quad 0 + +.section .ternary1, "a" +.quad 0 + +.section .ternary2, "a" +.quad 0