Skip to content

Commit ec09d83

Browse files
Merge branch 'users/quic-garvgupt/link_order' into users/quic-garvgupt/undefined
2 parents beaabe6 + fa8aad1 commit ec09d83

File tree

110 files changed

+3172
-1325
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+3172
-1325
lines changed

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,9 @@ static std::vector<llvm::StringRef> semanticTokenModifiers() {
494494
void ClangdLSPServer::onInitialize(const InitializeParams &Params,
495495
Callback<llvm::json::Value> Reply) {
496496
// Determine character encoding first as it affects constructed ClangdServer.
497-
if (Params.capabilities.offsetEncoding && !Opts.Encoding) {
497+
if (Params.capabilities.PositionEncodings && !Opts.Encoding) {
498498
Opts.Encoding = OffsetEncoding::UTF16; // fallback
499-
for (OffsetEncoding Supported : *Params.capabilities.offsetEncoding)
499+
for (OffsetEncoding Supported : *Params.capabilities.PositionEncodings)
500500
if (Supported != OffsetEncoding::UnsupportedEncoding) {
501501
Opts.Encoding = Supported;
502502
break;
@@ -686,13 +686,19 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
686686
ServerCaps["executeCommandProvider"] =
687687
llvm::json::Object{{"commands", Commands}};
688688

689+
if (Opts.Encoding)
690+
ServerCaps["positionEncoding"] = *Opts.Encoding;
691+
689692
llvm::json::Object Result{
690693
{{"serverInfo",
691694
llvm::json::Object{
692695
{"name", "clangd"},
693696
{"version", llvm::formatv("{0} {1} {2}", versionString(),
694697
featureString(), platformString())}}},
695698
{"capabilities", std::move(ServerCaps)}}};
699+
700+
// TODO: offsetEncoding capability is a deprecated clangd extension and should
701+
// be deleted.
696702
if (Opts.Encoding)
697703
Result["offsetEncoding"] = *Opts.Encoding;
698704
Reply(std::move(Result));

clang-tools-extra/clangd/Protocol.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,19 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R,
497497
if (auto Cancel = StaleRequestSupport->getBoolean("cancel"))
498498
R.CancelsStaleRequests = *Cancel;
499499
}
500+
if (auto *PositionEncodings = General->get("positionEncodings")) {
501+
R.PositionEncodings.emplace();
502+
if (!fromJSON(*PositionEncodings, *R.PositionEncodings,
503+
P.field("general").field("positionEncodings")))
504+
return false;
505+
}
500506
}
501507
if (auto *OffsetEncoding = O->get("offsetEncoding")) {
502-
R.offsetEncoding.emplace();
503-
if (!fromJSON(*OffsetEncoding, *R.offsetEncoding,
508+
R.PositionEncodings.emplace();
509+
elog("offsetEncoding capability is a deprecated clangd extension that'll "
510+
"go away with clangd 23. Migrate to standard positionEncodings "
511+
"capability introduced by LSP 3.17");
512+
if (!fromJSON(*OffsetEncoding, *R.PositionEncodings,
504513
P.field("offsetEncoding")))
505514
return false;
506515
}
@@ -536,8 +545,11 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R,
536545
}
537546
}
538547
if (auto *OffsetEncoding = Experimental->get("offsetEncoding")) {
539-
R.offsetEncoding.emplace();
540-
if (!fromJSON(*OffsetEncoding, *R.offsetEncoding,
548+
R.PositionEncodings.emplace();
549+
elog("offsetEncoding capability is a deprecated clangd extension that'll "
550+
"go away with clangd 23. Migrate to standard positionEncodings "
551+
"capability introduced by LSP 3.17");
552+
if (!fromJSON(*OffsetEncoding, *R.PositionEncodings,
541553
P.field("offsetEncoding")))
542554
return false;
543555
}

clang-tools-extra/clangd/Protocol.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,9 @@ struct ClientCapabilities {
528528
/// textDocument.semanticHighlightingCapabilities.semanticHighlighting
529529
bool TheiaSemanticHighlighting = false;
530530

531-
/// Supported encodings for LSP character offsets. (clangd extension).
532-
std::optional<std::vector<OffsetEncoding>> offsetEncoding;
531+
/// Supported encodings for LSP character offsets.
532+
/// general.positionEncodings
533+
std::optional<std::vector<OffsetEncoding>> PositionEncodings;
533534

534535
/// The content format that should be used for Hover requests.
535536
/// textDocument.hover.contentEncoding
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s
2+
# This test verifies that we can negotiate UTF-8 offsets via the positionEncodings capability introduced in LSP 3.17.
3+
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{"general":{"positionEncodings":["utf-8","utf-16"]}},"trace":"off"}}
4+
# CHECK: "positionEncoding": "utf-8"
5+
---
6+
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"/*ö*/int x;\nint y=x;"}}}
7+
---
8+
{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":6}}}
9+
# /*ö*/int x;
10+
# 01234567890
11+
# x is character (and utf-16) range [9,10) but byte range [10,11).
12+
# CHECK: "id": 1,
13+
# CHECK-NEXT: "jsonrpc": "2.0",
14+
# CHECK-NEXT: "result": [
15+
# CHECK-NEXT: {
16+
# CHECK-NEXT: "range": {
17+
# CHECK-NEXT: "end": {
18+
# CHECK-NEXT: "character": 11,
19+
# CHECK-NEXT: "line": 0
20+
# CHECK-NEXT: },
21+
# CHECK-NEXT: "start": {
22+
# CHECK-NEXT: "character": 10,
23+
# CHECK-NEXT: "line": 0
24+
# CHECK-NEXT: }
25+
# CHECK-NEXT: },
26+
# CHECK-NEXT: "uri": "file://{{.*}}/main.cpp"
27+
# CHECK-NEXT: }
28+
# CHECK-NEXT: ]
29+
---
30+
{"jsonrpc":"2.0","id":10000,"method":"shutdown"}
31+
---
32+
{"jsonrpc":"2.0","method":"exit"}

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,8 @@ bool Compiler<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {
748748
if (DiscardResult)
749749
return true;
750750

751-
return this->emitConstFloat(E->getValue(), E);
751+
APFloat F = E->getValue();
752+
return this->emitFloat(F, E);
752753
}
753754

754755
template <class Emitter>
@@ -4185,8 +4186,10 @@ bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
41854186
nullptr, E);
41864187
case PT_MemberPtr:
41874188
return this->emitNullMemberPtr(0, nullptr, E);
4188-
case PT_Float:
4189-
return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
4189+
case PT_Float: {
4190+
APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
4191+
return this->emitFloat(F, E);
4192+
}
41904193
case PT_FixedPoint: {
41914194
auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
41924195
return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
@@ -4674,10 +4677,7 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
46744677
if (!visitInitializer(Init))
46754678
return false;
46764679

4677-
if (!this->emitFinishInit(Init))
4678-
return false;
4679-
4680-
return this->emitPopPtr(Init);
4680+
return this->emitFinishInitGlobal(Init);
46814681
};
46824682

46834683
DeclScope<Emitter> LocalScope(this, VD);
@@ -4698,51 +4698,45 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
46984698
return false;
46994699

47004700
return !Init || (checkDecl() && initGlobal(*GlobalIndex));
4701-
} else {
4702-
InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD));
4703-
4704-
if (VarT) {
4705-
unsigned Offset = this->allocateLocalPrimitive(
4706-
VD, *VarT, VD->getType().isConstQualified(), nullptr,
4707-
ScopeKind::Block, IsConstexprUnknown);
4708-
if (Init) {
4709-
// If this is a toplevel declaration, create a scope for the
4710-
// initializer.
4711-
if (Toplevel) {
4712-
LocalScope<Emitter> Scope(this);
4713-
if (!this->visit(Init))
4714-
return false;
4715-
return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
4716-
} else {
4717-
if (!this->visit(Init))
4718-
return false;
4719-
return this->emitSetLocal(*VarT, Offset, VD);
4720-
}
4721-
}
4722-
} else {
4723-
if (std::optional<unsigned> Offset =
4724-
this->allocateLocal(VD, VD->getType(), nullptr, ScopeKind::Block,
4725-
IsConstexprUnknown)) {
4726-
if (!Init)
4727-
return true;
4701+
}
4702+
// Local variables.
4703+
InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD));
47284704

4729-
if (!this->emitGetPtrLocal(*Offset, Init))
4705+
if (VarT) {
4706+
unsigned Offset = this->allocateLocalPrimitive(
4707+
VD, *VarT, VD->getType().isConstQualified(), nullptr, ScopeKind::Block,
4708+
IsConstexprUnknown);
4709+
if (Init) {
4710+
// If this is a toplevel declaration, create a scope for the
4711+
// initializer.
4712+
if (Toplevel) {
4713+
LocalScope<Emitter> Scope(this);
4714+
if (!this->visit(Init))
47304715
return false;
4731-
4732-
if (!visitInitializer(Init))
4716+
return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
4717+
} else {
4718+
if (!this->visit(Init))
47334719
return false;
4720+
return this->emitSetLocal(*VarT, Offset, VD);
4721+
}
4722+
}
4723+
} else {
4724+
if (std::optional<unsigned> Offset = this->allocateLocal(
4725+
VD, VD->getType(), nullptr, ScopeKind::Block, IsConstexprUnknown)) {
4726+
if (!Init)
4727+
return true;
47344728

4735-
if (!this->emitFinishInit(Init))
4736-
return false;
4729+
if (!this->emitGetPtrLocal(*Offset, Init))
4730+
return false;
47374731

4738-
return this->emitPopPtr(Init);
4739-
}
4740-
return false;
4732+
if (!visitInitializer(Init))
4733+
return false;
4734+
4735+
return this->emitFinishInitPop(Init);
47414736
}
4742-
return true;
4737+
return false;
47434738
}
4744-
4745-
return false;
4739+
return true;
47464740
}
47474741

47484742
template <class Emitter>
@@ -4751,8 +4745,10 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
47514745
assert(!DiscardResult);
47524746
if (Val.isInt())
47534747
return this->emitConst(Val.getInt(), ValType, E);
4754-
else if (Val.isFloat())
4755-
return this->emitConstFloat(Val.getFloat(), E);
4748+
else if (Val.isFloat()) {
4749+
APFloat F = Val.getFloat();
4750+
return this->emitFloat(F, E);
4751+
}
47564752

47574753
if (Val.isLValue()) {
47584754
if (Val.isNullPointer())
@@ -6133,8 +6129,10 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
61336129
const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
61346130
if (!this->emitLoadFloat(E))
61356131
return false;
6136-
if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
6132+
APFloat F(TargetSemantics, 1);
6133+
if (!this->emitFloat(F, E))
61376134
return false;
6135+
61386136
if (!this->emitAddf(getFPOptions(E), E))
61396137
return false;
61406138
if (!this->emitStoreFloat(E))
@@ -6176,8 +6174,10 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
61766174
const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
61776175
if (!this->emitLoadFloat(E))
61786176
return false;
6179-
if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
6177+
APFloat F(TargetSemantics, 1);
6178+
if (!this->emitFloat(F, E))
61806179
return false;
6180+
61816181
if (!this->emitSubf(getFPOptions(E), E))
61826182
return false;
61836183
if (!this->emitStoreFloat(E))
@@ -6953,6 +6953,20 @@ bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
69536953
return true;
69546954
}
69556955

6956+
template <class Emitter>
6957+
bool Compiler<Emitter>::emitFloat(const APFloat &F, const Expr *E) {
6958+
assert(!DiscardResult && "Should've been checked before");
6959+
6960+
if (Floating::singleWord(F.getSemantics()))
6961+
return this->emitConstFloat(Floating(F), E);
6962+
6963+
APInt I = F.bitcastToAPInt();
6964+
return this->emitConstFloat(
6965+
Floating(const_cast<uint64_t *>(I.getRawData()),
6966+
llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
6967+
E);
6968+
}
6969+
69566970
// This function is constexpr if and only if To, From, and the types of
69576971
// all subobjects of To and From are types T such that...
69586972
// (3.1) - is_union_v<T> is false;

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
391391
bool emitRecordDestruction(const Record *R, SourceInfo Loc);
392392
bool emitDestruction(const Descriptor *Desc, SourceInfo Loc);
393393
bool emitDummyPtr(const DeclTy &D, const Expr *E);
394+
bool emitFloat(const APFloat &F, const Expr *E);
394395
unsigned collectBaseOffset(const QualType BaseType,
395396
const QualType DerivedType);
396397
bool emitLambdaStaticInvokerBody(const CXXMethodDecl *MD);

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
368368
bool IsTemporary, bool IsConst, UnknownSize)
369369
: Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark),
370370
MDSize(MD.value_or(0)),
371-
AllocSize(MDSize + sizeof(InitMapPtr) + alignof(void *)),
371+
AllocSize(MDSize + sizeof(InitMapPtr) + alignof(void *)), PrimT(Type),
372372
IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary),
373373
IsArray(true), CtorFn(getCtorArrayPrim(Type)),
374374
DtorFn(getDtorArrayPrim(Type)), MoveFn(getMoveArrayPrim(Type)) {

clang/lib/AST/ByteCode/Disasm.cpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,56 @@ inline static std::string printArg(Program &P, CodePtr &OpPC) {
5050
}
5151

5252
template <> inline std::string printArg<Floating>(Program &P, CodePtr &OpPC) {
53-
auto F = Floating::deserialize(*OpPC);
54-
OpPC += align(F.bytesToSerialize());
53+
auto Sem = Floating::deserializeSemantics(*OpPC);
5554

56-
std::string Result;
57-
llvm::raw_string_ostream SS(Result);
58-
SS << F;
59-
return Result;
55+
unsigned BitWidth = llvm::APFloatBase::semanticsSizeInBits(
56+
llvm::APFloatBase::EnumToSemantics(Sem));
57+
auto Memory =
58+
std::make_unique<uint64_t[]>(llvm::APInt::getNumWords(BitWidth));
59+
Floating Result(Memory.get(), Sem);
60+
Floating::deserialize(*OpPC, &Result);
61+
62+
OpPC += align(Result.bytesToSerialize());
63+
64+
std::string S;
65+
llvm::raw_string_ostream SS(S);
66+
SS << Result;
67+
return S;
6068
}
6169

6270
template <>
6371
inline std::string printArg<IntegralAP<false>>(Program &P, CodePtr &OpPC) {
64-
auto F = IntegralAP<false>::deserialize(*OpPC);
65-
OpPC += align(F.bytesToSerialize());
66-
67-
std::string Result;
68-
llvm::raw_string_ostream SS(Result);
69-
SS << F;
70-
return Result;
72+
using T = IntegralAP<false>;
73+
unsigned BitWidth = T::deserializeSize(*OpPC);
74+
auto Memory =
75+
std::make_unique<uint64_t[]>(llvm::APInt::getNumWords(BitWidth));
76+
77+
T Result(Memory.get(), BitWidth);
78+
T::deserialize(*OpPC, &Result);
79+
80+
OpPC += Result.bytesToSerialize();
81+
std::string Str;
82+
llvm::raw_string_ostream SS(Str);
83+
SS << Result;
84+
return Str;
7185
}
86+
7287
template <>
7388
inline std::string printArg<IntegralAP<true>>(Program &P, CodePtr &OpPC) {
74-
auto F = IntegralAP<true>::deserialize(*OpPC);
75-
OpPC += align(F.bytesToSerialize());
89+
using T = IntegralAP<true>;
90+
unsigned BitWidth = T::deserializeSize(*OpPC);
91+
auto Memory =
92+
std::make_unique<uint64_t[]>(llvm::APInt::getNumWords(BitWidth));
7693

77-
std::string Result;
78-
llvm::raw_string_ostream SS(Result);
79-
SS << F;
80-
return Result;
94+
T Result(Memory.get(), BitWidth);
95+
T::deserialize(*OpPC, &Result);
96+
97+
std::string Str;
98+
llvm::raw_string_ostream SS(Str);
99+
SS << Result;
100+
101+
OpPC += Result.bytesToSerialize();
102+
return Str;
81103
}
82104

83105
template <> inline std::string printArg<FixedPoint>(Program &P, CodePtr &OpPC) {

0 commit comments

Comments
 (0)