1 | //===-- LLParser.cpp - Parser Class ---------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the parser class for .ll files. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/AsmParser/LLParser.h" |
14 | #include "llvm/ADT/APSInt.h" |
15 | #include "llvm/ADT/DenseMap.h" |
16 | #include "llvm/ADT/STLExtras.h" |
17 | #include "llvm/ADT/ScopeExit.h" |
18 | #include "llvm/ADT/SmallPtrSet.h" |
19 | #include "llvm/AsmParser/LLToken.h" |
20 | #include "llvm/AsmParser/SlotMapping.h" |
21 | #include "llvm/BinaryFormat/Dwarf.h" |
22 | #include "llvm/IR/Argument.h" |
23 | #include "llvm/IR/AutoUpgrade.h" |
24 | #include "llvm/IR/BasicBlock.h" |
25 | #include "llvm/IR/CallingConv.h" |
26 | #include "llvm/IR/Comdat.h" |
27 | #include "llvm/IR/ConstantRange.h" |
28 | #include "llvm/IR/ConstantRangeList.h" |
29 | #include "llvm/IR/Constants.h" |
30 | #include "llvm/IR/DebugInfoMetadata.h" |
31 | #include "llvm/IR/DerivedTypes.h" |
32 | #include "llvm/IR/Function.h" |
33 | #include "llvm/IR/GlobalIFunc.h" |
34 | #include "llvm/IR/GlobalObject.h" |
35 | #include "llvm/IR/InlineAsm.h" |
36 | #include "llvm/IR/InstIterator.h" |
37 | #include "llvm/IR/Instructions.h" |
38 | #include "llvm/IR/IntrinsicInst.h" |
39 | #include "llvm/IR/Intrinsics.h" |
40 | #include "llvm/IR/LLVMContext.h" |
41 | #include "llvm/IR/Metadata.h" |
42 | #include "llvm/IR/Module.h" |
43 | #include "llvm/IR/Operator.h" |
44 | #include "llvm/IR/Value.h" |
45 | #include "llvm/IR/ValueSymbolTable.h" |
46 | #include "llvm/Support/Casting.h" |
47 | #include "llvm/Support/Compiler.h" |
48 | #include "llvm/Support/ErrorHandling.h" |
49 | #include "llvm/Support/MathExtras.h" |
50 | #include "llvm/Support/ModRef.h" |
51 | #include "llvm/Support/SaveAndRestore.h" |
52 | #include "llvm/Support/raw_ostream.h" |
53 | #include <algorithm> |
54 | #include <cassert> |
55 | #include <cstring> |
56 | #include <optional> |
57 | #include <vector> |
58 | |
59 | using namespace llvm; |
60 | |
61 | static cl::opt<bool> AllowIncompleteIR( |
62 | "allow-incomplete-ir" , cl::init(Val: false), cl::Hidden, |
63 | cl::desc( |
64 | "Allow incomplete IR on a best effort basis (references to unknown " |
65 | "metadata will be dropped)" )); |
66 | |
67 | static std::string getTypeString(Type *T) { |
68 | std::string Result; |
69 | raw_string_ostream Tmp(Result); |
70 | Tmp << *T; |
71 | return Tmp.str(); |
72 | } |
73 | |
74 | /// Run: module ::= toplevelentity* |
75 | bool LLParser::Run(bool UpgradeDebugInfo, |
76 | DataLayoutCallbackTy DataLayoutCallback) { |
77 | // Prime the lexer. |
78 | Lex.Lex(); |
79 | |
80 | if (Context.shouldDiscardValueNames()) |
81 | return error( |
82 | L: Lex.getLoc(), |
83 | Msg: "Can't read textual IR with a Context that discards named Values" ); |
84 | |
85 | if (M) { |
86 | if (parseTargetDefinitions(DataLayoutCallback)) |
87 | return true; |
88 | } |
89 | |
90 | return parseTopLevelEntities() || validateEndOfModule(UpgradeDebugInfo) || |
91 | validateEndOfIndex(); |
92 | } |
93 | |
94 | bool LLParser::parseStandaloneConstantValue(Constant *&C, |
95 | const SlotMapping *Slots) { |
96 | restoreParsingState(Slots); |
97 | Lex.Lex(); |
98 | |
99 | Type *Ty = nullptr; |
100 | if (parseType(Result&: Ty) || parseConstantValue(Ty, C)) |
101 | return true; |
102 | if (Lex.getKind() != lltok::Eof) |
103 | return error(L: Lex.getLoc(), Msg: "expected end of string" ); |
104 | return false; |
105 | } |
106 | |
107 | bool LLParser::parseTypeAtBeginning(Type *&Ty, unsigned &Read, |
108 | const SlotMapping *Slots) { |
109 | restoreParsingState(Slots); |
110 | Lex.Lex(); |
111 | |
112 | Read = 0; |
113 | SMLoc Start = Lex.getLoc(); |
114 | Ty = nullptr; |
115 | if (parseType(Result&: Ty)) |
116 | return true; |
117 | SMLoc End = Lex.getLoc(); |
118 | Read = End.getPointer() - Start.getPointer(); |
119 | |
120 | return false; |
121 | } |
122 | |
123 | bool LLParser::parseDIExpressionBodyAtBeginning(MDNode *&Result, unsigned &Read, |
124 | const SlotMapping *Slots) { |
125 | restoreParsingState(Slots); |
126 | Lex.Lex(); |
127 | |
128 | Read = 0; |
129 | SMLoc Start = Lex.getLoc(); |
130 | Result = nullptr; |
131 | bool Status = parseDIExpressionBody(Result, /*IsDistinct=*/false); |
132 | SMLoc End = Lex.getLoc(); |
133 | Read = End.getPointer() - Start.getPointer(); |
134 | |
135 | return Status; |
136 | } |
137 | |
138 | void LLParser::restoreParsingState(const SlotMapping *Slots) { |
139 | if (!Slots) |
140 | return; |
141 | NumberedVals = Slots->GlobalValues; |
142 | NumberedMetadata = Slots->MetadataNodes; |
143 | for (const auto &I : Slots->NamedTypes) |
144 | NamedTypes.insert( |
145 | KV: std::make_pair(x: I.getKey(), y: std::make_pair(x: I.second, y: LocTy()))); |
146 | for (const auto &I : Slots->Types) |
147 | NumberedTypes.insert( |
148 | x: std::make_pair(x: I.first, y: std::make_pair(x: I.second, y: LocTy()))); |
149 | } |
150 | |
151 | static void dropIntrinsicWithUnknownMetadataArgument(IntrinsicInst *II) { |
152 | // White-list intrinsics that are safe to drop. |
153 | if (!isa<DbgInfoIntrinsic>(Val: II) && |
154 | II->getIntrinsicID() != Intrinsic::experimental_noalias_scope_decl) |
155 | return; |
156 | |
157 | SmallVector<MetadataAsValue *> MVs; |
158 | for (Value *V : II->args()) |
159 | if (auto *MV = dyn_cast<MetadataAsValue>(Val: V)) |
160 | if (auto *MD = dyn_cast<MDNode>(Val: MV->getMetadata())) |
161 | if (MD->isTemporary()) |
162 | MVs.push_back(Elt: MV); |
163 | |
164 | if (!MVs.empty()) { |
165 | assert(II->use_empty() && "Cannot have uses" ); |
166 | II->eraseFromParent(); |
167 | |
168 | // Also remove no longer used MetadataAsValue wrappers. |
169 | for (MetadataAsValue *MV : MVs) |
170 | if (MV->use_empty()) |
171 | delete MV; |
172 | } |
173 | } |
174 | |
175 | void LLParser::dropUnknownMetadataReferences() { |
176 | auto Pred = [](unsigned MDKind, MDNode *Node) { return Node->isTemporary(); }; |
177 | for (Function &F : *M) { |
178 | F.eraseMetadataIf(Pred); |
179 | for (Instruction &I : make_early_inc_range(Range: instructions(F))) { |
180 | I.eraseMetadataIf(Pred); |
181 | |
182 | if (auto *II = dyn_cast<IntrinsicInst>(Val: &I)) |
183 | dropIntrinsicWithUnknownMetadataArgument(II); |
184 | } |
185 | } |
186 | |
187 | for (GlobalVariable &GV : M->globals()) |
188 | GV.eraseMetadataIf(Pred); |
189 | |
190 | for (const auto &[ID, Info] : make_early_inc_range(Range&: ForwardRefMDNodes)) { |
191 | // Check whether there is only a single use left, which would be in our |
192 | // own NumberedMetadata. |
193 | if (Info.first->getNumTemporaryUses() == 1) { |
194 | NumberedMetadata.erase(x: ID); |
195 | ForwardRefMDNodes.erase(x: ID); |
196 | } |
197 | } |
198 | } |
199 | |
200 | /// validateEndOfModule - Do final validity and basic correctness checks at the |
201 | /// end of the module. |
202 | bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) { |
203 | if (!M) |
204 | return false; |
205 | |
206 | // We should have already returned an error if we observed both intrinsics and |
207 | // records in this IR. |
208 | assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) && |
209 | "Mixed debug intrinsics/records seen without a parsing error?" ); |
210 | |
211 | // Handle any function attribute group forward references. |
212 | for (const auto &RAG : ForwardRefAttrGroups) { |
213 | Value *V = RAG.first; |
214 | const std::vector<unsigned> &Attrs = RAG.second; |
215 | AttrBuilder B(Context); |
216 | |
217 | for (const auto &Attr : Attrs) { |
218 | auto R = NumberedAttrBuilders.find(x: Attr); |
219 | if (R != NumberedAttrBuilders.end()) |
220 | B.merge(B: R->second); |
221 | } |
222 | |
223 | if (Function *Fn = dyn_cast<Function>(Val: V)) { |
224 | AttributeList AS = Fn->getAttributes(); |
225 | AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs()); |
226 | AS = AS.removeFnAttributes(C&: Context); |
227 | |
228 | FnAttrs.merge(B); |
229 | |
230 | // If the alignment was parsed as an attribute, move to the alignment |
231 | // field. |
232 | if (MaybeAlign A = FnAttrs.getAlignment()) { |
233 | Fn->setAlignment(*A); |
234 | FnAttrs.removeAttribute(Val: Attribute::Alignment); |
235 | } |
236 | |
237 | AS = AS.addFnAttributes(C&: Context, B: FnAttrs); |
238 | Fn->setAttributes(AS); |
239 | } else if (CallInst *CI = dyn_cast<CallInst>(Val: V)) { |
240 | AttributeList AS = CI->getAttributes(); |
241 | AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs()); |
242 | AS = AS.removeFnAttributes(C&: Context); |
243 | FnAttrs.merge(B); |
244 | AS = AS.addFnAttributes(C&: Context, B: FnAttrs); |
245 | CI->setAttributes(AS); |
246 | } else if (InvokeInst *II = dyn_cast<InvokeInst>(Val: V)) { |
247 | AttributeList AS = II->getAttributes(); |
248 | AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs()); |
249 | AS = AS.removeFnAttributes(C&: Context); |
250 | FnAttrs.merge(B); |
251 | AS = AS.addFnAttributes(C&: Context, B: FnAttrs); |
252 | II->setAttributes(AS); |
253 | } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(Val: V)) { |
254 | AttributeList AS = CBI->getAttributes(); |
255 | AttrBuilder FnAttrs(M->getContext(), AS.getFnAttrs()); |
256 | AS = AS.removeFnAttributes(C&: Context); |
257 | FnAttrs.merge(B); |
258 | AS = AS.addFnAttributes(C&: Context, B: FnAttrs); |
259 | CBI->setAttributes(AS); |
260 | } else if (auto *GV = dyn_cast<GlobalVariable>(Val: V)) { |
261 | AttrBuilder Attrs(M->getContext(), GV->getAttributes()); |
262 | Attrs.merge(B); |
263 | GV->setAttributes(AttributeSet::get(C&: Context,B: Attrs)); |
264 | } else { |
265 | llvm_unreachable("invalid object with forward attribute group reference" ); |
266 | } |
267 | } |
268 | |
269 | // If there are entries in ForwardRefBlockAddresses at this point, the |
270 | // function was never defined. |
271 | if (!ForwardRefBlockAddresses.empty()) |
272 | return error(L: ForwardRefBlockAddresses.begin()->first.Loc, |
273 | Msg: "expected function name in blockaddress" ); |
274 | |
275 | auto ResolveForwardRefDSOLocalEquivalents = [&](const ValID &GVRef, |
276 | GlobalValue *FwdRef) { |
277 | GlobalValue *GV = nullptr; |
278 | if (GVRef.Kind == ValID::t_GlobalName) { |
279 | GV = M->getNamedValue(Name: GVRef.StrVal); |
280 | } else { |
281 | GV = NumberedVals.get(ID: GVRef.UIntVal); |
282 | } |
283 | |
284 | if (!GV) |
285 | return error(L: GVRef.Loc, Msg: "unknown function '" + GVRef.StrVal + |
286 | "' referenced by dso_local_equivalent" ); |
287 | |
288 | if (!GV->getValueType()->isFunctionTy()) |
289 | return error(L: GVRef.Loc, |
290 | Msg: "expected a function, alias to function, or ifunc " |
291 | "in dso_local_equivalent" ); |
292 | |
293 | auto *Equiv = DSOLocalEquivalent::get(GV); |
294 | FwdRef->replaceAllUsesWith(V: Equiv); |
295 | FwdRef->eraseFromParent(); |
296 | return false; |
297 | }; |
298 | |
299 | // If there are entries in ForwardRefDSOLocalEquivalentIDs/Names at this |
300 | // point, they are references after the function was defined. Resolve those |
301 | // now. |
302 | for (auto &Iter : ForwardRefDSOLocalEquivalentIDs) { |
303 | if (ResolveForwardRefDSOLocalEquivalents(Iter.first, Iter.second)) |
304 | return true; |
305 | } |
306 | for (auto &Iter : ForwardRefDSOLocalEquivalentNames) { |
307 | if (ResolveForwardRefDSOLocalEquivalents(Iter.first, Iter.second)) |
308 | return true; |
309 | } |
310 | ForwardRefDSOLocalEquivalentIDs.clear(); |
311 | ForwardRefDSOLocalEquivalentNames.clear(); |
312 | |
313 | for (const auto &NT : NumberedTypes) |
314 | if (NT.second.second.isValid()) |
315 | return error(L: NT.second.second, |
316 | Msg: "use of undefined type '%" + Twine(NT.first) + "'" ); |
317 | |
318 | for (StringMap<std::pair<Type*, LocTy> >::iterator I = |
319 | NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I) |
320 | if (I->second.second.isValid()) |
321 | return error(L: I->second.second, |
322 | Msg: "use of undefined type named '" + I->getKey() + "'" ); |
323 | |
324 | if (!ForwardRefComdats.empty()) |
325 | return error(L: ForwardRefComdats.begin()->second, |
326 | Msg: "use of undefined comdat '$" + |
327 | ForwardRefComdats.begin()->first + "'" ); |
328 | |
329 | for (const auto &[Name, Info] : make_early_inc_range(Range&: ForwardRefVals)) { |
330 | if (StringRef(Name).starts_with(Prefix: "llvm." )) { |
331 | Intrinsic::ID IID = Intrinsic::lookupIntrinsicID(Name); |
332 | if (IID == Intrinsic::not_intrinsic) |
333 | // Don't do anything for unknown intrinsics. |
334 | continue; |
335 | |
336 | // Automatically create declarations for intrinsics. Intrinsics can only |
337 | // be called directly, so the call function type directly determines the |
338 | // declaration function type. |
339 | // |
340 | // Additionally, automatically add the required mangling suffix to the |
341 | // intrinsic name. This means that we may replace a single forward |
342 | // declaration with multiple functions here. |
343 | for (Use &U : make_early_inc_range(Range: Info.first->uses())) { |
344 | auto *CB = dyn_cast<CallBase>(Val: U.getUser()); |
345 | if (!CB || !CB->isCallee(U: &U)) |
346 | return error(L: Info.second, Msg: "intrinsic can only be used as callee" ); |
347 | |
348 | SmallVector<Type *> OverloadTys; |
349 | if (!Intrinsic::getIntrinsicSignature(IID, FT: CB->getFunctionType(), |
350 | ArgTys&: OverloadTys)) |
351 | return error(L: Info.second, Msg: "invalid intrinsic signature" ); |
352 | |
353 | U.set(Intrinsic::getOrInsertDeclaration(M, id: IID, Tys: OverloadTys)); |
354 | } |
355 | |
356 | Info.first->eraseFromParent(); |
357 | ForwardRefVals.erase(x: Name); |
358 | continue; |
359 | } |
360 | |
361 | // If incomplete IR is allowed, also add declarations for |
362 | // non-intrinsics. |
363 | if (!AllowIncompleteIR) |
364 | continue; |
365 | |
366 | auto GetCommonFunctionType = [](Value *V) -> FunctionType * { |
367 | FunctionType *FTy = nullptr; |
368 | for (Use &U : V->uses()) { |
369 | auto *CB = dyn_cast<CallBase>(Val: U.getUser()); |
370 | if (!CB || !CB->isCallee(U: &U) || (FTy && FTy != CB->getFunctionType())) |
371 | return nullptr; |
372 | FTy = CB->getFunctionType(); |
373 | } |
374 | return FTy; |
375 | }; |
376 | |
377 | // First check whether this global is only used in calls with the same |
378 | // type, in which case we'll insert a function. Otherwise, fall back to |
379 | // using a dummy i8 type. |
380 | Type *Ty = GetCommonFunctionType(Info.first); |
381 | if (!Ty) |
382 | Ty = Type::getInt8Ty(C&: Context); |
383 | |
384 | GlobalValue *GV; |
385 | if (auto *FTy = dyn_cast<FunctionType>(Val: Ty)) |
386 | GV = Function::Create(Ty: FTy, Linkage: GlobalValue::ExternalLinkage, N: Name, M); |
387 | else |
388 | GV = new GlobalVariable(*M, Ty, /*isConstant*/ false, |
389 | GlobalValue::ExternalLinkage, |
390 | /*Initializer*/ nullptr, Name); |
391 | Info.first->replaceAllUsesWith(V: GV); |
392 | Info.first->eraseFromParent(); |
393 | ForwardRefVals.erase(x: Name); |
394 | } |
395 | |
396 | if (!ForwardRefVals.empty()) |
397 | return error(L: ForwardRefVals.begin()->second.second, |
398 | Msg: "use of undefined value '@" + ForwardRefVals.begin()->first + |
399 | "'" ); |
400 | |
401 | if (!ForwardRefValIDs.empty()) |
402 | return error(L: ForwardRefValIDs.begin()->second.second, |
403 | Msg: "use of undefined value '@" + |
404 | Twine(ForwardRefValIDs.begin()->first) + "'" ); |
405 | |
406 | if (AllowIncompleteIR && !ForwardRefMDNodes.empty()) |
407 | dropUnknownMetadataReferences(); |
408 | |
409 | if (!ForwardRefMDNodes.empty()) |
410 | return error(L: ForwardRefMDNodes.begin()->second.second, |
411 | Msg: "use of undefined metadata '!" + |
412 | Twine(ForwardRefMDNodes.begin()->first) + "'" ); |
413 | |
414 | // Resolve metadata cycles. |
415 | for (auto &N : NumberedMetadata) { |
416 | if (N.second && !N.second->isResolved()) |
417 | N.second->resolveCycles(); |
418 | } |
419 | |
420 | for (auto *Inst : InstsWithTBAATag) { |
421 | MDNode *MD = Inst->getMetadata(KindID: LLVMContext::MD_tbaa); |
422 | // With incomplete IR, the tbaa metadata may have been dropped. |
423 | if (!AllowIncompleteIR) |
424 | assert(MD && "UpgradeInstWithTBAATag should have a TBAA tag" ); |
425 | if (MD) { |
426 | auto *UpgradedMD = UpgradeTBAANode(TBAANode&: *MD); |
427 | if (MD != UpgradedMD) |
428 | Inst->setMetadata(KindID: LLVMContext::MD_tbaa, Node: UpgradedMD); |
429 | } |
430 | } |
431 | |
432 | // Look for intrinsic functions and CallInst that need to be upgraded. We use |
433 | // make_early_inc_range here because we may remove some functions. |
434 | for (Function &F : llvm::make_early_inc_range(Range&: *M)) |
435 | UpgradeCallsToIntrinsic(F: &F); |
436 | |
437 | if (UpgradeDebugInfo) |
438 | llvm::UpgradeDebugInfo(M&: *M); |
439 | |
440 | UpgradeModuleFlags(M&: *M); |
441 | UpgradeNVVMAnnotations(M&: *M); |
442 | UpgradeSectionAttributes(M&: *M); |
443 | |
444 | if (!Slots) |
445 | return false; |
446 | // Initialize the slot mapping. |
447 | // Because by this point we've parsed and validated everything, we can "steal" |
448 | // the mapping from LLParser as it doesn't need it anymore. |
449 | Slots->GlobalValues = std::move(NumberedVals); |
450 | Slots->MetadataNodes = std::move(NumberedMetadata); |
451 | for (const auto &I : NamedTypes) |
452 | Slots->NamedTypes.insert(KV: std::make_pair(x: I.getKey(), y: I.second.first)); |
453 | for (const auto &I : NumberedTypes) |
454 | Slots->Types.insert(x: std::make_pair(x: I.first, y: I.second.first)); |
455 | |
456 | return false; |
457 | } |
458 | |
459 | /// Do final validity and basic correctness checks at the end of the index. |
460 | bool LLParser::validateEndOfIndex() { |
461 | if (!Index) |
462 | return false; |
463 | |
464 | if (!ForwardRefValueInfos.empty()) |
465 | return error(L: ForwardRefValueInfos.begin()->second.front().second, |
466 | Msg: "use of undefined summary '^" + |
467 | Twine(ForwardRefValueInfos.begin()->first) + "'" ); |
468 | |
469 | if (!ForwardRefAliasees.empty()) |
470 | return error(L: ForwardRefAliasees.begin()->second.front().second, |
471 | Msg: "use of undefined summary '^" + |
472 | Twine(ForwardRefAliasees.begin()->first) + "'" ); |
473 | |
474 | if (!ForwardRefTypeIds.empty()) |
475 | return error(L: ForwardRefTypeIds.begin()->second.front().second, |
476 | Msg: "use of undefined type id summary '^" + |
477 | Twine(ForwardRefTypeIds.begin()->first) + "'" ); |
478 | |
479 | return false; |
480 | } |
481 | |
482 | //===----------------------------------------------------------------------===// |
483 | // Top-Level Entities |
484 | //===----------------------------------------------------------------------===// |
485 | |
486 | bool LLParser::parseTargetDefinitions(DataLayoutCallbackTy DataLayoutCallback) { |
487 | // Delay parsing of the data layout string until the target triple is known. |
488 | // Then, pass both the the target triple and the tentative data layout string |
489 | // to DataLayoutCallback, allowing to override the DL string. |
490 | // This enables importing modules with invalid DL strings. |
491 | std::string TentativeDLStr = M->getDataLayoutStr(); |
492 | LocTy DLStrLoc; |
493 | |
494 | bool Done = false; |
495 | while (!Done) { |
496 | switch (Lex.getKind()) { |
497 | case lltok::kw_target: |
498 | if (parseTargetDefinition(TentativeDLStr, DLStrLoc)) |
499 | return true; |
500 | break; |
501 | case lltok::kw_source_filename: |
502 | if (parseSourceFileName()) |
503 | return true; |
504 | break; |
505 | default: |
506 | Done = true; |
507 | } |
508 | } |
509 | // Run the override callback to potentially change the data layout string, and |
510 | // parse the data layout string. |
511 | if (auto LayoutOverride = |
512 | DataLayoutCallback(M->getTargetTriple().str(), TentativeDLStr)) { |
513 | TentativeDLStr = *LayoutOverride; |
514 | DLStrLoc = {}; |
515 | } |
516 | Expected<DataLayout> MaybeDL = DataLayout::parse(LayoutString: TentativeDLStr); |
517 | if (!MaybeDL) |
518 | return error(L: DLStrLoc, Msg: toString(E: MaybeDL.takeError())); |
519 | M->setDataLayout(MaybeDL.get()); |
520 | return false; |
521 | } |
522 | |
523 | bool LLParser::parseTopLevelEntities() { |
524 | // If there is no Module, then parse just the summary index entries. |
525 | if (!M) { |
526 | while (true) { |
527 | switch (Lex.getKind()) { |
528 | case lltok::Eof: |
529 | return false; |
530 | case lltok::SummaryID: |
531 | if (parseSummaryEntry()) |
532 | return true; |
533 | break; |
534 | case lltok::kw_source_filename: |
535 | if (parseSourceFileName()) |
536 | return true; |
537 | break; |
538 | default: |
539 | // Skip everything else |
540 | Lex.Lex(); |
541 | } |
542 | } |
543 | } |
544 | while (true) { |
545 | switch (Lex.getKind()) { |
546 | default: |
547 | return tokError(Msg: "expected top-level entity" ); |
548 | case lltok::Eof: return false; |
549 | case lltok::kw_declare: |
550 | if (parseDeclare()) |
551 | return true; |
552 | break; |
553 | case lltok::kw_define: |
554 | if (parseDefine()) |
555 | return true; |
556 | break; |
557 | case lltok::kw_module: |
558 | if (parseModuleAsm()) |
559 | return true; |
560 | break; |
561 | case lltok::LocalVarID: |
562 | if (parseUnnamedType()) |
563 | return true; |
564 | break; |
565 | case lltok::LocalVar: |
566 | if (parseNamedType()) |
567 | return true; |
568 | break; |
569 | case lltok::GlobalID: |
570 | if (parseUnnamedGlobal()) |
571 | return true; |
572 | break; |
573 | case lltok::GlobalVar: |
574 | if (parseNamedGlobal()) |
575 | return true; |
576 | break; |
577 | case lltok::ComdatVar: if (parseComdat()) return true; break; |
578 | case lltok::exclaim: |
579 | if (parseStandaloneMetadata()) |
580 | return true; |
581 | break; |
582 | case lltok::SummaryID: |
583 | if (parseSummaryEntry()) |
584 | return true; |
585 | break; |
586 | case lltok::MetadataVar: |
587 | if (parseNamedMetadata()) |
588 | return true; |
589 | break; |
590 | case lltok::kw_attributes: |
591 | if (parseUnnamedAttrGrp()) |
592 | return true; |
593 | break; |
594 | case lltok::kw_uselistorder: |
595 | if (parseUseListOrder()) |
596 | return true; |
597 | break; |
598 | case lltok::kw_uselistorder_bb: |
599 | if (parseUseListOrderBB()) |
600 | return true; |
601 | break; |
602 | } |
603 | } |
604 | } |
605 | |
606 | /// toplevelentity |
607 | /// ::= 'module' 'asm' STRINGCONSTANT |
608 | bool LLParser::parseModuleAsm() { |
609 | assert(Lex.getKind() == lltok::kw_module); |
610 | Lex.Lex(); |
611 | |
612 | std::string AsmStr; |
613 | if (parseToken(T: lltok::kw_asm, ErrMsg: "expected 'module asm'" ) || |
614 | parseStringConstant(Result&: AsmStr)) |
615 | return true; |
616 | |
617 | M->appendModuleInlineAsm(Asm: AsmStr); |
618 | return false; |
619 | } |
620 | |
621 | /// toplevelentity |
622 | /// ::= 'target' 'triple' '=' STRINGCONSTANT |
623 | /// ::= 'target' 'datalayout' '=' STRINGCONSTANT |
624 | bool LLParser::parseTargetDefinition(std::string &TentativeDLStr, |
625 | LocTy &DLStrLoc) { |
626 | assert(Lex.getKind() == lltok::kw_target); |
627 | std::string Str; |
628 | switch (Lex.Lex()) { |
629 | default: |
630 | return tokError(Msg: "unknown target property" ); |
631 | case lltok::kw_triple: |
632 | Lex.Lex(); |
633 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after target triple" ) || |
634 | parseStringConstant(Result&: Str)) |
635 | return true; |
636 | M->setTargetTriple(Triple(std::move(Str))); |
637 | return false; |
638 | case lltok::kw_datalayout: |
639 | Lex.Lex(); |
640 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after target datalayout" )) |
641 | return true; |
642 | DLStrLoc = Lex.getLoc(); |
643 | if (parseStringConstant(Result&: TentativeDLStr)) |
644 | return true; |
645 | return false; |
646 | } |
647 | } |
648 | |
649 | /// toplevelentity |
650 | /// ::= 'source_filename' '=' STRINGCONSTANT |
651 | bool LLParser::parseSourceFileName() { |
652 | assert(Lex.getKind() == lltok::kw_source_filename); |
653 | Lex.Lex(); |
654 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after source_filename" ) || |
655 | parseStringConstant(Result&: SourceFileName)) |
656 | return true; |
657 | if (M) |
658 | M->setSourceFileName(SourceFileName); |
659 | return false; |
660 | } |
661 | |
662 | /// parseUnnamedType: |
663 | /// ::= LocalVarID '=' 'type' type |
664 | bool LLParser::parseUnnamedType() { |
665 | LocTy TypeLoc = Lex.getLoc(); |
666 | unsigned TypeID = Lex.getUIntVal(); |
667 | Lex.Lex(); // eat LocalVarID; |
668 | |
669 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after name" ) || |
670 | parseToken(T: lltok::kw_type, ErrMsg: "expected 'type' after '='" )) |
671 | return true; |
672 | |
673 | Type *Result = nullptr; |
674 | if (parseStructDefinition(TypeLoc, Name: "" , Entry&: NumberedTypes[TypeID], ResultTy&: Result)) |
675 | return true; |
676 | |
677 | if (!isa<StructType>(Val: Result)) { |
678 | std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID]; |
679 | if (Entry.first) |
680 | return error(L: TypeLoc, Msg: "non-struct types may not be recursive" ); |
681 | Entry.first = Result; |
682 | Entry.second = SMLoc(); |
683 | } |
684 | |
685 | return false; |
686 | } |
687 | |
688 | /// toplevelentity |
689 | /// ::= LocalVar '=' 'type' type |
690 | bool LLParser::parseNamedType() { |
691 | std::string Name = Lex.getStrVal(); |
692 | LocTy NameLoc = Lex.getLoc(); |
693 | Lex.Lex(); // eat LocalVar. |
694 | |
695 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after name" ) || |
696 | parseToken(T: lltok::kw_type, ErrMsg: "expected 'type' after name" )) |
697 | return true; |
698 | |
699 | Type *Result = nullptr; |
700 | if (parseStructDefinition(TypeLoc: NameLoc, Name, Entry&: NamedTypes[Name], ResultTy&: Result)) |
701 | return true; |
702 | |
703 | if (!isa<StructType>(Val: Result)) { |
704 | std::pair<Type*, LocTy> &Entry = NamedTypes[Name]; |
705 | if (Entry.first) |
706 | return error(L: NameLoc, Msg: "non-struct types may not be recursive" ); |
707 | Entry.first = Result; |
708 | Entry.second = SMLoc(); |
709 | } |
710 | |
711 | return false; |
712 | } |
713 | |
714 | /// toplevelentity |
715 | /// ::= 'declare' FunctionHeader |
716 | bool LLParser::parseDeclare() { |
717 | assert(Lex.getKind() == lltok::kw_declare); |
718 | Lex.Lex(); |
719 | |
720 | std::vector<std::pair<unsigned, MDNode *>> MDs; |
721 | while (Lex.getKind() == lltok::MetadataVar) { |
722 | unsigned MDK; |
723 | MDNode *N; |
724 | if (parseMetadataAttachment(Kind&: MDK, MD&: N)) |
725 | return true; |
726 | MDs.push_back(x: {MDK, N}); |
727 | } |
728 | |
729 | Function *F; |
730 | unsigned FunctionNumber = -1; |
731 | SmallVector<unsigned> UnnamedArgNums; |
732 | if (parseFunctionHeader(Fn&: F, IsDefine: false, FunctionNumber, UnnamedArgNums)) |
733 | return true; |
734 | for (auto &MD : MDs) |
735 | F->addMetadata(KindID: MD.first, MD&: *MD.second); |
736 | return false; |
737 | } |
738 | |
739 | /// toplevelentity |
740 | /// ::= 'define' FunctionHeader (!dbg !56)* '{' ... |
741 | bool LLParser::parseDefine() { |
742 | assert(Lex.getKind() == lltok::kw_define); |
743 | Lex.Lex(); |
744 | |
745 | Function *F; |
746 | unsigned FunctionNumber = -1; |
747 | SmallVector<unsigned> UnnamedArgNums; |
748 | return parseFunctionHeader(Fn&: F, IsDefine: true, FunctionNumber, UnnamedArgNums) || |
749 | parseOptionalFunctionMetadata(F&: *F) || |
750 | parseFunctionBody(Fn&: *F, FunctionNumber, UnnamedArgNums); |
751 | } |
752 | |
753 | /// parseGlobalType |
754 | /// ::= 'constant' |
755 | /// ::= 'global' |
756 | bool LLParser::parseGlobalType(bool &IsConstant) { |
757 | if (Lex.getKind() == lltok::kw_constant) |
758 | IsConstant = true; |
759 | else if (Lex.getKind() == lltok::kw_global) |
760 | IsConstant = false; |
761 | else { |
762 | IsConstant = false; |
763 | return tokError(Msg: "expected 'global' or 'constant'" ); |
764 | } |
765 | Lex.Lex(); |
766 | return false; |
767 | } |
768 | |
769 | bool LLParser::parseOptionalUnnamedAddr( |
770 | GlobalVariable::UnnamedAddr &UnnamedAddr) { |
771 | if (EatIfPresent(T: lltok::kw_unnamed_addr)) |
772 | UnnamedAddr = GlobalValue::UnnamedAddr::Global; |
773 | else if (EatIfPresent(T: lltok::kw_local_unnamed_addr)) |
774 | UnnamedAddr = GlobalValue::UnnamedAddr::Local; |
775 | else |
776 | UnnamedAddr = GlobalValue::UnnamedAddr::None; |
777 | return false; |
778 | } |
779 | |
780 | /// parseUnnamedGlobal: |
781 | /// OptionalVisibility (ALIAS | IFUNC) ... |
782 | /// OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility |
783 | /// OptionalDLLStorageClass |
784 | /// ... -> global variable |
785 | /// GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ... |
786 | /// GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier |
787 | /// OptionalVisibility |
788 | /// OptionalDLLStorageClass |
789 | /// ... -> global variable |
790 | bool LLParser::parseUnnamedGlobal() { |
791 | unsigned VarID; |
792 | std::string Name; |
793 | LocTy NameLoc = Lex.getLoc(); |
794 | |
795 | // Handle the GlobalID form. |
796 | if (Lex.getKind() == lltok::GlobalID) { |
797 | VarID = Lex.getUIntVal(); |
798 | if (checkValueID(L: NameLoc, Kind: "global" , Prefix: "@" , NextID: NumberedVals.getNext(), ID: VarID)) |
799 | return true; |
800 | |
801 | Lex.Lex(); // eat GlobalID; |
802 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after name" )) |
803 | return true; |
804 | } else { |
805 | VarID = NumberedVals.getNext(); |
806 | } |
807 | |
808 | bool HasLinkage; |
809 | unsigned Linkage, Visibility, DLLStorageClass; |
810 | bool DSOLocal; |
811 | GlobalVariable::ThreadLocalMode TLM; |
812 | GlobalVariable::UnnamedAddr UnnamedAddr; |
813 | if (parseOptionalLinkage(Res&: Linkage, HasLinkage, Visibility, DLLStorageClass, |
814 | DSOLocal) || |
815 | parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr)) |
816 | return true; |
817 | |
818 | switch (Lex.getKind()) { |
819 | default: |
820 | return parseGlobal(Name, NameID: VarID, NameLoc, Linkage, HasLinkage, Visibility, |
821 | DLLStorageClass, DSOLocal, TLM, UnnamedAddr); |
822 | case lltok::kw_alias: |
823 | case lltok::kw_ifunc: |
824 | return parseAliasOrIFunc(Name, NameID: VarID, NameLoc, L: Linkage, Visibility, |
825 | DLLStorageClass, DSOLocal, TLM, UnnamedAddr); |
826 | } |
827 | } |
828 | |
829 | /// parseNamedGlobal: |
830 | /// GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ... |
831 | /// GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier |
832 | /// OptionalVisibility OptionalDLLStorageClass |
833 | /// ... -> global variable |
834 | bool LLParser::parseNamedGlobal() { |
835 | assert(Lex.getKind() == lltok::GlobalVar); |
836 | LocTy NameLoc = Lex.getLoc(); |
837 | std::string Name = Lex.getStrVal(); |
838 | Lex.Lex(); |
839 | |
840 | bool HasLinkage; |
841 | unsigned Linkage, Visibility, DLLStorageClass; |
842 | bool DSOLocal; |
843 | GlobalVariable::ThreadLocalMode TLM; |
844 | GlobalVariable::UnnamedAddr UnnamedAddr; |
845 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' in global variable" ) || |
846 | parseOptionalLinkage(Res&: Linkage, HasLinkage, Visibility, DLLStorageClass, |
847 | DSOLocal) || |
848 | parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr)) |
849 | return true; |
850 | |
851 | switch (Lex.getKind()) { |
852 | default: |
853 | return parseGlobal(Name, NameID: -1, NameLoc, Linkage, HasLinkage, Visibility, |
854 | DLLStorageClass, DSOLocal, TLM, UnnamedAddr); |
855 | case lltok::kw_alias: |
856 | case lltok::kw_ifunc: |
857 | return parseAliasOrIFunc(Name, NameID: -1, NameLoc, L: Linkage, Visibility, |
858 | DLLStorageClass, DSOLocal, TLM, UnnamedAddr); |
859 | } |
860 | } |
861 | |
862 | bool LLParser::parseComdat() { |
863 | assert(Lex.getKind() == lltok::ComdatVar); |
864 | std::string Name = Lex.getStrVal(); |
865 | LocTy NameLoc = Lex.getLoc(); |
866 | Lex.Lex(); |
867 | |
868 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' here" )) |
869 | return true; |
870 | |
871 | if (parseToken(T: lltok::kw_comdat, ErrMsg: "expected comdat keyword" )) |
872 | return tokError(Msg: "expected comdat type" ); |
873 | |
874 | Comdat::SelectionKind SK; |
875 | switch (Lex.getKind()) { |
876 | default: |
877 | return tokError(Msg: "unknown selection kind" ); |
878 | case lltok::kw_any: |
879 | SK = Comdat::Any; |
880 | break; |
881 | case lltok::kw_exactmatch: |
882 | SK = Comdat::ExactMatch; |
883 | break; |
884 | case lltok::kw_largest: |
885 | SK = Comdat::Largest; |
886 | break; |
887 | case lltok::kw_nodeduplicate: |
888 | SK = Comdat::NoDeduplicate; |
889 | break; |
890 | case lltok::kw_samesize: |
891 | SK = Comdat::SameSize; |
892 | break; |
893 | } |
894 | Lex.Lex(); |
895 | |
896 | // See if the comdat was forward referenced, if so, use the comdat. |
897 | Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable(); |
898 | Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Key: Name); |
899 | if (I != ComdatSymTab.end() && !ForwardRefComdats.erase(x: Name)) |
900 | return error(L: NameLoc, Msg: "redefinition of comdat '$" + Name + "'" ); |
901 | |
902 | Comdat *C; |
903 | if (I != ComdatSymTab.end()) |
904 | C = &I->second; |
905 | else |
906 | C = M->getOrInsertComdat(Name); |
907 | C->setSelectionKind(SK); |
908 | |
909 | return false; |
910 | } |
911 | |
912 | // MDString: |
913 | // ::= '!' STRINGCONSTANT |
914 | bool LLParser::parseMDString(MDString *&Result) { |
915 | std::string Str; |
916 | if (parseStringConstant(Result&: Str)) |
917 | return true; |
918 | Result = MDString::get(Context, Str); |
919 | return false; |
920 | } |
921 | |
922 | // MDNode: |
923 | // ::= '!' MDNodeNumber |
924 | bool LLParser::parseMDNodeID(MDNode *&Result) { |
925 | // !{ ..., !42, ... } |
926 | LocTy IDLoc = Lex.getLoc(); |
927 | unsigned MID = 0; |
928 | if (parseUInt32(Val&: MID)) |
929 | return true; |
930 | |
931 | // If not a forward reference, just return it now. |
932 | auto [It, Inserted] = NumberedMetadata.try_emplace(k: MID); |
933 | if (!Inserted) { |
934 | Result = It->second; |
935 | return false; |
936 | } |
937 | |
938 | // Otherwise, create MDNode forward reference. |
939 | auto &FwdRef = ForwardRefMDNodes[MID]; |
940 | FwdRef = std::make_pair(x: MDTuple::getTemporary(Context, MDs: {}), y&: IDLoc); |
941 | |
942 | Result = FwdRef.first.get(); |
943 | It->second.reset(MD: Result); |
944 | return false; |
945 | } |
946 | |
947 | /// parseNamedMetadata: |
948 | /// !foo = !{ !1, !2 } |
949 | bool LLParser::parseNamedMetadata() { |
950 | assert(Lex.getKind() == lltok::MetadataVar); |
951 | std::string Name = Lex.getStrVal(); |
952 | Lex.Lex(); |
953 | |
954 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' here" ) || |
955 | parseToken(T: lltok::exclaim, ErrMsg: "Expected '!' here" ) || |
956 | parseToken(T: lltok::lbrace, ErrMsg: "Expected '{' here" )) |
957 | return true; |
958 | |
959 | NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name); |
960 | if (Lex.getKind() != lltok::rbrace) |
961 | do { |
962 | MDNode *N = nullptr; |
963 | // parse DIExpressions inline as a special case. They are still MDNodes, |
964 | // so they can still appear in named metadata. Remove this logic if they |
965 | // become plain Metadata. |
966 | if (Lex.getKind() == lltok::MetadataVar && |
967 | Lex.getStrVal() == "DIExpression" ) { |
968 | if (parseDIExpression(Result&: N, /*IsDistinct=*/false)) |
969 | return true; |
970 | // DIArgLists should only appear inline in a function, as they may |
971 | // contain LocalAsMetadata arguments which require a function context. |
972 | } else if (Lex.getKind() == lltok::MetadataVar && |
973 | Lex.getStrVal() == "DIArgList" ) { |
974 | return tokError(Msg: "found DIArgList outside of function" ); |
975 | } else if (parseToken(T: lltok::exclaim, ErrMsg: "Expected '!' here" ) || |
976 | parseMDNodeID(Result&: N)) { |
977 | return true; |
978 | } |
979 | NMD->addOperand(M: N); |
980 | } while (EatIfPresent(T: lltok::comma)); |
981 | |
982 | return parseToken(T: lltok::rbrace, ErrMsg: "expected end of metadata node" ); |
983 | } |
984 | |
985 | /// parseStandaloneMetadata: |
986 | /// !42 = !{...} |
987 | bool LLParser::parseStandaloneMetadata() { |
988 | assert(Lex.getKind() == lltok::exclaim); |
989 | Lex.Lex(); |
990 | unsigned MetadataID = 0; |
991 | |
992 | MDNode *Init; |
993 | if (parseUInt32(Val&: MetadataID) || parseToken(T: lltok::equal, ErrMsg: "expected '=' here" )) |
994 | return true; |
995 | |
996 | // Detect common error, from old metadata syntax. |
997 | if (Lex.getKind() == lltok::Type) |
998 | return tokError(Msg: "unexpected type in metadata definition" ); |
999 | |
1000 | bool IsDistinct = EatIfPresent(T: lltok::kw_distinct); |
1001 | if (Lex.getKind() == lltok::MetadataVar) { |
1002 | if (parseSpecializedMDNode(N&: Init, IsDistinct)) |
1003 | return true; |
1004 | } else if (parseToken(T: lltok::exclaim, ErrMsg: "Expected '!' here" ) || |
1005 | parseMDTuple(MD&: Init, IsDistinct)) |
1006 | return true; |
1007 | |
1008 | // See if this was forward referenced, if so, handle it. |
1009 | auto FI = ForwardRefMDNodes.find(x: MetadataID); |
1010 | if (FI != ForwardRefMDNodes.end()) { |
1011 | auto *ToReplace = FI->second.first.get(); |
1012 | // DIAssignID has its own special forward-reference "replacement" for |
1013 | // attachments (the temporary attachments are never actually attached). |
1014 | if (isa<DIAssignID>(Val: Init)) { |
1015 | for (auto *Inst : TempDIAssignIDAttachments[ToReplace]) { |
1016 | assert(!Inst->getMetadata(LLVMContext::MD_DIAssignID) && |
1017 | "Inst unexpectedly already has DIAssignID attachment" ); |
1018 | Inst->setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: Init); |
1019 | } |
1020 | } |
1021 | |
1022 | ToReplace->replaceAllUsesWith(MD: Init); |
1023 | ForwardRefMDNodes.erase(position: FI); |
1024 | |
1025 | assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work" ); |
1026 | } else { |
1027 | auto [It, Inserted] = NumberedMetadata.try_emplace(k: MetadataID); |
1028 | if (!Inserted) |
1029 | return tokError(Msg: "Metadata id is already used" ); |
1030 | It->second.reset(MD: Init); |
1031 | } |
1032 | |
1033 | return false; |
1034 | } |
1035 | |
1036 | // Skips a single module summary entry. |
1037 | bool LLParser::skipModuleSummaryEntry() { |
1038 | // Each module summary entry consists of a tag for the entry |
1039 | // type, followed by a colon, then the fields which may be surrounded by |
1040 | // nested sets of parentheses. The "tag:" looks like a Label. Once parsing |
1041 | // support is in place we will look for the tokens corresponding to the |
1042 | // expected tags. |
1043 | if (Lex.getKind() != lltok::kw_gv && Lex.getKind() != lltok::kw_module && |
1044 | Lex.getKind() != lltok::kw_typeid && Lex.getKind() != lltok::kw_flags && |
1045 | Lex.getKind() != lltok::kw_blockcount) |
1046 | return tokError( |
1047 | Msg: "Expected 'gv', 'module', 'typeid', 'flags' or 'blockcount' at the " |
1048 | "start of summary entry" ); |
1049 | if (Lex.getKind() == lltok::kw_flags) |
1050 | return parseSummaryIndexFlags(); |
1051 | if (Lex.getKind() == lltok::kw_blockcount) |
1052 | return parseBlockCount(); |
1053 | Lex.Lex(); |
1054 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' at start of summary entry" ) || |
1055 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' at start of summary entry" )) |
1056 | return true; |
1057 | // Now walk through the parenthesized entry, until the number of open |
1058 | // parentheses goes back down to 0 (the first '(' was parsed above). |
1059 | unsigned NumOpenParen = 1; |
1060 | do { |
1061 | switch (Lex.getKind()) { |
1062 | case lltok::lparen: |
1063 | NumOpenParen++; |
1064 | break; |
1065 | case lltok::rparen: |
1066 | NumOpenParen--; |
1067 | break; |
1068 | case lltok::Eof: |
1069 | return tokError(Msg: "found end of file while parsing summary entry" ); |
1070 | default: |
1071 | // Skip everything in between parentheses. |
1072 | break; |
1073 | } |
1074 | Lex.Lex(); |
1075 | } while (NumOpenParen > 0); |
1076 | return false; |
1077 | } |
1078 | |
1079 | /// SummaryEntry |
1080 | /// ::= SummaryID '=' GVEntry | ModuleEntry | TypeIdEntry |
1081 | bool LLParser::parseSummaryEntry() { |
1082 | assert(Lex.getKind() == lltok::SummaryID); |
1083 | unsigned SummaryID = Lex.getUIntVal(); |
1084 | |
1085 | // For summary entries, colons should be treated as distinct tokens, |
1086 | // not an indication of the end of a label token. |
1087 | Lex.setIgnoreColonInIdentifiers(true); |
1088 | |
1089 | Lex.Lex(); |
1090 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' here" )) |
1091 | return true; |
1092 | |
1093 | // If we don't have an index object, skip the summary entry. |
1094 | if (!Index) |
1095 | return skipModuleSummaryEntry(); |
1096 | |
1097 | bool result = false; |
1098 | switch (Lex.getKind()) { |
1099 | case lltok::kw_gv: |
1100 | result = parseGVEntry(ID: SummaryID); |
1101 | break; |
1102 | case lltok::kw_module: |
1103 | result = parseModuleEntry(ID: SummaryID); |
1104 | break; |
1105 | case lltok::kw_typeid: |
1106 | result = parseTypeIdEntry(ID: SummaryID); |
1107 | break; |
1108 | case lltok::kw_typeidCompatibleVTable: |
1109 | result = parseTypeIdCompatibleVtableEntry(ID: SummaryID); |
1110 | break; |
1111 | case lltok::kw_flags: |
1112 | result = parseSummaryIndexFlags(); |
1113 | break; |
1114 | case lltok::kw_blockcount: |
1115 | result = parseBlockCount(); |
1116 | break; |
1117 | default: |
1118 | result = error(L: Lex.getLoc(), Msg: "unexpected summary kind" ); |
1119 | break; |
1120 | } |
1121 | Lex.setIgnoreColonInIdentifiers(false); |
1122 | return result; |
1123 | } |
1124 | |
1125 | static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { |
1126 | return !GlobalValue::isLocalLinkage(Linkage: (GlobalValue::LinkageTypes)L) || |
1127 | (GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility; |
1128 | } |
1129 | static bool isValidDLLStorageClassForLinkage(unsigned S, unsigned L) { |
1130 | return !GlobalValue::isLocalLinkage(Linkage: (GlobalValue::LinkageTypes)L) || |
1131 | (GlobalValue::DLLStorageClassTypes)S == GlobalValue::DefaultStorageClass; |
1132 | } |
1133 | |
1134 | // If there was an explicit dso_local, update GV. In the absence of an explicit |
1135 | // dso_local we keep the default value. |
1136 | static void maybeSetDSOLocal(bool DSOLocal, GlobalValue &GV) { |
1137 | if (DSOLocal) |
1138 | GV.setDSOLocal(true); |
1139 | } |
1140 | |
1141 | /// parseAliasOrIFunc: |
1142 | /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier |
1143 | /// OptionalVisibility OptionalDLLStorageClass |
1144 | /// OptionalThreadLocal OptionalUnnamedAddr |
1145 | /// 'alias|ifunc' AliaseeOrResolver SymbolAttrs* |
1146 | /// |
1147 | /// AliaseeOrResolver |
1148 | /// ::= TypeAndValue |
1149 | /// |
1150 | /// SymbolAttrs |
1151 | /// ::= ',' 'partition' StringConstant |
1152 | /// |
1153 | /// Everything through OptionalUnnamedAddr has already been parsed. |
1154 | /// |
1155 | bool LLParser::parseAliasOrIFunc(const std::string &Name, unsigned NameID, |
1156 | LocTy NameLoc, unsigned L, unsigned Visibility, |
1157 | unsigned DLLStorageClass, bool DSOLocal, |
1158 | GlobalVariable::ThreadLocalMode TLM, |
1159 | GlobalVariable::UnnamedAddr UnnamedAddr) { |
1160 | bool IsAlias; |
1161 | if (Lex.getKind() == lltok::kw_alias) |
1162 | IsAlias = true; |
1163 | else if (Lex.getKind() == lltok::kw_ifunc) |
1164 | IsAlias = false; |
1165 | else |
1166 | llvm_unreachable("Not an alias or ifunc!" ); |
1167 | Lex.Lex(); |
1168 | |
1169 | GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L; |
1170 | |
1171 | if(IsAlias && !GlobalAlias::isValidLinkage(L: Linkage)) |
1172 | return error(L: NameLoc, Msg: "invalid linkage type for alias" ); |
1173 | |
1174 | if (!isValidVisibilityForLinkage(V: Visibility, L)) |
1175 | return error(L: NameLoc, |
1176 | Msg: "symbol with local linkage must have default visibility" ); |
1177 | |
1178 | if (!isValidDLLStorageClassForLinkage(S: DLLStorageClass, L)) |
1179 | return error(L: NameLoc, |
1180 | Msg: "symbol with local linkage cannot have a DLL storage class" ); |
1181 | |
1182 | Type *Ty; |
1183 | LocTy ExplicitTypeLoc = Lex.getLoc(); |
1184 | if (parseType(Result&: Ty) || |
1185 | parseToken(T: lltok::comma, ErrMsg: "expected comma after alias or ifunc's type" )) |
1186 | return true; |
1187 | |
1188 | Constant *Aliasee; |
1189 | LocTy AliaseeLoc = Lex.getLoc(); |
1190 | if (Lex.getKind() != lltok::kw_bitcast && |
1191 | Lex.getKind() != lltok::kw_getelementptr && |
1192 | Lex.getKind() != lltok::kw_addrspacecast && |
1193 | Lex.getKind() != lltok::kw_inttoptr) { |
1194 | if (parseGlobalTypeAndValue(V&: Aliasee)) |
1195 | return true; |
1196 | } else { |
1197 | // The bitcast dest type is not present, it is implied by the dest type. |
1198 | ValID ID; |
1199 | if (parseValID(ID, /*PFS=*/nullptr)) |
1200 | return true; |
1201 | if (ID.Kind != ValID::t_Constant) |
1202 | return error(L: AliaseeLoc, Msg: "invalid aliasee" ); |
1203 | Aliasee = ID.ConstantVal; |
1204 | } |
1205 | |
1206 | Type *AliaseeType = Aliasee->getType(); |
1207 | auto *PTy = dyn_cast<PointerType>(Val: AliaseeType); |
1208 | if (!PTy) |
1209 | return error(L: AliaseeLoc, Msg: "An alias or ifunc must have pointer type" ); |
1210 | unsigned AddrSpace = PTy->getAddressSpace(); |
1211 | |
1212 | GlobalValue *GVal = nullptr; |
1213 | |
1214 | // See if the alias was forward referenced, if so, prepare to replace the |
1215 | // forward reference. |
1216 | if (!Name.empty()) { |
1217 | auto I = ForwardRefVals.find(x: Name); |
1218 | if (I != ForwardRefVals.end()) { |
1219 | GVal = I->second.first; |
1220 | ForwardRefVals.erase(x: Name); |
1221 | } else if (M->getNamedValue(Name)) { |
1222 | return error(L: NameLoc, Msg: "redefinition of global '@" + Name + "'" ); |
1223 | } |
1224 | } else { |
1225 | auto I = ForwardRefValIDs.find(x: NameID); |
1226 | if (I != ForwardRefValIDs.end()) { |
1227 | GVal = I->second.first; |
1228 | ForwardRefValIDs.erase(position: I); |
1229 | } |
1230 | } |
1231 | |
1232 | // Okay, create the alias/ifunc but do not insert it into the module yet. |
1233 | std::unique_ptr<GlobalAlias> GA; |
1234 | std::unique_ptr<GlobalIFunc> GI; |
1235 | GlobalValue *GV; |
1236 | if (IsAlias) { |
1237 | GA.reset(p: GlobalAlias::create(Ty, AddressSpace: AddrSpace, Linkage, Name, Aliasee, |
1238 | /*Parent=*/nullptr)); |
1239 | GV = GA.get(); |
1240 | } else { |
1241 | GI.reset(p: GlobalIFunc::create(Ty, AddressSpace: AddrSpace, Linkage, Name, Resolver: Aliasee, |
1242 | /*Parent=*/nullptr)); |
1243 | GV = GI.get(); |
1244 | } |
1245 | GV->setThreadLocalMode(TLM); |
1246 | GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); |
1247 | GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); |
1248 | GV->setUnnamedAddr(UnnamedAddr); |
1249 | maybeSetDSOLocal(DSOLocal, GV&: *GV); |
1250 | |
1251 | // At this point we've parsed everything except for the IndirectSymbolAttrs. |
1252 | // Now parse them if there are any. |
1253 | while (Lex.getKind() == lltok::comma) { |
1254 | Lex.Lex(); |
1255 | |
1256 | if (Lex.getKind() == lltok::kw_partition) { |
1257 | Lex.Lex(); |
1258 | GV->setPartition(Lex.getStrVal()); |
1259 | if (parseToken(T: lltok::StringConstant, ErrMsg: "expected partition string" )) |
1260 | return true; |
1261 | } else { |
1262 | return tokError(Msg: "unknown alias or ifunc property!" ); |
1263 | } |
1264 | } |
1265 | |
1266 | if (Name.empty()) |
1267 | NumberedVals.add(ID: NameID, V: GV); |
1268 | |
1269 | if (GVal) { |
1270 | // Verify that types agree. |
1271 | if (GVal->getType() != GV->getType()) |
1272 | return error( |
1273 | L: ExplicitTypeLoc, |
1274 | Msg: "forward reference and definition of alias have different types" ); |
1275 | |
1276 | // If they agree, just RAUW the old value with the alias and remove the |
1277 | // forward ref info. |
1278 | GVal->replaceAllUsesWith(V: GV); |
1279 | GVal->eraseFromParent(); |
1280 | } |
1281 | |
1282 | // Insert into the module, we know its name won't collide now. |
1283 | if (IsAlias) |
1284 | M->insertAlias(Alias: GA.release()); |
1285 | else |
1286 | M->insertIFunc(IFunc: GI.release()); |
1287 | assert(GV->getName() == Name && "Should not be a name conflict!" ); |
1288 | |
1289 | return false; |
1290 | } |
1291 | |
1292 | static bool isSanitizer(lltok::Kind Kind) { |
1293 | switch (Kind) { |
1294 | case lltok::kw_no_sanitize_address: |
1295 | case lltok::kw_no_sanitize_hwaddress: |
1296 | case lltok::kw_sanitize_memtag: |
1297 | case lltok::kw_sanitize_address_dyninit: |
1298 | return true; |
1299 | default: |
1300 | return false; |
1301 | } |
1302 | } |
1303 | |
1304 | bool LLParser::parseSanitizer(GlobalVariable *GV) { |
1305 | using SanitizerMetadata = GlobalValue::SanitizerMetadata; |
1306 | SanitizerMetadata Meta; |
1307 | if (GV->hasSanitizerMetadata()) |
1308 | Meta = GV->getSanitizerMetadata(); |
1309 | |
1310 | switch (Lex.getKind()) { |
1311 | case lltok::kw_no_sanitize_address: |
1312 | Meta.NoAddress = true; |
1313 | break; |
1314 | case lltok::kw_no_sanitize_hwaddress: |
1315 | Meta.NoHWAddress = true; |
1316 | break; |
1317 | case lltok::kw_sanitize_memtag: |
1318 | Meta.Memtag = true; |
1319 | break; |
1320 | case lltok::kw_sanitize_address_dyninit: |
1321 | Meta.IsDynInit = true; |
1322 | break; |
1323 | default: |
1324 | return tokError(Msg: "non-sanitizer token passed to LLParser::parseSanitizer()" ); |
1325 | } |
1326 | GV->setSanitizerMetadata(Meta); |
1327 | Lex.Lex(); |
1328 | return false; |
1329 | } |
1330 | |
1331 | /// parseGlobal |
1332 | /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier |
1333 | /// OptionalVisibility OptionalDLLStorageClass |
1334 | /// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace |
1335 | /// OptionalExternallyInitialized GlobalType Type Const OptionalAttrs |
1336 | /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility |
1337 | /// OptionalDLLStorageClass OptionalThreadLocal OptionalUnnamedAddr |
1338 | /// OptionalAddrSpace OptionalExternallyInitialized GlobalType Type |
1339 | /// Const OptionalAttrs |
1340 | /// |
1341 | /// Everything up to and including OptionalUnnamedAddr has been parsed |
1342 | /// already. |
1343 | /// |
1344 | bool LLParser::parseGlobal(const std::string &Name, unsigned NameID, |
1345 | LocTy NameLoc, unsigned Linkage, bool HasLinkage, |
1346 | unsigned Visibility, unsigned DLLStorageClass, |
1347 | bool DSOLocal, GlobalVariable::ThreadLocalMode TLM, |
1348 | GlobalVariable::UnnamedAddr UnnamedAddr) { |
1349 | if (!isValidVisibilityForLinkage(V: Visibility, L: Linkage)) |
1350 | return error(L: NameLoc, |
1351 | Msg: "symbol with local linkage must have default visibility" ); |
1352 | |
1353 | if (!isValidDLLStorageClassForLinkage(S: DLLStorageClass, L: Linkage)) |
1354 | return error(L: NameLoc, |
1355 | Msg: "symbol with local linkage cannot have a DLL storage class" ); |
1356 | |
1357 | unsigned AddrSpace; |
1358 | bool IsConstant, IsExternallyInitialized; |
1359 | LocTy IsExternallyInitializedLoc; |
1360 | LocTy TyLoc; |
1361 | |
1362 | Type *Ty = nullptr; |
1363 | if (parseOptionalAddrSpace(AddrSpace) || |
1364 | parseOptionalToken(T: lltok::kw_externally_initialized, |
1365 | Present&: IsExternallyInitialized, |
1366 | Loc: &IsExternallyInitializedLoc) || |
1367 | parseGlobalType(IsConstant) || parseType(Result&: Ty, Loc&: TyLoc)) |
1368 | return true; |
1369 | |
1370 | // If the linkage is specified and is external, then no initializer is |
1371 | // present. |
1372 | Constant *Init = nullptr; |
1373 | if (!HasLinkage || |
1374 | !GlobalValue::isValidDeclarationLinkage( |
1375 | Linkage: (GlobalValue::LinkageTypes)Linkage)) { |
1376 | if (parseGlobalValue(Ty, C&: Init)) |
1377 | return true; |
1378 | } |
1379 | |
1380 | if (Ty->isFunctionTy() || !PointerType::isValidElementType(ElemTy: Ty)) |
1381 | return error(L: TyLoc, Msg: "invalid type for global variable" ); |
1382 | |
1383 | GlobalValue *GVal = nullptr; |
1384 | |
1385 | // See if the global was forward referenced, if so, use the global. |
1386 | if (!Name.empty()) { |
1387 | auto I = ForwardRefVals.find(x: Name); |
1388 | if (I != ForwardRefVals.end()) { |
1389 | GVal = I->second.first; |
1390 | ForwardRefVals.erase(position: I); |
1391 | } else if (M->getNamedValue(Name)) { |
1392 | return error(L: NameLoc, Msg: "redefinition of global '@" + Name + "'" ); |
1393 | } |
1394 | } else { |
1395 | // Handle @"", where a name is syntactically specified, but semantically |
1396 | // missing. |
1397 | if (NameID == (unsigned)-1) |
1398 | NameID = NumberedVals.getNext(); |
1399 | |
1400 | auto I = ForwardRefValIDs.find(x: NameID); |
1401 | if (I != ForwardRefValIDs.end()) { |
1402 | GVal = I->second.first; |
1403 | ForwardRefValIDs.erase(position: I); |
1404 | } |
1405 | } |
1406 | |
1407 | GlobalVariable *GV = new GlobalVariable( |
1408 | *M, Ty, false, GlobalValue::ExternalLinkage, nullptr, Name, nullptr, |
1409 | GlobalVariable::NotThreadLocal, AddrSpace); |
1410 | |
1411 | if (Name.empty()) |
1412 | NumberedVals.add(ID: NameID, V: GV); |
1413 | |
1414 | // Set the parsed properties on the global. |
1415 | if (Init) |
1416 | GV->setInitializer(Init); |
1417 | GV->setConstant(IsConstant); |
1418 | GV->setLinkage((GlobalValue::LinkageTypes)Linkage); |
1419 | maybeSetDSOLocal(DSOLocal, GV&: *GV); |
1420 | GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); |
1421 | GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); |
1422 | GV->setExternallyInitialized(IsExternallyInitialized); |
1423 | GV->setThreadLocalMode(TLM); |
1424 | GV->setUnnamedAddr(UnnamedAddr); |
1425 | |
1426 | if (GVal) { |
1427 | if (GVal->getAddressSpace() != AddrSpace) |
1428 | return error( |
1429 | L: TyLoc, |
1430 | Msg: "forward reference and definition of global have different types" ); |
1431 | |
1432 | GVal->replaceAllUsesWith(V: GV); |
1433 | GVal->eraseFromParent(); |
1434 | } |
1435 | |
1436 | // parse attributes on the global. |
1437 | while (Lex.getKind() == lltok::comma) { |
1438 | Lex.Lex(); |
1439 | |
1440 | if (Lex.getKind() == lltok::kw_section) { |
1441 | Lex.Lex(); |
1442 | GV->setSection(Lex.getStrVal()); |
1443 | if (parseToken(T: lltok::StringConstant, ErrMsg: "expected global section string" )) |
1444 | return true; |
1445 | } else if (Lex.getKind() == lltok::kw_partition) { |
1446 | Lex.Lex(); |
1447 | GV->setPartition(Lex.getStrVal()); |
1448 | if (parseToken(T: lltok::StringConstant, ErrMsg: "expected partition string" )) |
1449 | return true; |
1450 | } else if (Lex.getKind() == lltok::kw_align) { |
1451 | MaybeAlign Alignment; |
1452 | if (parseOptionalAlignment(Alignment)) |
1453 | return true; |
1454 | if (Alignment) |
1455 | GV->setAlignment(*Alignment); |
1456 | } else if (Lex.getKind() == lltok::kw_code_model) { |
1457 | CodeModel::Model CodeModel; |
1458 | if (parseOptionalCodeModel(model&: CodeModel)) |
1459 | return true; |
1460 | GV->setCodeModel(CodeModel); |
1461 | } else if (Lex.getKind() == lltok::MetadataVar) { |
1462 | if (parseGlobalObjectMetadataAttachment(GO&: *GV)) |
1463 | return true; |
1464 | } else if (isSanitizer(Kind: Lex.getKind())) { |
1465 | if (parseSanitizer(GV)) |
1466 | return true; |
1467 | } else { |
1468 | Comdat *C; |
1469 | if (parseOptionalComdat(GlobalName: Name, C)) |
1470 | return true; |
1471 | if (C) |
1472 | GV->setComdat(C); |
1473 | else |
1474 | return tokError(Msg: "unknown global variable property!" ); |
1475 | } |
1476 | } |
1477 | |
1478 | AttrBuilder Attrs(M->getContext()); |
1479 | LocTy BuiltinLoc; |
1480 | std::vector<unsigned> FwdRefAttrGrps; |
1481 | if (parseFnAttributeValuePairs(B&: Attrs, FwdRefAttrGrps, inAttrGrp: false, BuiltinLoc)) |
1482 | return true; |
1483 | if (Attrs.hasAttributes() || !FwdRefAttrGrps.empty()) { |
1484 | GV->setAttributes(AttributeSet::get(C&: Context, B: Attrs)); |
1485 | ForwardRefAttrGroups[GV] = FwdRefAttrGrps; |
1486 | } |
1487 | |
1488 | return false; |
1489 | } |
1490 | |
1491 | /// parseUnnamedAttrGrp |
1492 | /// ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}' |
1493 | bool LLParser::parseUnnamedAttrGrp() { |
1494 | assert(Lex.getKind() == lltok::kw_attributes); |
1495 | LocTy AttrGrpLoc = Lex.getLoc(); |
1496 | Lex.Lex(); |
1497 | |
1498 | if (Lex.getKind() != lltok::AttrGrpID) |
1499 | return tokError(Msg: "expected attribute group id" ); |
1500 | |
1501 | unsigned VarID = Lex.getUIntVal(); |
1502 | std::vector<unsigned> unused; |
1503 | LocTy BuiltinLoc; |
1504 | Lex.Lex(); |
1505 | |
1506 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' here" ) || |
1507 | parseToken(T: lltok::lbrace, ErrMsg: "expected '{' here" )) |
1508 | return true; |
1509 | |
1510 | auto R = NumberedAttrBuilders.find(x: VarID); |
1511 | if (R == NumberedAttrBuilders.end()) |
1512 | R = NumberedAttrBuilders.emplace(args&: VarID, args: AttrBuilder(M->getContext())).first; |
1513 | |
1514 | if (parseFnAttributeValuePairs(B&: R->second, FwdRefAttrGrps&: unused, inAttrGrp: true, BuiltinLoc) || |
1515 | parseToken(T: lltok::rbrace, ErrMsg: "expected end of attribute group" )) |
1516 | return true; |
1517 | |
1518 | if (!R->second.hasAttributes()) |
1519 | return error(L: AttrGrpLoc, Msg: "attribute group has no attributes" ); |
1520 | |
1521 | return false; |
1522 | } |
1523 | |
1524 | static Attribute::AttrKind tokenToAttribute(lltok::Kind Kind) { |
1525 | switch (Kind) { |
1526 | #define GET_ATTR_NAMES |
1527 | #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \ |
1528 | case lltok::kw_##DISPLAY_NAME: \ |
1529 | return Attribute::ENUM_NAME; |
1530 | #include "llvm/IR/Attributes.inc" |
1531 | default: |
1532 | return Attribute::None; |
1533 | } |
1534 | } |
1535 | |
1536 | bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B, |
1537 | bool InAttrGroup) { |
1538 | if (Attribute::isTypeAttrKind(Kind: Attr)) |
1539 | return parseRequiredTypeAttr(B, AttrToken: Lex.getKind(), AttrKind: Attr); |
1540 | |
1541 | switch (Attr) { |
1542 | case Attribute::Alignment: { |
1543 | MaybeAlign Alignment; |
1544 | if (InAttrGroup) { |
1545 | uint32_t Value = 0; |
1546 | Lex.Lex(); |
1547 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' here" ) || parseUInt32(Val&: Value)) |
1548 | return true; |
1549 | Alignment = Align(Value); |
1550 | } else { |
1551 | if (parseOptionalAlignment(Alignment, AllowParens: true)) |
1552 | return true; |
1553 | } |
1554 | B.addAlignmentAttr(Align: Alignment); |
1555 | return false; |
1556 | } |
1557 | case Attribute::StackAlignment: { |
1558 | unsigned Alignment; |
1559 | if (InAttrGroup) { |
1560 | Lex.Lex(); |
1561 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' here" ) || |
1562 | parseUInt32(Val&: Alignment)) |
1563 | return true; |
1564 | } else { |
1565 | if (parseOptionalStackAlignment(Alignment)) |
1566 | return true; |
1567 | } |
1568 | B.addStackAlignmentAttr(Align: Alignment); |
1569 | return false; |
1570 | } |
1571 | case Attribute::AllocSize: { |
1572 | unsigned ElemSizeArg; |
1573 | std::optional<unsigned> NumElemsArg; |
1574 | if (parseAllocSizeArguments(BaseSizeArg&: ElemSizeArg, HowManyArg&: NumElemsArg)) |
1575 | return true; |
1576 | B.addAllocSizeAttr(ElemSizeArg, NumElemsArg); |
1577 | return false; |
1578 | } |
1579 | case Attribute::VScaleRange: { |
1580 | unsigned MinValue, MaxValue; |
1581 | if (parseVScaleRangeArguments(MinValue, MaxValue)) |
1582 | return true; |
1583 | B.addVScaleRangeAttr(MinValue, |
1584 | MaxValue: MaxValue > 0 ? MaxValue : std::optional<unsigned>()); |
1585 | return false; |
1586 | } |
1587 | case Attribute::Dereferenceable: { |
1588 | uint64_t Bytes; |
1589 | if (parseOptionalDerefAttrBytes(AttrKind: lltok::kw_dereferenceable, Bytes)) |
1590 | return true; |
1591 | B.addDereferenceableAttr(Bytes); |
1592 | return false; |
1593 | } |
1594 | case Attribute::DereferenceableOrNull: { |
1595 | uint64_t Bytes; |
1596 | if (parseOptionalDerefAttrBytes(AttrKind: lltok::kw_dereferenceable_or_null, Bytes)) |
1597 | return true; |
1598 | B.addDereferenceableOrNullAttr(Bytes); |
1599 | return false; |
1600 | } |
1601 | case Attribute::UWTable: { |
1602 | UWTableKind Kind; |
1603 | if (parseOptionalUWTableKind(Kind)) |
1604 | return true; |
1605 | B.addUWTableAttr(Kind); |
1606 | return false; |
1607 | } |
1608 | case Attribute::AllocKind: { |
1609 | AllocFnKind Kind = AllocFnKind::Unknown; |
1610 | if (parseAllocKind(Kind)) |
1611 | return true; |
1612 | B.addAllocKindAttr(Kind); |
1613 | return false; |
1614 | } |
1615 | case Attribute::Memory: { |
1616 | std::optional<MemoryEffects> ME = parseMemoryAttr(); |
1617 | if (!ME) |
1618 | return true; |
1619 | B.addMemoryAttr(ME: *ME); |
1620 | return false; |
1621 | } |
1622 | case Attribute::NoFPClass: { |
1623 | if (FPClassTest NoFPClass = |
1624 | static_cast<FPClassTest>(parseNoFPClassAttr())) { |
1625 | B.addNoFPClassAttr(NoFPClassMask: NoFPClass); |
1626 | return false; |
1627 | } |
1628 | |
1629 | return true; |
1630 | } |
1631 | case Attribute::Range: |
1632 | return parseRangeAttr(B); |
1633 | case Attribute::Initializes: |
1634 | return parseInitializesAttr(B); |
1635 | case Attribute::Captures: |
1636 | return parseCapturesAttr(B); |
1637 | default: |
1638 | B.addAttribute(Val: Attr); |
1639 | Lex.Lex(); |
1640 | return false; |
1641 | } |
1642 | } |
1643 | |
1644 | static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) { |
1645 | switch (Kind) { |
1646 | case lltok::kw_readnone: |
1647 | ME &= MemoryEffects::none(); |
1648 | return true; |
1649 | case lltok::kw_readonly: |
1650 | ME &= MemoryEffects::readOnly(); |
1651 | return true; |
1652 | case lltok::kw_writeonly: |
1653 | ME &= MemoryEffects::writeOnly(); |
1654 | return true; |
1655 | case lltok::kw_argmemonly: |
1656 | ME &= MemoryEffects::argMemOnly(); |
1657 | return true; |
1658 | case lltok::kw_inaccessiblememonly: |
1659 | ME &= MemoryEffects::inaccessibleMemOnly(); |
1660 | return true; |
1661 | case lltok::kw_inaccessiblemem_or_argmemonly: |
1662 | ME &= MemoryEffects::inaccessibleOrArgMemOnly(); |
1663 | return true; |
1664 | default: |
1665 | return false; |
1666 | } |
1667 | } |
1668 | |
1669 | /// parseFnAttributeValuePairs |
1670 | /// ::= <attr> | <attr> '=' <value> |
1671 | bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, |
1672 | std::vector<unsigned> &FwdRefAttrGrps, |
1673 | bool InAttrGrp, LocTy &BuiltinLoc) { |
1674 | bool HaveError = false; |
1675 | |
1676 | B.clear(); |
1677 | |
1678 | MemoryEffects ME = MemoryEffects::unknown(); |
1679 | while (true) { |
1680 | lltok::Kind Token = Lex.getKind(); |
1681 | if (Token == lltok::rbrace) |
1682 | break; // Finished. |
1683 | |
1684 | if (Token == lltok::StringConstant) { |
1685 | if (parseStringAttribute(B)) |
1686 | return true; |
1687 | continue; |
1688 | } |
1689 | |
1690 | if (Token == lltok::AttrGrpID) { |
1691 | // Allow a function to reference an attribute group: |
1692 | // |
1693 | // define void @foo() #1 { ... } |
1694 | if (InAttrGrp) { |
1695 | HaveError |= error( |
1696 | L: Lex.getLoc(), |
1697 | Msg: "cannot have an attribute group reference in an attribute group" ); |
1698 | } else { |
1699 | // Save the reference to the attribute group. We'll fill it in later. |
1700 | FwdRefAttrGrps.push_back(x: Lex.getUIntVal()); |
1701 | } |
1702 | Lex.Lex(); |
1703 | continue; |
1704 | } |
1705 | |
1706 | SMLoc Loc = Lex.getLoc(); |
1707 | if (Token == lltok::kw_builtin) |
1708 | BuiltinLoc = Loc; |
1709 | |
1710 | if (upgradeMemoryAttr(ME, Kind: Token)) { |
1711 | Lex.Lex(); |
1712 | continue; |
1713 | } |
1714 | |
1715 | Attribute::AttrKind Attr = tokenToAttribute(Kind: Token); |
1716 | if (Attr == Attribute::None) { |
1717 | if (!InAttrGrp) |
1718 | break; |
1719 | return error(L: Lex.getLoc(), Msg: "unterminated attribute group" ); |
1720 | } |
1721 | |
1722 | if (parseEnumAttribute(Attr, B, InAttrGroup: InAttrGrp)) |
1723 | return true; |
1724 | |
1725 | // As a hack, we allow function alignment to be initially parsed as an |
1726 | // attribute on a function declaration/definition or added to an attribute |
1727 | // group and later moved to the alignment field. |
1728 | if (!Attribute::canUseAsFnAttr(Kind: Attr) && Attr != Attribute::Alignment) |
1729 | HaveError |= error(L: Loc, Msg: "this attribute does not apply to functions" ); |
1730 | } |
1731 | |
1732 | if (ME != MemoryEffects::unknown()) |
1733 | B.addMemoryAttr(ME); |
1734 | return HaveError; |
1735 | } |
1736 | |
1737 | //===----------------------------------------------------------------------===// |
1738 | // GlobalValue Reference/Resolution Routines. |
1739 | //===----------------------------------------------------------------------===// |
1740 | |
1741 | static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy) { |
1742 | // The used global type does not matter. We will later RAUW it with a |
1743 | // global/function of the correct type. |
1744 | return new GlobalVariable(*M, Type::getInt8Ty(C&: M->getContext()), false, |
1745 | GlobalValue::ExternalWeakLinkage, nullptr, "" , |
1746 | nullptr, GlobalVariable::NotThreadLocal, |
1747 | PTy->getAddressSpace()); |
1748 | } |
1749 | |
1750 | Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty, |
1751 | Value *Val) { |
1752 | Type *ValTy = Val->getType(); |
1753 | if (ValTy == Ty) |
1754 | return Val; |
1755 | if (Ty->isLabelTy()) |
1756 | error(L: Loc, Msg: "'" + Name + "' is not a basic block" ); |
1757 | else |
1758 | error(L: Loc, Msg: "'" + Name + "' defined with type '" + |
1759 | getTypeString(T: Val->getType()) + "' but expected '" + |
1760 | getTypeString(T: Ty) + "'" ); |
1761 | return nullptr; |
1762 | } |
1763 | |
1764 | /// getGlobalVal - Get a value with the specified name or ID, creating a |
1765 | /// forward reference record if needed. This can return null if the value |
1766 | /// exists but does not have the right type. |
1767 | GlobalValue *LLParser::getGlobalVal(const std::string &Name, Type *Ty, |
1768 | LocTy Loc) { |
1769 | PointerType *PTy = dyn_cast<PointerType>(Val: Ty); |
1770 | if (!PTy) { |
1771 | error(L: Loc, Msg: "global variable reference must have pointer type" ); |
1772 | return nullptr; |
1773 | } |
1774 | |
1775 | // Look this name up in the normal function symbol table. |
1776 | GlobalValue *Val = |
1777 | cast_or_null<GlobalValue>(Val: M->getValueSymbolTable().lookup(Name)); |
1778 | |
1779 | // If this is a forward reference for the value, see if we already created a |
1780 | // forward ref record. |
1781 | if (!Val) { |
1782 | auto I = ForwardRefVals.find(x: Name); |
1783 | if (I != ForwardRefVals.end()) |
1784 | Val = I->second.first; |
1785 | } |
1786 | |
1787 | // If we have the value in the symbol table or fwd-ref table, return it. |
1788 | if (Val) |
1789 | return cast_or_null<GlobalValue>( |
1790 | Val: checkValidVariableType(Loc, Name: "@" + Name, Ty, Val)); |
1791 | |
1792 | // Otherwise, create a new forward reference for this value and remember it. |
1793 | GlobalValue *FwdVal = createGlobalFwdRef(M, PTy); |
1794 | ForwardRefVals[Name] = std::make_pair(x&: FwdVal, y&: Loc); |
1795 | return FwdVal; |
1796 | } |
1797 | |
1798 | GlobalValue *LLParser::getGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { |
1799 | PointerType *PTy = dyn_cast<PointerType>(Val: Ty); |
1800 | if (!PTy) { |
1801 | error(L: Loc, Msg: "global variable reference must have pointer type" ); |
1802 | return nullptr; |
1803 | } |
1804 | |
1805 | GlobalValue *Val = NumberedVals.get(ID); |
1806 | |
1807 | // If this is a forward reference for the value, see if we already created a |
1808 | // forward ref record. |
1809 | if (!Val) { |
1810 | auto I = ForwardRefValIDs.find(x: ID); |
1811 | if (I != ForwardRefValIDs.end()) |
1812 | Val = I->second.first; |
1813 | } |
1814 | |
1815 | // If we have the value in the symbol table or fwd-ref table, return it. |
1816 | if (Val) |
1817 | return cast_or_null<GlobalValue>( |
1818 | Val: checkValidVariableType(Loc, Name: "@" + Twine(ID), Ty, Val)); |
1819 | |
1820 | // Otherwise, create a new forward reference for this value and remember it. |
1821 | GlobalValue *FwdVal = createGlobalFwdRef(M, PTy); |
1822 | ForwardRefValIDs[ID] = std::make_pair(x&: FwdVal, y&: Loc); |
1823 | return FwdVal; |
1824 | } |
1825 | |
1826 | //===----------------------------------------------------------------------===// |
1827 | // Comdat Reference/Resolution Routines. |
1828 | //===----------------------------------------------------------------------===// |
1829 | |
1830 | Comdat *LLParser::getComdat(const std::string &Name, LocTy Loc) { |
1831 | // Look this name up in the comdat symbol table. |
1832 | Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable(); |
1833 | Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Key: Name); |
1834 | if (I != ComdatSymTab.end()) |
1835 | return &I->second; |
1836 | |
1837 | // Otherwise, create a new forward reference for this value and remember it. |
1838 | Comdat *C = M->getOrInsertComdat(Name); |
1839 | ForwardRefComdats[Name] = Loc; |
1840 | return C; |
1841 | } |
1842 | |
1843 | //===----------------------------------------------------------------------===// |
1844 | // Helper Routines. |
1845 | //===----------------------------------------------------------------------===// |
1846 | |
1847 | /// parseToken - If the current token has the specified kind, eat it and return |
1848 | /// success. Otherwise, emit the specified error and return failure. |
1849 | bool LLParser::parseToken(lltok::Kind T, const char *ErrMsg) { |
1850 | if (Lex.getKind() != T) |
1851 | return tokError(Msg: ErrMsg); |
1852 | Lex.Lex(); |
1853 | return false; |
1854 | } |
1855 | |
1856 | /// parseStringConstant |
1857 | /// ::= StringConstant |
1858 | bool LLParser::parseStringConstant(std::string &Result) { |
1859 | if (Lex.getKind() != lltok::StringConstant) |
1860 | return tokError(Msg: "expected string constant" ); |
1861 | Result = Lex.getStrVal(); |
1862 | Lex.Lex(); |
1863 | return false; |
1864 | } |
1865 | |
1866 | /// parseUInt32 |
1867 | /// ::= uint32 |
1868 | bool LLParser::parseUInt32(uint32_t &Val) { |
1869 | if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) |
1870 | return tokError(Msg: "expected integer" ); |
1871 | uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(Limit: 0xFFFFFFFFULL+1); |
1872 | if (Val64 != unsigned(Val64)) |
1873 | return tokError(Msg: "expected 32-bit integer (too large)" ); |
1874 | Val = Val64; |
1875 | Lex.Lex(); |
1876 | return false; |
1877 | } |
1878 | |
1879 | /// parseUInt64 |
1880 | /// ::= uint64 |
1881 | bool LLParser::parseUInt64(uint64_t &Val) { |
1882 | if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) |
1883 | return tokError(Msg: "expected integer" ); |
1884 | Val = Lex.getAPSIntVal().getLimitedValue(); |
1885 | Lex.Lex(); |
1886 | return false; |
1887 | } |
1888 | |
1889 | /// parseTLSModel |
1890 | /// := 'localdynamic' |
1891 | /// := 'initialexec' |
1892 | /// := 'localexec' |
1893 | bool LLParser::parseTLSModel(GlobalVariable::ThreadLocalMode &TLM) { |
1894 | switch (Lex.getKind()) { |
1895 | default: |
1896 | return tokError(Msg: "expected localdynamic, initialexec or localexec" ); |
1897 | case lltok::kw_localdynamic: |
1898 | TLM = GlobalVariable::LocalDynamicTLSModel; |
1899 | break; |
1900 | case lltok::kw_initialexec: |
1901 | TLM = GlobalVariable::InitialExecTLSModel; |
1902 | break; |
1903 | case lltok::kw_localexec: |
1904 | TLM = GlobalVariable::LocalExecTLSModel; |
1905 | break; |
1906 | } |
1907 | |
1908 | Lex.Lex(); |
1909 | return false; |
1910 | } |
1911 | |
1912 | /// parseOptionalThreadLocal |
1913 | /// := /*empty*/ |
1914 | /// := 'thread_local' |
1915 | /// := 'thread_local' '(' tlsmodel ')' |
1916 | bool LLParser::parseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) { |
1917 | TLM = GlobalVariable::NotThreadLocal; |
1918 | if (!EatIfPresent(T: lltok::kw_thread_local)) |
1919 | return false; |
1920 | |
1921 | TLM = GlobalVariable::GeneralDynamicTLSModel; |
1922 | if (Lex.getKind() == lltok::lparen) { |
1923 | Lex.Lex(); |
1924 | return parseTLSModel(TLM) || |
1925 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' after thread local model" ); |
1926 | } |
1927 | return false; |
1928 | } |
1929 | |
1930 | /// parseOptionalAddrSpace |
1931 | /// := /*empty*/ |
1932 | /// := 'addrspace' '(' uint32 ')' |
1933 | bool LLParser::parseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS) { |
1934 | AddrSpace = DefaultAS; |
1935 | if (!EatIfPresent(T: lltok::kw_addrspace)) |
1936 | return false; |
1937 | |
1938 | auto ParseAddrspaceValue = [&](unsigned &AddrSpace) -> bool { |
1939 | if (Lex.getKind() == lltok::StringConstant) { |
1940 | auto AddrSpaceStr = Lex.getStrVal(); |
1941 | if (AddrSpaceStr == "A" ) { |
1942 | AddrSpace = M->getDataLayout().getAllocaAddrSpace(); |
1943 | } else if (AddrSpaceStr == "G" ) { |
1944 | AddrSpace = M->getDataLayout().getDefaultGlobalsAddressSpace(); |
1945 | } else if (AddrSpaceStr == "P" ) { |
1946 | AddrSpace = M->getDataLayout().getProgramAddressSpace(); |
1947 | } else { |
1948 | return tokError(Msg: "invalid symbolic addrspace '" + AddrSpaceStr + "'" ); |
1949 | } |
1950 | Lex.Lex(); |
1951 | return false; |
1952 | } |
1953 | if (Lex.getKind() != lltok::APSInt) |
1954 | return tokError(Msg: "expected integer or string constant" ); |
1955 | SMLoc Loc = Lex.getLoc(); |
1956 | if (parseUInt32(Val&: AddrSpace)) |
1957 | return true; |
1958 | if (!isUInt<24>(x: AddrSpace)) |
1959 | return error(L: Loc, Msg: "invalid address space, must be a 24-bit integer" ); |
1960 | return false; |
1961 | }; |
1962 | |
1963 | return parseToken(T: lltok::lparen, ErrMsg: "expected '(' in address space" ) || |
1964 | ParseAddrspaceValue(AddrSpace) || |
1965 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' in address space" ); |
1966 | } |
1967 | |
1968 | /// parseStringAttribute |
1969 | /// := StringConstant |
1970 | /// := StringConstant '=' StringConstant |
1971 | bool LLParser::parseStringAttribute(AttrBuilder &B) { |
1972 | std::string Attr = Lex.getStrVal(); |
1973 | Lex.Lex(); |
1974 | std::string Val; |
1975 | if (EatIfPresent(T: lltok::equal) && parseStringConstant(Result&: Val)) |
1976 | return true; |
1977 | B.addAttribute(A: Attr, V: Val); |
1978 | return false; |
1979 | } |
1980 | |
1981 | /// Parse a potentially empty list of parameter or return attributes. |
1982 | bool LLParser::parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam) { |
1983 | bool HaveError = false; |
1984 | |
1985 | B.clear(); |
1986 | |
1987 | while (true) { |
1988 | lltok::Kind Token = Lex.getKind(); |
1989 | if (Token == lltok::StringConstant) { |
1990 | if (parseStringAttribute(B)) |
1991 | return true; |
1992 | continue; |
1993 | } |
1994 | |
1995 | if (Token == lltok::kw_nocapture) { |
1996 | Lex.Lex(); |
1997 | B.addCapturesAttr(CI: CaptureInfo::none()); |
1998 | continue; |
1999 | } |
2000 | |
2001 | SMLoc Loc = Lex.getLoc(); |
2002 | Attribute::AttrKind Attr = tokenToAttribute(Kind: Token); |
2003 | if (Attr == Attribute::None) |
2004 | return HaveError; |
2005 | |
2006 | if (parseEnumAttribute(Attr, B, /* InAttrGroup */ false)) |
2007 | return true; |
2008 | |
2009 | if (IsParam && !Attribute::canUseAsParamAttr(Kind: Attr)) |
2010 | HaveError |= error(L: Loc, Msg: "this attribute does not apply to parameters" ); |
2011 | if (!IsParam && !Attribute::canUseAsRetAttr(Kind: Attr)) |
2012 | HaveError |= error(L: Loc, Msg: "this attribute does not apply to return values" ); |
2013 | } |
2014 | } |
2015 | |
2016 | static unsigned parseOptionalLinkageAux(lltok::Kind Kind, bool &HasLinkage) { |
2017 | HasLinkage = true; |
2018 | switch (Kind) { |
2019 | default: |
2020 | HasLinkage = false; |
2021 | return GlobalValue::ExternalLinkage; |
2022 | case lltok::kw_private: |
2023 | return GlobalValue::PrivateLinkage; |
2024 | case lltok::kw_internal: |
2025 | return GlobalValue::InternalLinkage; |
2026 | case lltok::kw_weak: |
2027 | return GlobalValue::WeakAnyLinkage; |
2028 | case lltok::kw_weak_odr: |
2029 | return GlobalValue::WeakODRLinkage; |
2030 | case lltok::kw_linkonce: |
2031 | return GlobalValue::LinkOnceAnyLinkage; |
2032 | case lltok::kw_linkonce_odr: |
2033 | return GlobalValue::LinkOnceODRLinkage; |
2034 | case lltok::kw_available_externally: |
2035 | return GlobalValue::AvailableExternallyLinkage; |
2036 | case lltok::kw_appending: |
2037 | return GlobalValue::AppendingLinkage; |
2038 | case lltok::kw_common: |
2039 | return GlobalValue::CommonLinkage; |
2040 | case lltok::kw_extern_weak: |
2041 | return GlobalValue::ExternalWeakLinkage; |
2042 | case lltok::kw_external: |
2043 | return GlobalValue::ExternalLinkage; |
2044 | } |
2045 | } |
2046 | |
2047 | /// parseOptionalLinkage |
2048 | /// ::= /*empty*/ |
2049 | /// ::= 'private' |
2050 | /// ::= 'internal' |
2051 | /// ::= 'weak' |
2052 | /// ::= 'weak_odr' |
2053 | /// ::= 'linkonce' |
2054 | /// ::= 'linkonce_odr' |
2055 | /// ::= 'available_externally' |
2056 | /// ::= 'appending' |
2057 | /// ::= 'common' |
2058 | /// ::= 'extern_weak' |
2059 | /// ::= 'external' |
2060 | bool LLParser::parseOptionalLinkage(unsigned &Res, bool &HasLinkage, |
2061 | unsigned &Visibility, |
2062 | unsigned &DLLStorageClass, bool &DSOLocal) { |
2063 | Res = parseOptionalLinkageAux(Kind: Lex.getKind(), HasLinkage); |
2064 | if (HasLinkage) |
2065 | Lex.Lex(); |
2066 | parseOptionalDSOLocal(DSOLocal); |
2067 | parseOptionalVisibility(Res&: Visibility); |
2068 | parseOptionalDLLStorageClass(Res&: DLLStorageClass); |
2069 | |
2070 | if (DSOLocal && DLLStorageClass == GlobalValue::DLLImportStorageClass) { |
2071 | return error(L: Lex.getLoc(), Msg: "dso_location and DLL-StorageClass mismatch" ); |
2072 | } |
2073 | |
2074 | return false; |
2075 | } |
2076 | |
2077 | void LLParser::parseOptionalDSOLocal(bool &DSOLocal) { |
2078 | switch (Lex.getKind()) { |
2079 | default: |
2080 | DSOLocal = false; |
2081 | break; |
2082 | case lltok::kw_dso_local: |
2083 | DSOLocal = true; |
2084 | Lex.Lex(); |
2085 | break; |
2086 | case lltok::kw_dso_preemptable: |
2087 | DSOLocal = false; |
2088 | Lex.Lex(); |
2089 | break; |
2090 | } |
2091 | } |
2092 | |
2093 | /// parseOptionalVisibility |
2094 | /// ::= /*empty*/ |
2095 | /// ::= 'default' |
2096 | /// ::= 'hidden' |
2097 | /// ::= 'protected' |
2098 | /// |
2099 | void LLParser::parseOptionalVisibility(unsigned &Res) { |
2100 | switch (Lex.getKind()) { |
2101 | default: |
2102 | Res = GlobalValue::DefaultVisibility; |
2103 | return; |
2104 | case lltok::kw_default: |
2105 | Res = GlobalValue::DefaultVisibility; |
2106 | break; |
2107 | case lltok::kw_hidden: |
2108 | Res = GlobalValue::HiddenVisibility; |
2109 | break; |
2110 | case lltok::kw_protected: |
2111 | Res = GlobalValue::ProtectedVisibility; |
2112 | break; |
2113 | } |
2114 | Lex.Lex(); |
2115 | } |
2116 | |
2117 | bool LLParser::parseOptionalImportType(lltok::Kind Kind, |
2118 | GlobalValueSummary::ImportKind &Res) { |
2119 | switch (Kind) { |
2120 | default: |
2121 | return tokError(Msg: "unknown import kind. Expect definition or declaration." ); |
2122 | case lltok::kw_definition: |
2123 | Res = GlobalValueSummary::Definition; |
2124 | return false; |
2125 | case lltok::kw_declaration: |
2126 | Res = GlobalValueSummary::Declaration; |
2127 | return false; |
2128 | } |
2129 | } |
2130 | |
2131 | /// parseOptionalDLLStorageClass |
2132 | /// ::= /*empty*/ |
2133 | /// ::= 'dllimport' |
2134 | /// ::= 'dllexport' |
2135 | /// |
2136 | void LLParser::parseOptionalDLLStorageClass(unsigned &Res) { |
2137 | switch (Lex.getKind()) { |
2138 | default: |
2139 | Res = GlobalValue::DefaultStorageClass; |
2140 | return; |
2141 | case lltok::kw_dllimport: |
2142 | Res = GlobalValue::DLLImportStorageClass; |
2143 | break; |
2144 | case lltok::kw_dllexport: |
2145 | Res = GlobalValue::DLLExportStorageClass; |
2146 | break; |
2147 | } |
2148 | Lex.Lex(); |
2149 | } |
2150 | |
2151 | /// parseOptionalCallingConv |
2152 | /// ::= /*empty*/ |
2153 | /// ::= 'ccc' |
2154 | /// ::= 'fastcc' |
2155 | /// ::= 'intel_ocl_bicc' |
2156 | /// ::= 'coldcc' |
2157 | /// ::= 'cfguard_checkcc' |
2158 | /// ::= 'x86_stdcallcc' |
2159 | /// ::= 'x86_fastcallcc' |
2160 | /// ::= 'x86_thiscallcc' |
2161 | /// ::= 'x86_vectorcallcc' |
2162 | /// ::= 'arm_apcscc' |
2163 | /// ::= 'arm_aapcscc' |
2164 | /// ::= 'arm_aapcs_vfpcc' |
2165 | /// ::= 'aarch64_vector_pcs' |
2166 | /// ::= 'aarch64_sve_vector_pcs' |
2167 | /// ::= 'aarch64_sme_preservemost_from_x0' |
2168 | /// ::= 'aarch64_sme_preservemost_from_x1' |
2169 | /// ::= 'aarch64_sme_preservemost_from_x2' |
2170 | /// ::= 'msp430_intrcc' |
2171 | /// ::= 'avr_intrcc' |
2172 | /// ::= 'avr_signalcc' |
2173 | /// ::= 'ptx_kernel' |
2174 | /// ::= 'ptx_device' |
2175 | /// ::= 'spir_func' |
2176 | /// ::= 'spir_kernel' |
2177 | /// ::= 'x86_64_sysvcc' |
2178 | /// ::= 'win64cc' |
2179 | /// ::= 'anyregcc' |
2180 | /// ::= 'preserve_mostcc' |
2181 | /// ::= 'preserve_allcc' |
2182 | /// ::= 'preserve_nonecc' |
2183 | /// ::= 'ghccc' |
2184 | /// ::= 'swiftcc' |
2185 | /// ::= 'swifttailcc' |
2186 | /// ::= 'x86_intrcc' |
2187 | /// ::= 'hhvmcc' |
2188 | /// ::= 'hhvm_ccc' |
2189 | /// ::= 'cxx_fast_tlscc' |
2190 | /// ::= 'amdgpu_vs' |
2191 | /// ::= 'amdgpu_ls' |
2192 | /// ::= 'amdgpu_hs' |
2193 | /// ::= 'amdgpu_es' |
2194 | /// ::= 'amdgpu_gs' |
2195 | /// ::= 'amdgpu_ps' |
2196 | /// ::= 'amdgpu_cs' |
2197 | /// ::= 'amdgpu_cs_chain' |
2198 | /// ::= 'amdgpu_cs_chain_preserve' |
2199 | /// ::= 'amdgpu_kernel' |
2200 | /// ::= 'tailcc' |
2201 | /// ::= 'm68k_rtdcc' |
2202 | /// ::= 'graalcc' |
2203 | /// ::= 'riscv_vector_cc' |
2204 | /// ::= 'riscv_vls_cc' |
2205 | /// ::= 'cc' UINT |
2206 | /// |
2207 | bool LLParser::parseOptionalCallingConv(unsigned &CC) { |
2208 | switch (Lex.getKind()) { |
2209 | default: CC = CallingConv::C; return false; |
2210 | case lltok::kw_ccc: CC = CallingConv::C; break; |
2211 | case lltok::kw_fastcc: CC = CallingConv::Fast; break; |
2212 | case lltok::kw_coldcc: CC = CallingConv::Cold; break; |
2213 | case lltok::kw_cfguard_checkcc: CC = CallingConv::CFGuard_Check; break; |
2214 | case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break; |
2215 | case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break; |
2216 | case lltok::kw_x86_regcallcc: CC = CallingConv::X86_RegCall; break; |
2217 | case lltok::kw_x86_thiscallcc: CC = CallingConv::X86_ThisCall; break; |
2218 | case lltok::kw_x86_vectorcallcc:CC = CallingConv::X86_VectorCall; break; |
2219 | case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break; |
2220 | case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break; |
2221 | case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break; |
2222 | case lltok::kw_aarch64_vector_pcs:CC = CallingConv::AArch64_VectorCall; break; |
2223 | case lltok::kw_aarch64_sve_vector_pcs: |
2224 | CC = CallingConv::AArch64_SVE_VectorCall; |
2225 | break; |
2226 | case lltok::kw_aarch64_sme_preservemost_from_x0: |
2227 | CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0; |
2228 | break; |
2229 | case lltok::kw_aarch64_sme_preservemost_from_x1: |
2230 | CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1; |
2231 | break; |
2232 | case lltok::kw_aarch64_sme_preservemost_from_x2: |
2233 | CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2; |
2234 | break; |
2235 | case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break; |
2236 | case lltok::kw_avr_intrcc: CC = CallingConv::AVR_INTR; break; |
2237 | case lltok::kw_avr_signalcc: CC = CallingConv::AVR_SIGNAL; break; |
2238 | case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break; |
2239 | case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break; |
2240 | case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break; |
2241 | case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break; |
2242 | case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break; |
2243 | case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break; |
2244 | case lltok::kw_win64cc: CC = CallingConv::Win64; break; |
2245 | case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break; |
2246 | case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break; |
2247 | case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break; |
2248 | case lltok::kw_preserve_nonecc:CC = CallingConv::PreserveNone; break; |
2249 | case lltok::kw_ghccc: CC = CallingConv::GHC; break; |
2250 | case lltok::kw_swiftcc: CC = CallingConv::Swift; break; |
2251 | case lltok::kw_swifttailcc: CC = CallingConv::SwiftTail; break; |
2252 | case lltok::kw_x86_intrcc: CC = CallingConv::X86_INTR; break; |
2253 | case lltok::kw_hhvmcc: |
2254 | CC = CallingConv::DUMMY_HHVM; |
2255 | break; |
2256 | case lltok::kw_hhvm_ccc: |
2257 | CC = CallingConv::DUMMY_HHVM_C; |
2258 | break; |
2259 | case lltok::kw_cxx_fast_tlscc: CC = CallingConv::CXX_FAST_TLS; break; |
2260 | case lltok::kw_amdgpu_vs: CC = CallingConv::AMDGPU_VS; break; |
2261 | case lltok::kw_amdgpu_gfx: CC = CallingConv::AMDGPU_Gfx; break; |
2262 | case lltok::kw_amdgpu_ls: CC = CallingConv::AMDGPU_LS; break; |
2263 | case lltok::kw_amdgpu_hs: CC = CallingConv::AMDGPU_HS; break; |
2264 | case lltok::kw_amdgpu_es: CC = CallingConv::AMDGPU_ES; break; |
2265 | case lltok::kw_amdgpu_gs: CC = CallingConv::AMDGPU_GS; break; |
2266 | case lltok::kw_amdgpu_ps: CC = CallingConv::AMDGPU_PS; break; |
2267 | case lltok::kw_amdgpu_cs: CC = CallingConv::AMDGPU_CS; break; |
2268 | case lltok::kw_amdgpu_cs_chain: |
2269 | CC = CallingConv::AMDGPU_CS_Chain; |
2270 | break; |
2271 | case lltok::kw_amdgpu_cs_chain_preserve: |
2272 | CC = CallingConv::AMDGPU_CS_ChainPreserve; |
2273 | break; |
2274 | case lltok::kw_amdgpu_kernel: CC = CallingConv::AMDGPU_KERNEL; break; |
2275 | case lltok::kw_tailcc: CC = CallingConv::Tail; break; |
2276 | case lltok::kw_m68k_rtdcc: CC = CallingConv::M68k_RTD; break; |
2277 | case lltok::kw_graalcc: CC = CallingConv::GRAAL; break; |
2278 | case lltok::kw_riscv_vector_cc: |
2279 | CC = CallingConv::RISCV_VectorCall; |
2280 | break; |
2281 | case lltok::kw_riscv_vls_cc: |
2282 | // Default ABI_VLEN |
2283 | CC = CallingConv::RISCV_VLSCall_128; |
2284 | Lex.Lex(); |
2285 | if (!EatIfPresent(T: lltok::lparen)) |
2286 | break; |
2287 | uint32_t ABIVlen; |
2288 | if (parseUInt32(Val&: ABIVlen) || !EatIfPresent(T: lltok::rparen)) |
2289 | return true; |
2290 | switch (ABIVlen) { |
2291 | default: |
2292 | return tokError(Msg: "unknown RISC-V ABI VLEN" ); |
2293 | #define CC_VLS_CASE(ABIVlen) \ |
2294 | case ABIVlen: \ |
2295 | CC = CallingConv::RISCV_VLSCall_##ABIVlen; \ |
2296 | break; |
2297 | CC_VLS_CASE(32) |
2298 | CC_VLS_CASE(64) |
2299 | CC_VLS_CASE(128) |
2300 | CC_VLS_CASE(256) |
2301 | CC_VLS_CASE(512) |
2302 | CC_VLS_CASE(1024) |
2303 | CC_VLS_CASE(2048) |
2304 | CC_VLS_CASE(4096) |
2305 | CC_VLS_CASE(8192) |
2306 | CC_VLS_CASE(16384) |
2307 | CC_VLS_CASE(32768) |
2308 | CC_VLS_CASE(65536) |
2309 | #undef CC_VLS_CASE |
2310 | } |
2311 | return false; |
2312 | case lltok::kw_cc: { |
2313 | Lex.Lex(); |
2314 | return parseUInt32(Val&: CC); |
2315 | } |
2316 | } |
2317 | |
2318 | Lex.Lex(); |
2319 | return false; |
2320 | } |
2321 | |
2322 | /// parseMetadataAttachment |
2323 | /// ::= !dbg !42 |
2324 | bool LLParser::parseMetadataAttachment(unsigned &Kind, MDNode *&MD) { |
2325 | assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata attachment" ); |
2326 | |
2327 | std::string Name = Lex.getStrVal(); |
2328 | Kind = M->getMDKindID(Name); |
2329 | Lex.Lex(); |
2330 | |
2331 | return parseMDNode(N&: MD); |
2332 | } |
2333 | |
2334 | /// parseInstructionMetadata |
2335 | /// ::= !dbg !42 (',' !dbg !57)* |
2336 | bool LLParser::parseInstructionMetadata(Instruction &Inst) { |
2337 | do { |
2338 | if (Lex.getKind() != lltok::MetadataVar) |
2339 | return tokError(Msg: "expected metadata after comma" ); |
2340 | |
2341 | unsigned MDK; |
2342 | MDNode *N; |
2343 | if (parseMetadataAttachment(Kind&: MDK, MD&: N)) |
2344 | return true; |
2345 | |
2346 | if (MDK == LLVMContext::MD_DIAssignID) |
2347 | TempDIAssignIDAttachments[N].push_back(Elt: &Inst); |
2348 | else |
2349 | Inst.setMetadata(KindID: MDK, Node: N); |
2350 | |
2351 | if (MDK == LLVMContext::MD_tbaa) |
2352 | InstsWithTBAATag.push_back(Elt: &Inst); |
2353 | |
2354 | // If this is the end of the list, we're done. |
2355 | } while (EatIfPresent(T: lltok::comma)); |
2356 | return false; |
2357 | } |
2358 | |
2359 | /// parseGlobalObjectMetadataAttachment |
2360 | /// ::= !dbg !57 |
2361 | bool LLParser::parseGlobalObjectMetadataAttachment(GlobalObject &GO) { |
2362 | unsigned MDK; |
2363 | MDNode *N; |
2364 | if (parseMetadataAttachment(Kind&: MDK, MD&: N)) |
2365 | return true; |
2366 | |
2367 | GO.addMetadata(KindID: MDK, MD&: *N); |
2368 | return false; |
2369 | } |
2370 | |
2371 | /// parseOptionalFunctionMetadata |
2372 | /// ::= (!dbg !57)* |
2373 | bool LLParser::parseOptionalFunctionMetadata(Function &F) { |
2374 | while (Lex.getKind() == lltok::MetadataVar) |
2375 | if (parseGlobalObjectMetadataAttachment(GO&: F)) |
2376 | return true; |
2377 | return false; |
2378 | } |
2379 | |
2380 | /// parseOptionalAlignment |
2381 | /// ::= /* empty */ |
2382 | /// ::= 'align' 4 |
2383 | bool LLParser::parseOptionalAlignment(MaybeAlign &Alignment, bool AllowParens) { |
2384 | Alignment = std::nullopt; |
2385 | if (!EatIfPresent(T: lltok::kw_align)) |
2386 | return false; |
2387 | LocTy AlignLoc = Lex.getLoc(); |
2388 | uint64_t Value = 0; |
2389 | |
2390 | LocTy ParenLoc = Lex.getLoc(); |
2391 | bool HaveParens = false; |
2392 | if (AllowParens) { |
2393 | if (EatIfPresent(T: lltok::lparen)) |
2394 | HaveParens = true; |
2395 | } |
2396 | |
2397 | if (parseUInt64(Val&: Value)) |
2398 | return true; |
2399 | |
2400 | if (HaveParens && !EatIfPresent(T: lltok::rparen)) |
2401 | return error(L: ParenLoc, Msg: "expected ')'" ); |
2402 | |
2403 | if (!isPowerOf2_64(Value)) |
2404 | return error(L: AlignLoc, Msg: "alignment is not a power of two" ); |
2405 | if (Value > Value::MaximumAlignment) |
2406 | return error(L: AlignLoc, Msg: "huge alignments are not supported yet" ); |
2407 | Alignment = Align(Value); |
2408 | return false; |
2409 | } |
2410 | |
2411 | /// parseOptionalCodeModel |
2412 | /// ::= /* empty */ |
2413 | /// ::= 'code_model' "large" |
2414 | bool LLParser::parseOptionalCodeModel(CodeModel::Model &model) { |
2415 | Lex.Lex(); |
2416 | auto StrVal = Lex.getStrVal(); |
2417 | auto ErrMsg = "expected global code model string" ; |
2418 | if (StrVal == "tiny" ) |
2419 | model = CodeModel::Tiny; |
2420 | else if (StrVal == "small" ) |
2421 | model = CodeModel::Small; |
2422 | else if (StrVal == "kernel" ) |
2423 | model = CodeModel::Kernel; |
2424 | else if (StrVal == "medium" ) |
2425 | model = CodeModel::Medium; |
2426 | else if (StrVal == "large" ) |
2427 | model = CodeModel::Large; |
2428 | else |
2429 | return tokError(Msg: ErrMsg); |
2430 | if (parseToken(T: lltok::StringConstant, ErrMsg)) |
2431 | return true; |
2432 | return false; |
2433 | } |
2434 | |
2435 | /// parseOptionalDerefAttrBytes |
2436 | /// ::= /* empty */ |
2437 | /// ::= AttrKind '(' 4 ')' |
2438 | /// |
2439 | /// where AttrKind is either 'dereferenceable' or 'dereferenceable_or_null'. |
2440 | bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind, |
2441 | uint64_t &Bytes) { |
2442 | assert((AttrKind == lltok::kw_dereferenceable || |
2443 | AttrKind == lltok::kw_dereferenceable_or_null) && |
2444 | "contract!" ); |
2445 | |
2446 | Bytes = 0; |
2447 | if (!EatIfPresent(T: AttrKind)) |
2448 | return false; |
2449 | LocTy ParenLoc = Lex.getLoc(); |
2450 | if (!EatIfPresent(T: lltok::lparen)) |
2451 | return error(L: ParenLoc, Msg: "expected '('" ); |
2452 | LocTy DerefLoc = Lex.getLoc(); |
2453 | if (parseUInt64(Val&: Bytes)) |
2454 | return true; |
2455 | ParenLoc = Lex.getLoc(); |
2456 | if (!EatIfPresent(T: lltok::rparen)) |
2457 | return error(L: ParenLoc, Msg: "expected ')'" ); |
2458 | if (!Bytes) |
2459 | return error(L: DerefLoc, Msg: "dereferenceable bytes must be non-zero" ); |
2460 | return false; |
2461 | } |
2462 | |
2463 | bool LLParser::parseOptionalUWTableKind(UWTableKind &Kind) { |
2464 | Lex.Lex(); |
2465 | Kind = UWTableKind::Default; |
2466 | if (!EatIfPresent(T: lltok::lparen)) |
2467 | return false; |
2468 | LocTy KindLoc = Lex.getLoc(); |
2469 | if (Lex.getKind() == lltok::kw_sync) |
2470 | Kind = UWTableKind::Sync; |
2471 | else if (Lex.getKind() == lltok::kw_async) |
2472 | Kind = UWTableKind::Async; |
2473 | else |
2474 | return error(L: KindLoc, Msg: "expected unwind table kind" ); |
2475 | Lex.Lex(); |
2476 | return parseToken(T: lltok::rparen, ErrMsg: "expected ')'" ); |
2477 | } |
2478 | |
2479 | bool LLParser::parseAllocKind(AllocFnKind &Kind) { |
2480 | Lex.Lex(); |
2481 | LocTy ParenLoc = Lex.getLoc(); |
2482 | if (!EatIfPresent(T: lltok::lparen)) |
2483 | return error(L: ParenLoc, Msg: "expected '('" ); |
2484 | LocTy KindLoc = Lex.getLoc(); |
2485 | std::string Arg; |
2486 | if (parseStringConstant(Result&: Arg)) |
2487 | return error(L: KindLoc, Msg: "expected allockind value" ); |
2488 | for (StringRef A : llvm::split(Str: Arg, Separator: "," )) { |
2489 | if (A == "alloc" ) { |
2490 | Kind |= AllocFnKind::Alloc; |
2491 | } else if (A == "realloc" ) { |
2492 | Kind |= AllocFnKind::Realloc; |
2493 | } else if (A == "free" ) { |
2494 | Kind |= AllocFnKind::Free; |
2495 | } else if (A == "uninitialized" ) { |
2496 | Kind |= AllocFnKind::Uninitialized; |
2497 | } else if (A == "zeroed" ) { |
2498 | Kind |= AllocFnKind::Zeroed; |
2499 | } else if (A == "aligned" ) { |
2500 | Kind |= AllocFnKind::Aligned; |
2501 | } else { |
2502 | return error(L: KindLoc, Msg: Twine("unknown allockind " ) + A); |
2503 | } |
2504 | } |
2505 | ParenLoc = Lex.getLoc(); |
2506 | if (!EatIfPresent(T: lltok::rparen)) |
2507 | return error(L: ParenLoc, Msg: "expected ')'" ); |
2508 | if (Kind == AllocFnKind::Unknown) |
2509 | return error(L: KindLoc, Msg: "expected allockind value" ); |
2510 | return false; |
2511 | } |
2512 | |
2513 | static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) { |
2514 | switch (Tok) { |
2515 | case lltok::kw_argmem: |
2516 | return IRMemLocation::ArgMem; |
2517 | case lltok::kw_inaccessiblemem: |
2518 | return IRMemLocation::InaccessibleMem; |
2519 | case lltok::kw_errnomem: |
2520 | return IRMemLocation::ErrnoMem; |
2521 | default: |
2522 | return std::nullopt; |
2523 | } |
2524 | } |
2525 | |
2526 | static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) { |
2527 | switch (Tok) { |
2528 | case lltok::kw_none: |
2529 | return ModRefInfo::NoModRef; |
2530 | case lltok::kw_read: |
2531 | return ModRefInfo::Ref; |
2532 | case lltok::kw_write: |
2533 | return ModRefInfo::Mod; |
2534 | case lltok::kw_readwrite: |
2535 | return ModRefInfo::ModRef; |
2536 | default: |
2537 | return std::nullopt; |
2538 | } |
2539 | } |
2540 | |
2541 | std::optional<MemoryEffects> LLParser::parseMemoryAttr() { |
2542 | MemoryEffects ME = MemoryEffects::none(); |
2543 | |
2544 | // We use syntax like memory(argmem: read), so the colon should not be |
2545 | // interpreted as a label terminator. |
2546 | Lex.setIgnoreColonInIdentifiers(true); |
2547 | auto _ = make_scope_exit(F: [&] { Lex.setIgnoreColonInIdentifiers(false); }); |
2548 | |
2549 | Lex.Lex(); |
2550 | if (!EatIfPresent(T: lltok::lparen)) { |
2551 | tokError(Msg: "expected '('" ); |
2552 | return std::nullopt; |
2553 | } |
2554 | |
2555 | bool SeenLoc = false; |
2556 | do { |
2557 | std::optional<IRMemLocation> Loc = keywordToLoc(Tok: Lex.getKind()); |
2558 | if (Loc) { |
2559 | Lex.Lex(); |
2560 | if (!EatIfPresent(T: lltok::colon)) { |
2561 | tokError(Msg: "expected ':' after location" ); |
2562 | return std::nullopt; |
2563 | } |
2564 | } |
2565 | |
2566 | std::optional<ModRefInfo> MR = keywordToModRef(Tok: Lex.getKind()); |
2567 | if (!MR) { |
2568 | if (!Loc) |
2569 | tokError(Msg: "expected memory location (argmem, inaccessiblemem, errnomem) " |
2570 | "or access kind (none, read, write, readwrite)" ); |
2571 | else |
2572 | tokError(Msg: "expected access kind (none, read, write, readwrite)" ); |
2573 | return std::nullopt; |
2574 | } |
2575 | |
2576 | Lex.Lex(); |
2577 | if (Loc) { |
2578 | SeenLoc = true; |
2579 | ME = ME.getWithModRef(Loc: *Loc, MR: *MR); |
2580 | } else { |
2581 | if (SeenLoc) { |
2582 | tokError(Msg: "default access kind must be specified first" ); |
2583 | return std::nullopt; |
2584 | } |
2585 | ME = MemoryEffects(*MR); |
2586 | } |
2587 | |
2588 | if (EatIfPresent(T: lltok::rparen)) |
2589 | return ME; |
2590 | } while (EatIfPresent(T: lltok::comma)); |
2591 | |
2592 | tokError(Msg: "unterminated memory attribute" ); |
2593 | return std::nullopt; |
2594 | } |
2595 | |
2596 | static unsigned keywordToFPClassTest(lltok::Kind Tok) { |
2597 | switch (Tok) { |
2598 | case lltok::kw_all: |
2599 | return fcAllFlags; |
2600 | case lltok::kw_nan: |
2601 | return fcNan; |
2602 | case lltok::kw_snan: |
2603 | return fcSNan; |
2604 | case lltok::kw_qnan: |
2605 | return fcQNan; |
2606 | case lltok::kw_inf: |
2607 | return fcInf; |
2608 | case lltok::kw_ninf: |
2609 | return fcNegInf; |
2610 | case lltok::kw_pinf: |
2611 | return fcPosInf; |
2612 | case lltok::kw_norm: |
2613 | return fcNormal; |
2614 | case lltok::kw_nnorm: |
2615 | return fcNegNormal; |
2616 | case lltok::kw_pnorm: |
2617 | return fcPosNormal; |
2618 | case lltok::kw_sub: |
2619 | return fcSubnormal; |
2620 | case lltok::kw_nsub: |
2621 | return fcNegSubnormal; |
2622 | case lltok::kw_psub: |
2623 | return fcPosSubnormal; |
2624 | case lltok::kw_zero: |
2625 | return fcZero; |
2626 | case lltok::kw_nzero: |
2627 | return fcNegZero; |
2628 | case lltok::kw_pzero: |
2629 | return fcPosZero; |
2630 | default: |
2631 | return 0; |
2632 | } |
2633 | } |
2634 | |
2635 | unsigned LLParser::parseNoFPClassAttr() { |
2636 | unsigned Mask = fcNone; |
2637 | |
2638 | Lex.Lex(); |
2639 | if (!EatIfPresent(T: lltok::lparen)) { |
2640 | tokError(Msg: "expected '('" ); |
2641 | return 0; |
2642 | } |
2643 | |
2644 | do { |
2645 | uint64_t Value = 0; |
2646 | unsigned TestMask = keywordToFPClassTest(Tok: Lex.getKind()); |
2647 | if (TestMask != 0) { |
2648 | Mask |= TestMask; |
2649 | // TODO: Disallow overlapping masks to avoid copy paste errors |
2650 | } else if (Mask == 0 && Lex.getKind() == lltok::APSInt && |
2651 | !parseUInt64(Val&: Value)) { |
2652 | if (Value == 0 || (Value & ~static_cast<unsigned>(fcAllFlags)) != 0) { |
2653 | error(L: Lex.getLoc(), Msg: "invalid mask value for 'nofpclass'" ); |
2654 | return 0; |
2655 | } |
2656 | |
2657 | if (!EatIfPresent(T: lltok::rparen)) { |
2658 | error(L: Lex.getLoc(), Msg: "expected ')'" ); |
2659 | return 0; |
2660 | } |
2661 | |
2662 | return Value; |
2663 | } else { |
2664 | error(L: Lex.getLoc(), Msg: "expected nofpclass test mask" ); |
2665 | return 0; |
2666 | } |
2667 | |
2668 | Lex.Lex(); |
2669 | if (EatIfPresent(T: lltok::rparen)) |
2670 | return Mask; |
2671 | } while (1); |
2672 | |
2673 | llvm_unreachable("unterminated nofpclass attribute" ); |
2674 | } |
2675 | |
2676 | /// parseOptionalCommaAlign |
2677 | /// ::= |
2678 | /// ::= ',' align 4 |
2679 | /// |
2680 | /// This returns with AteExtraComma set to true if it ate an excess comma at the |
2681 | /// end. |
2682 | bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment, |
2683 | bool &) { |
2684 | AteExtraComma = false; |
2685 | while (EatIfPresent(T: lltok::comma)) { |
2686 | // Metadata at the end is an early exit. |
2687 | if (Lex.getKind() == lltok::MetadataVar) { |
2688 | AteExtraComma = true; |
2689 | return false; |
2690 | } |
2691 | |
2692 | if (Lex.getKind() != lltok::kw_align) |
2693 | return error(L: Lex.getLoc(), Msg: "expected metadata or 'align'" ); |
2694 | |
2695 | if (parseOptionalAlignment(Alignment)) |
2696 | return true; |
2697 | } |
2698 | |
2699 | return false; |
2700 | } |
2701 | |
2702 | /// parseOptionalCommaAddrSpace |
2703 | /// ::= |
2704 | /// ::= ',' addrspace(1) |
2705 | /// |
2706 | /// This returns with AteExtraComma set to true if it ate an excess comma at the |
2707 | /// end. |
2708 | bool LLParser::parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc, |
2709 | bool &) { |
2710 | AteExtraComma = false; |
2711 | while (EatIfPresent(T: lltok::comma)) { |
2712 | // Metadata at the end is an early exit. |
2713 | if (Lex.getKind() == lltok::MetadataVar) { |
2714 | AteExtraComma = true; |
2715 | return false; |
2716 | } |
2717 | |
2718 | Loc = Lex.getLoc(); |
2719 | if (Lex.getKind() != lltok::kw_addrspace) |
2720 | return error(L: Lex.getLoc(), Msg: "expected metadata or 'addrspace'" ); |
2721 | |
2722 | if (parseOptionalAddrSpace(AddrSpace)) |
2723 | return true; |
2724 | } |
2725 | |
2726 | return false; |
2727 | } |
2728 | |
2729 | bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg, |
2730 | std::optional<unsigned> &HowManyArg) { |
2731 | Lex.Lex(); |
2732 | |
2733 | auto StartParen = Lex.getLoc(); |
2734 | if (!EatIfPresent(T: lltok::lparen)) |
2735 | return error(L: StartParen, Msg: "expected '('" ); |
2736 | |
2737 | if (parseUInt32(Val&: BaseSizeArg)) |
2738 | return true; |
2739 | |
2740 | if (EatIfPresent(T: lltok::comma)) { |
2741 | auto HowManyAt = Lex.getLoc(); |
2742 | unsigned HowMany; |
2743 | if (parseUInt32(Val&: HowMany)) |
2744 | return true; |
2745 | if (HowMany == BaseSizeArg) |
2746 | return error(L: HowManyAt, |
2747 | Msg: "'allocsize' indices can't refer to the same parameter" ); |
2748 | HowManyArg = HowMany; |
2749 | } else |
2750 | HowManyArg = std::nullopt; |
2751 | |
2752 | auto EndParen = Lex.getLoc(); |
2753 | if (!EatIfPresent(T: lltok::rparen)) |
2754 | return error(L: EndParen, Msg: "expected ')'" ); |
2755 | return false; |
2756 | } |
2757 | |
2758 | bool LLParser::parseVScaleRangeArguments(unsigned &MinValue, |
2759 | unsigned &MaxValue) { |
2760 | Lex.Lex(); |
2761 | |
2762 | auto StartParen = Lex.getLoc(); |
2763 | if (!EatIfPresent(T: lltok::lparen)) |
2764 | return error(L: StartParen, Msg: "expected '('" ); |
2765 | |
2766 | if (parseUInt32(Val&: MinValue)) |
2767 | return true; |
2768 | |
2769 | if (EatIfPresent(T: lltok::comma)) { |
2770 | if (parseUInt32(Val&: MaxValue)) |
2771 | return true; |
2772 | } else |
2773 | MaxValue = MinValue; |
2774 | |
2775 | auto EndParen = Lex.getLoc(); |
2776 | if (!EatIfPresent(T: lltok::rparen)) |
2777 | return error(L: EndParen, Msg: "expected ')'" ); |
2778 | return false; |
2779 | } |
2780 | |
2781 | /// parseScopeAndOrdering |
2782 | /// if isAtomic: ::= SyncScope? AtomicOrdering |
2783 | /// else: ::= |
2784 | /// |
2785 | /// This sets Scope and Ordering to the parsed values. |
2786 | bool LLParser::parseScopeAndOrdering(bool IsAtomic, SyncScope::ID &SSID, |
2787 | AtomicOrdering &Ordering) { |
2788 | if (!IsAtomic) |
2789 | return false; |
2790 | |
2791 | return parseScope(SSID) || parseOrdering(Ordering); |
2792 | } |
2793 | |
2794 | /// parseScope |
2795 | /// ::= syncscope("singlethread" | "<target scope>")? |
2796 | /// |
2797 | /// This sets synchronization scope ID to the ID of the parsed value. |
2798 | bool LLParser::parseScope(SyncScope::ID &SSID) { |
2799 | SSID = SyncScope::System; |
2800 | if (EatIfPresent(T: lltok::kw_syncscope)) { |
2801 | auto StartParenAt = Lex.getLoc(); |
2802 | if (!EatIfPresent(T: lltok::lparen)) |
2803 | return error(L: StartParenAt, Msg: "Expected '(' in syncscope" ); |
2804 | |
2805 | std::string SSN; |
2806 | auto SSNAt = Lex.getLoc(); |
2807 | if (parseStringConstant(Result&: SSN)) |
2808 | return error(L: SSNAt, Msg: "Expected synchronization scope name" ); |
2809 | |
2810 | auto EndParenAt = Lex.getLoc(); |
2811 | if (!EatIfPresent(T: lltok::rparen)) |
2812 | return error(L: EndParenAt, Msg: "Expected ')' in syncscope" ); |
2813 | |
2814 | SSID = Context.getOrInsertSyncScopeID(SSN); |
2815 | } |
2816 | |
2817 | return false; |
2818 | } |
2819 | |
2820 | /// parseOrdering |
2821 | /// ::= AtomicOrdering |
2822 | /// |
2823 | /// This sets Ordering to the parsed value. |
2824 | bool LLParser::parseOrdering(AtomicOrdering &Ordering) { |
2825 | switch (Lex.getKind()) { |
2826 | default: |
2827 | return tokError(Msg: "Expected ordering on atomic instruction" ); |
2828 | case lltok::kw_unordered: Ordering = AtomicOrdering::Unordered; break; |
2829 | case lltok::kw_monotonic: Ordering = AtomicOrdering::Monotonic; break; |
2830 | // Not specified yet: |
2831 | // case lltok::kw_consume: Ordering = AtomicOrdering::Consume; break; |
2832 | case lltok::kw_acquire: Ordering = AtomicOrdering::Acquire; break; |
2833 | case lltok::kw_release: Ordering = AtomicOrdering::Release; break; |
2834 | case lltok::kw_acq_rel: Ordering = AtomicOrdering::AcquireRelease; break; |
2835 | case lltok::kw_seq_cst: |
2836 | Ordering = AtomicOrdering::SequentiallyConsistent; |
2837 | break; |
2838 | } |
2839 | Lex.Lex(); |
2840 | return false; |
2841 | } |
2842 | |
2843 | /// parseOptionalStackAlignment |
2844 | /// ::= /* empty */ |
2845 | /// ::= 'alignstack' '(' 4 ')' |
2846 | bool LLParser::parseOptionalStackAlignment(unsigned &Alignment) { |
2847 | Alignment = 0; |
2848 | if (!EatIfPresent(T: lltok::kw_alignstack)) |
2849 | return false; |
2850 | LocTy ParenLoc = Lex.getLoc(); |
2851 | if (!EatIfPresent(T: lltok::lparen)) |
2852 | return error(L: ParenLoc, Msg: "expected '('" ); |
2853 | LocTy AlignLoc = Lex.getLoc(); |
2854 | if (parseUInt32(Val&: Alignment)) |
2855 | return true; |
2856 | ParenLoc = Lex.getLoc(); |
2857 | if (!EatIfPresent(T: lltok::rparen)) |
2858 | return error(L: ParenLoc, Msg: "expected ')'" ); |
2859 | if (!isPowerOf2_32(Value: Alignment)) |
2860 | return error(L: AlignLoc, Msg: "stack alignment is not a power of two" ); |
2861 | return false; |
2862 | } |
2863 | |
2864 | /// parseIndexList - This parses the index list for an insert/extractvalue |
2865 | /// instruction. This sets AteExtraComma in the case where we eat an extra |
2866 | /// comma at the end of the line and find that it is followed by metadata. |
2867 | /// Clients that don't allow metadata can call the version of this function that |
2868 | /// only takes one argument. |
2869 | /// |
2870 | /// parseIndexList |
2871 | /// ::= (',' uint32)+ |
2872 | /// |
2873 | bool LLParser::parseIndexList(SmallVectorImpl<unsigned> &Indices, |
2874 | bool &) { |
2875 | AteExtraComma = false; |
2876 | |
2877 | if (Lex.getKind() != lltok::comma) |
2878 | return tokError(Msg: "expected ',' as start of index list" ); |
2879 | |
2880 | while (EatIfPresent(T: lltok::comma)) { |
2881 | if (Lex.getKind() == lltok::MetadataVar) { |
2882 | if (Indices.empty()) |
2883 | return tokError(Msg: "expected index" ); |
2884 | AteExtraComma = true; |
2885 | return false; |
2886 | } |
2887 | unsigned Idx = 0; |
2888 | if (parseUInt32(Val&: Idx)) |
2889 | return true; |
2890 | Indices.push_back(Elt: Idx); |
2891 | } |
2892 | |
2893 | return false; |
2894 | } |
2895 | |
2896 | //===----------------------------------------------------------------------===// |
2897 | // Type Parsing. |
2898 | //===----------------------------------------------------------------------===// |
2899 | |
2900 | /// parseType - parse a type. |
2901 | bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) { |
2902 | SMLoc TypeLoc = Lex.getLoc(); |
2903 | switch (Lex.getKind()) { |
2904 | default: |
2905 | return tokError(Msg); |
2906 | case lltok::Type: |
2907 | // Type ::= 'float' | 'void' (etc) |
2908 | Result = Lex.getTyVal(); |
2909 | Lex.Lex(); |
2910 | |
2911 | // Handle "ptr" opaque pointer type. |
2912 | // |
2913 | // Type ::= ptr ('addrspace' '(' uint32 ')')? |
2914 | if (Result->isPointerTy()) { |
2915 | unsigned AddrSpace; |
2916 | if (parseOptionalAddrSpace(AddrSpace)) |
2917 | return true; |
2918 | Result = PointerType::get(C&: getContext(), AddressSpace: AddrSpace); |
2919 | |
2920 | // Give a nice error for 'ptr*'. |
2921 | if (Lex.getKind() == lltok::star) |
2922 | return tokError(Msg: "ptr* is invalid - use ptr instead" ); |
2923 | |
2924 | // Fall through to parsing the type suffixes only if this 'ptr' is a |
2925 | // function return. Otherwise, return success, implicitly rejecting other |
2926 | // suffixes. |
2927 | if (Lex.getKind() != lltok::lparen) |
2928 | return false; |
2929 | } |
2930 | break; |
2931 | case lltok::kw_target: { |
2932 | // Type ::= TargetExtType |
2933 | if (parseTargetExtType(Result)) |
2934 | return true; |
2935 | break; |
2936 | } |
2937 | case lltok::lbrace: |
2938 | // Type ::= StructType |
2939 | if (parseAnonStructType(Result, Packed: false)) |
2940 | return true; |
2941 | break; |
2942 | case lltok::lsquare: |
2943 | // Type ::= '[' ... ']' |
2944 | Lex.Lex(); // eat the lsquare. |
2945 | if (parseArrayVectorType(Result, IsVector: false)) |
2946 | return true; |
2947 | break; |
2948 | case lltok::less: // Either vector or packed struct. |
2949 | // Type ::= '<' ... '>' |
2950 | Lex.Lex(); |
2951 | if (Lex.getKind() == lltok::lbrace) { |
2952 | if (parseAnonStructType(Result, Packed: true) || |
2953 | parseToken(T: lltok::greater, ErrMsg: "expected '>' at end of packed struct" )) |
2954 | return true; |
2955 | } else if (parseArrayVectorType(Result, IsVector: true)) |
2956 | return true; |
2957 | break; |
2958 | case lltok::LocalVar: { |
2959 | // Type ::= %foo |
2960 | std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()]; |
2961 | |
2962 | // If the type hasn't been defined yet, create a forward definition and |
2963 | // remember where that forward def'n was seen (in case it never is defined). |
2964 | if (!Entry.first) { |
2965 | Entry.first = StructType::create(Context, Name: Lex.getStrVal()); |
2966 | Entry.second = Lex.getLoc(); |
2967 | } |
2968 | Result = Entry.first; |
2969 | Lex.Lex(); |
2970 | break; |
2971 | } |
2972 | |
2973 | case lltok::LocalVarID: { |
2974 | // Type ::= %4 |
2975 | std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()]; |
2976 | |
2977 | // If the type hasn't been defined yet, create a forward definition and |
2978 | // remember where that forward def'n was seen (in case it never is defined). |
2979 | if (!Entry.first) { |
2980 | Entry.first = StructType::create(Context); |
2981 | Entry.second = Lex.getLoc(); |
2982 | } |
2983 | Result = Entry.first; |
2984 | Lex.Lex(); |
2985 | break; |
2986 | } |
2987 | } |
2988 | |
2989 | // parse the type suffixes. |
2990 | while (true) { |
2991 | switch (Lex.getKind()) { |
2992 | // End of type. |
2993 | default: |
2994 | if (!AllowVoid && Result->isVoidTy()) |
2995 | return error(L: TypeLoc, Msg: "void type only allowed for function results" ); |
2996 | return false; |
2997 | |
2998 | // Type ::= Type '*' |
2999 | case lltok::star: |
3000 | if (Result->isLabelTy()) |
3001 | return tokError(Msg: "basic block pointers are invalid" ); |
3002 | if (Result->isVoidTy()) |
3003 | return tokError(Msg: "pointers to void are invalid - use i8* instead" ); |
3004 | if (!PointerType::isValidElementType(ElemTy: Result)) |
3005 | return tokError(Msg: "pointer to this type is invalid" ); |
3006 | Result = PointerType::getUnqual(C&: Context); |
3007 | Lex.Lex(); |
3008 | break; |
3009 | |
3010 | // Type ::= Type 'addrspace' '(' uint32 ')' '*' |
3011 | case lltok::kw_addrspace: { |
3012 | if (Result->isLabelTy()) |
3013 | return tokError(Msg: "basic block pointers are invalid" ); |
3014 | if (Result->isVoidTy()) |
3015 | return tokError(Msg: "pointers to void are invalid; use i8* instead" ); |
3016 | if (!PointerType::isValidElementType(ElemTy: Result)) |
3017 | return tokError(Msg: "pointer to this type is invalid" ); |
3018 | unsigned AddrSpace; |
3019 | if (parseOptionalAddrSpace(AddrSpace) || |
3020 | parseToken(T: lltok::star, ErrMsg: "expected '*' in address space" )) |
3021 | return true; |
3022 | |
3023 | Result = PointerType::get(C&: Context, AddressSpace: AddrSpace); |
3024 | break; |
3025 | } |
3026 | |
3027 | /// Types '(' ArgTypeListI ')' OptFuncAttrs |
3028 | case lltok::lparen: |
3029 | if (parseFunctionType(Result)) |
3030 | return true; |
3031 | break; |
3032 | } |
3033 | } |
3034 | } |
3035 | |
3036 | /// parseParameterList |
3037 | /// ::= '(' ')' |
3038 | /// ::= '(' Arg (',' Arg)* ')' |
3039 | /// Arg |
3040 | /// ::= Type OptionalAttributes Value OptionalAttributes |
3041 | bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList, |
3042 | PerFunctionState &PFS, bool IsMustTailCall, |
3043 | bool InVarArgsFunc) { |
3044 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in call" )) |
3045 | return true; |
3046 | |
3047 | while (Lex.getKind() != lltok::rparen) { |
3048 | // If this isn't the first argument, we need a comma. |
3049 | if (!ArgList.empty() && |
3050 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in argument list" )) |
3051 | return true; |
3052 | |
3053 | // parse an ellipsis if this is a musttail call in a variadic function. |
3054 | if (Lex.getKind() == lltok::dotdotdot) { |
3055 | const char *Msg = "unexpected ellipsis in argument list for " ; |
3056 | if (!IsMustTailCall) |
3057 | return tokError(Msg: Twine(Msg) + "non-musttail call" ); |
3058 | if (!InVarArgsFunc) |
3059 | return tokError(Msg: Twine(Msg) + "musttail call in non-varargs function" ); |
3060 | Lex.Lex(); // Lex the '...', it is purely for readability. |
3061 | return parseToken(T: lltok::rparen, ErrMsg: "expected ')' at end of argument list" ); |
3062 | } |
3063 | |
3064 | // parse the argument. |
3065 | LocTy ArgLoc; |
3066 | Type *ArgTy = nullptr; |
3067 | Value *V; |
3068 | if (parseType(Result&: ArgTy, Loc&: ArgLoc)) |
3069 | return true; |
3070 | if (!FunctionType::isValidArgumentType(ArgTy)) |
3071 | return error(L: ArgLoc, Msg: "invalid type for function argument" ); |
3072 | |
3073 | AttrBuilder ArgAttrs(M->getContext()); |
3074 | |
3075 | if (ArgTy->isMetadataTy()) { |
3076 | if (parseMetadataAsValue(V, PFS)) |
3077 | return true; |
3078 | } else { |
3079 | // Otherwise, handle normal operands. |
3080 | if (parseOptionalParamAttrs(B&: ArgAttrs) || parseValue(Ty: ArgTy, V, PFS)) |
3081 | return true; |
3082 | } |
3083 | ArgList.push_back(Elt: ParamInfo( |
3084 | ArgLoc, V, AttributeSet::get(C&: V->getContext(), B: ArgAttrs))); |
3085 | } |
3086 | |
3087 | if (IsMustTailCall && InVarArgsFunc) |
3088 | return tokError(Msg: "expected '...' at end of argument list for musttail call " |
3089 | "in varargs function" ); |
3090 | |
3091 | Lex.Lex(); // Lex the ')'. |
3092 | return false; |
3093 | } |
3094 | |
3095 | /// parseRequiredTypeAttr |
3096 | /// ::= attrname(<ty>) |
3097 | bool LLParser::parseRequiredTypeAttr(AttrBuilder &B, lltok::Kind AttrToken, |
3098 | Attribute::AttrKind AttrKind) { |
3099 | Type *Ty = nullptr; |
3100 | if (!EatIfPresent(T: AttrToken)) |
3101 | return true; |
3102 | if (!EatIfPresent(T: lltok::lparen)) |
3103 | return error(L: Lex.getLoc(), Msg: "expected '('" ); |
3104 | if (parseType(Result&: Ty)) |
3105 | return true; |
3106 | if (!EatIfPresent(T: lltok::rparen)) |
3107 | return error(L: Lex.getLoc(), Msg: "expected ')'" ); |
3108 | |
3109 | B.addTypeAttr(Kind: AttrKind, Ty); |
3110 | return false; |
3111 | } |
3112 | |
3113 | /// parseRangeAttr |
3114 | /// ::= range(<ty> <n>,<n>) |
3115 | bool LLParser::parseRangeAttr(AttrBuilder &B) { |
3116 | Lex.Lex(); |
3117 | |
3118 | APInt Lower; |
3119 | APInt Upper; |
3120 | Type *Ty = nullptr; |
3121 | LocTy TyLoc; |
3122 | |
3123 | auto ParseAPSInt = [&](unsigned BitWidth, APInt &Val) { |
3124 | if (Lex.getKind() != lltok::APSInt) |
3125 | return tokError(Msg: "expected integer" ); |
3126 | if (Lex.getAPSIntVal().getBitWidth() > BitWidth) |
3127 | return tokError( |
3128 | Msg: "integer is too large for the bit width of specified type" ); |
3129 | Val = Lex.getAPSIntVal().extend(width: BitWidth); |
3130 | Lex.Lex(); |
3131 | return false; |
3132 | }; |
3133 | |
3134 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '('" ) || parseType(Result&: Ty, Loc&: TyLoc)) |
3135 | return true; |
3136 | if (!Ty->isIntegerTy()) |
3137 | return error(L: TyLoc, Msg: "the range must have integer type!" ); |
3138 | |
3139 | unsigned BitWidth = Ty->getPrimitiveSizeInBits(); |
3140 | |
3141 | if (ParseAPSInt(BitWidth, Lower) || |
3142 | parseToken(T: lltok::comma, ErrMsg: "expected ','" ) || ParseAPSInt(BitWidth, Upper)) |
3143 | return true; |
3144 | if (Lower == Upper && !Lower.isZero()) |
3145 | return tokError(Msg: "the range represent the empty set but limits aren't 0!" ); |
3146 | |
3147 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')'" )) |
3148 | return true; |
3149 | |
3150 | B.addRangeAttr(CR: ConstantRange(Lower, Upper)); |
3151 | return false; |
3152 | } |
3153 | |
3154 | /// parseInitializesAttr |
3155 | /// ::= initializes((Lo1,Hi1),(Lo2,Hi2),...) |
3156 | bool LLParser::parseInitializesAttr(AttrBuilder &B) { |
3157 | Lex.Lex(); |
3158 | |
3159 | auto ParseAPSInt = [&](APInt &Val) { |
3160 | if (Lex.getKind() != lltok::APSInt) |
3161 | return tokError(Msg: "expected integer" ); |
3162 | Val = Lex.getAPSIntVal().extend(width: 64); |
3163 | Lex.Lex(); |
3164 | return false; |
3165 | }; |
3166 | |
3167 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '('" )) |
3168 | return true; |
3169 | |
3170 | SmallVector<ConstantRange, 2> RangeList; |
3171 | // Parse each constant range. |
3172 | do { |
3173 | APInt Lower, Upper; |
3174 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '('" )) |
3175 | return true; |
3176 | |
3177 | if (ParseAPSInt(Lower) || parseToken(T: lltok::comma, ErrMsg: "expected ','" ) || |
3178 | ParseAPSInt(Upper)) |
3179 | return true; |
3180 | |
3181 | if (Lower == Upper) |
3182 | return tokError(Msg: "the range should not represent the full or empty set!" ); |
3183 | |
3184 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')'" )) |
3185 | return true; |
3186 | |
3187 | RangeList.push_back(Elt: ConstantRange(Lower, Upper)); |
3188 | } while (EatIfPresent(T: lltok::comma)); |
3189 | |
3190 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')'" )) |
3191 | return true; |
3192 | |
3193 | auto CRLOrNull = ConstantRangeList::getConstantRangeList(RangesRef: RangeList); |
3194 | if (!CRLOrNull.has_value()) |
3195 | return tokError(Msg: "Invalid (unordered or overlapping) range list" ); |
3196 | B.addInitializesAttr(CRL: *CRLOrNull); |
3197 | return false; |
3198 | } |
3199 | |
3200 | bool LLParser::parseCapturesAttr(AttrBuilder &B) { |
3201 | CaptureComponents Other = CaptureComponents::None; |
3202 | std::optional<CaptureComponents> Ret; |
3203 | |
3204 | // We use syntax like captures(ret: address, provenance), so the colon |
3205 | // should not be interpreted as a label terminator. |
3206 | Lex.setIgnoreColonInIdentifiers(true); |
3207 | auto _ = make_scope_exit(F: [&] { Lex.setIgnoreColonInIdentifiers(false); }); |
3208 | |
3209 | Lex.Lex(); |
3210 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '('" )) |
3211 | return true; |
3212 | |
3213 | CaptureComponents *Current = &Other; |
3214 | bool SeenComponent = false; |
3215 | while (true) { |
3216 | if (EatIfPresent(T: lltok::kw_ret)) { |
3217 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
3218 | return true; |
3219 | if (Ret) |
3220 | return tokError(Msg: "duplicate 'ret' location" ); |
3221 | Ret = CaptureComponents::None; |
3222 | Current = &*Ret; |
3223 | SeenComponent = false; |
3224 | } |
3225 | |
3226 | if (EatIfPresent(T: lltok::kw_none)) { |
3227 | if (SeenComponent) |
3228 | return tokError(Msg: "cannot use 'none' with other component" ); |
3229 | *Current = CaptureComponents::None; |
3230 | } else { |
3231 | if (SeenComponent && capturesNothing(CC: *Current)) |
3232 | return tokError(Msg: "cannot use 'none' with other component" ); |
3233 | |
3234 | if (EatIfPresent(T: lltok::kw_address_is_null)) |
3235 | *Current |= CaptureComponents::AddressIsNull; |
3236 | else if (EatIfPresent(T: lltok::kw_address)) |
3237 | *Current |= CaptureComponents::Address; |
3238 | else if (EatIfPresent(T: lltok::kw_provenance)) |
3239 | *Current |= CaptureComponents::Provenance; |
3240 | else if (EatIfPresent(T: lltok::kw_read_provenance)) |
3241 | *Current |= CaptureComponents::ReadProvenance; |
3242 | else |
3243 | return tokError(Msg: "expected one of 'none', 'address', 'address_is_null', " |
3244 | "'provenance' or 'read_provenance'" ); |
3245 | } |
3246 | |
3247 | SeenComponent = true; |
3248 | if (EatIfPresent(T: lltok::rparen)) |
3249 | break; |
3250 | |
3251 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' or ')'" )) |
3252 | return true; |
3253 | } |
3254 | |
3255 | B.addCapturesAttr(CI: CaptureInfo(Other, Ret.value_or(u&: Other))); |
3256 | return false; |
3257 | } |
3258 | |
3259 | /// parseOptionalOperandBundles |
3260 | /// ::= /*empty*/ |
3261 | /// ::= '[' OperandBundle [, OperandBundle ]* ']' |
3262 | /// |
3263 | /// OperandBundle |
3264 | /// ::= bundle-tag '(' ')' |
3265 | /// ::= bundle-tag '(' Type Value [, Type Value ]* ')' |
3266 | /// |
3267 | /// bundle-tag ::= String Constant |
3268 | bool LLParser::parseOptionalOperandBundles( |
3269 | SmallVectorImpl<OperandBundleDef> &BundleList, PerFunctionState &PFS) { |
3270 | LocTy BeginLoc = Lex.getLoc(); |
3271 | if (!EatIfPresent(T: lltok::lsquare)) |
3272 | return false; |
3273 | |
3274 | while (Lex.getKind() != lltok::rsquare) { |
3275 | // If this isn't the first operand bundle, we need a comma. |
3276 | if (!BundleList.empty() && |
3277 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in input list" )) |
3278 | return true; |
3279 | |
3280 | std::string Tag; |
3281 | if (parseStringConstant(Result&: Tag)) |
3282 | return true; |
3283 | |
3284 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in operand bundle" )) |
3285 | return true; |
3286 | |
3287 | std::vector<Value *> Inputs; |
3288 | while (Lex.getKind() != lltok::rparen) { |
3289 | // If this isn't the first input, we need a comma. |
3290 | if (!Inputs.empty() && |
3291 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in input list" )) |
3292 | return true; |
3293 | |
3294 | Type *Ty = nullptr; |
3295 | Value *Input = nullptr; |
3296 | if (parseType(Result&: Ty)) |
3297 | return true; |
3298 | if (Ty->isMetadataTy()) { |
3299 | if (parseMetadataAsValue(V&: Input, PFS)) |
3300 | return true; |
3301 | } else if (parseValue(Ty, V&: Input, PFS)) { |
3302 | return true; |
3303 | } |
3304 | Inputs.push_back(x: Input); |
3305 | } |
3306 | |
3307 | BundleList.emplace_back(Args: std::move(Tag), Args: std::move(Inputs)); |
3308 | |
3309 | Lex.Lex(); // Lex the ')'. |
3310 | } |
3311 | |
3312 | if (BundleList.empty()) |
3313 | return error(L: BeginLoc, Msg: "operand bundle set must not be empty" ); |
3314 | |
3315 | Lex.Lex(); // Lex the ']'. |
3316 | return false; |
3317 | } |
3318 | |
3319 | bool LLParser::checkValueID(LocTy Loc, StringRef Kind, StringRef Prefix, |
3320 | unsigned NextID, unsigned ID) { |
3321 | if (ID < NextID) |
3322 | return error(L: Loc, Msg: Kind + " expected to be numbered '" + Prefix + |
3323 | Twine(NextID) + "' or greater" ); |
3324 | |
3325 | return false; |
3326 | } |
3327 | |
3328 | /// parseArgumentList - parse the argument list for a function type or function |
3329 | /// prototype. |
3330 | /// ::= '(' ArgTypeListI ')' |
3331 | /// ArgTypeListI |
3332 | /// ::= /*empty*/ |
3333 | /// ::= '...' |
3334 | /// ::= ArgTypeList ',' '...' |
3335 | /// ::= ArgType (',' ArgType)* |
3336 | /// |
3337 | bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, |
3338 | SmallVectorImpl<unsigned> &UnnamedArgNums, |
3339 | bool &IsVarArg) { |
3340 | unsigned CurValID = 0; |
3341 | IsVarArg = false; |
3342 | assert(Lex.getKind() == lltok::lparen); |
3343 | Lex.Lex(); // eat the (. |
3344 | |
3345 | if (Lex.getKind() != lltok::rparen) { |
3346 | do { |
3347 | // Handle ... at end of arg list. |
3348 | if (EatIfPresent(T: lltok::dotdotdot)) { |
3349 | IsVarArg = true; |
3350 | break; |
3351 | } |
3352 | |
3353 | // Otherwise must be an argument type. |
3354 | LocTy TypeLoc = Lex.getLoc(); |
3355 | Type *ArgTy = nullptr; |
3356 | AttrBuilder Attrs(M->getContext()); |
3357 | if (parseType(Result&: ArgTy) || parseOptionalParamAttrs(B&: Attrs)) |
3358 | return true; |
3359 | |
3360 | if (ArgTy->isVoidTy()) |
3361 | return error(L: TypeLoc, Msg: "argument can not have void type" ); |
3362 | |
3363 | std::string Name; |
3364 | if (Lex.getKind() == lltok::LocalVar) { |
3365 | Name = Lex.getStrVal(); |
3366 | Lex.Lex(); |
3367 | } else { |
3368 | unsigned ArgID; |
3369 | if (Lex.getKind() == lltok::LocalVarID) { |
3370 | ArgID = Lex.getUIntVal(); |
3371 | if (checkValueID(Loc: TypeLoc, Kind: "argument" , Prefix: "%" , NextID: CurValID, ID: ArgID)) |
3372 | return true; |
3373 | Lex.Lex(); |
3374 | } else { |
3375 | ArgID = CurValID; |
3376 | } |
3377 | UnnamedArgNums.push_back(Elt: ArgID); |
3378 | CurValID = ArgID + 1; |
3379 | } |
3380 | |
3381 | if (!FunctionType::isValidArgumentType(ArgTy)) |
3382 | return error(L: TypeLoc, Msg: "invalid type for function argument" ); |
3383 | |
3384 | ArgList.emplace_back(Args&: TypeLoc, Args&: ArgTy, |
3385 | Args: AttributeSet::get(C&: ArgTy->getContext(), B: Attrs), |
3386 | Args: std::move(Name)); |
3387 | } while (EatIfPresent(T: lltok::comma)); |
3388 | } |
3389 | |
3390 | return parseToken(T: lltok::rparen, ErrMsg: "expected ')' at end of argument list" ); |
3391 | } |
3392 | |
3393 | /// parseFunctionType |
3394 | /// ::= Type ArgumentList OptionalAttrs |
3395 | bool LLParser::parseFunctionType(Type *&Result) { |
3396 | assert(Lex.getKind() == lltok::lparen); |
3397 | |
3398 | if (!FunctionType::isValidReturnType(RetTy: Result)) |
3399 | return tokError(Msg: "invalid function return type" ); |
3400 | |
3401 | SmallVector<ArgInfo, 8> ArgList; |
3402 | bool IsVarArg; |
3403 | SmallVector<unsigned> UnnamedArgNums; |
3404 | if (parseArgumentList(ArgList, UnnamedArgNums, IsVarArg)) |
3405 | return true; |
3406 | |
3407 | // Reject names on the arguments lists. |
3408 | for (const ArgInfo &Arg : ArgList) { |
3409 | if (!Arg.Name.empty()) |
3410 | return error(L: Arg.Loc, Msg: "argument name invalid in function type" ); |
3411 | if (Arg.Attrs.hasAttributes()) |
3412 | return error(L: Arg.Loc, Msg: "argument attributes invalid in function type" ); |
3413 | } |
3414 | |
3415 | SmallVector<Type*, 16> ArgListTy; |
3416 | for (const ArgInfo &Arg : ArgList) |
3417 | ArgListTy.push_back(Elt: Arg.Ty); |
3418 | |
3419 | Result = FunctionType::get(Result, Params: ArgListTy, isVarArg: IsVarArg); |
3420 | return false; |
3421 | } |
3422 | |
3423 | /// parseAnonStructType - parse an anonymous struct type, which is inlined into |
3424 | /// other structs. |
3425 | bool LLParser::parseAnonStructType(Type *&Result, bool Packed) { |
3426 | SmallVector<Type*, 8> Elts; |
3427 | if (parseStructBody(Body&: Elts)) |
3428 | return true; |
3429 | |
3430 | Result = StructType::get(Context, Elements: Elts, isPacked: Packed); |
3431 | return false; |
3432 | } |
3433 | |
3434 | /// parseStructDefinition - parse a struct in a 'type' definition. |
3435 | bool LLParser::parseStructDefinition(SMLoc TypeLoc, StringRef Name, |
3436 | std::pair<Type *, LocTy> &Entry, |
3437 | Type *&ResultTy) { |
3438 | // If the type was already defined, diagnose the redefinition. |
3439 | if (Entry.first && !Entry.second.isValid()) |
3440 | return error(L: TypeLoc, Msg: "redefinition of type" ); |
3441 | |
3442 | // If we have opaque, just return without filling in the definition for the |
3443 | // struct. This counts as a definition as far as the .ll file goes. |
3444 | if (EatIfPresent(T: lltok::kw_opaque)) { |
3445 | // This type is being defined, so clear the location to indicate this. |
3446 | Entry.second = SMLoc(); |
3447 | |
3448 | // If this type number has never been uttered, create it. |
3449 | if (!Entry.first) |
3450 | Entry.first = StructType::create(Context, Name); |
3451 | ResultTy = Entry.first; |
3452 | return false; |
3453 | } |
3454 | |
3455 | // If the type starts with '<', then it is either a packed struct or a vector. |
3456 | bool isPacked = EatIfPresent(T: lltok::less); |
3457 | |
3458 | // If we don't have a struct, then we have a random type alias, which we |
3459 | // accept for compatibility with old files. These types are not allowed to be |
3460 | // forward referenced and not allowed to be recursive. |
3461 | if (Lex.getKind() != lltok::lbrace) { |
3462 | if (Entry.first) |
3463 | return error(L: TypeLoc, Msg: "forward references to non-struct type" ); |
3464 | |
3465 | ResultTy = nullptr; |
3466 | if (isPacked) |
3467 | return parseArrayVectorType(Result&: ResultTy, IsVector: true); |
3468 | return parseType(Result&: ResultTy); |
3469 | } |
3470 | |
3471 | // This type is being defined, so clear the location to indicate this. |
3472 | Entry.second = SMLoc(); |
3473 | |
3474 | // If this type number has never been uttered, create it. |
3475 | if (!Entry.first) |
3476 | Entry.first = StructType::create(Context, Name); |
3477 | |
3478 | StructType *STy = cast<StructType>(Val: Entry.first); |
3479 | |
3480 | SmallVector<Type*, 8> Body; |
3481 | if (parseStructBody(Body) || |
3482 | (isPacked && parseToken(T: lltok::greater, ErrMsg: "expected '>' in packed struct" ))) |
3483 | return true; |
3484 | |
3485 | if (auto E = STy->setBodyOrError(Elements: Body, isPacked)) |
3486 | return tokError(Msg: toString(E: std::move(E))); |
3487 | |
3488 | ResultTy = STy; |
3489 | return false; |
3490 | } |
3491 | |
3492 | /// parseStructType: Handles packed and unpacked types. </> parsed elsewhere. |
3493 | /// StructType |
3494 | /// ::= '{' '}' |
3495 | /// ::= '{' Type (',' Type)* '}' |
3496 | /// ::= '<' '{' '}' '>' |
3497 | /// ::= '<' '{' Type (',' Type)* '}' '>' |
3498 | bool LLParser::parseStructBody(SmallVectorImpl<Type *> &Body) { |
3499 | assert(Lex.getKind() == lltok::lbrace); |
3500 | Lex.Lex(); // Consume the '{' |
3501 | |
3502 | // Handle the empty struct. |
3503 | if (EatIfPresent(T: lltok::rbrace)) |
3504 | return false; |
3505 | |
3506 | LocTy EltTyLoc = Lex.getLoc(); |
3507 | Type *Ty = nullptr; |
3508 | if (parseType(Result&: Ty)) |
3509 | return true; |
3510 | Body.push_back(Elt: Ty); |
3511 | |
3512 | if (!StructType::isValidElementType(ElemTy: Ty)) |
3513 | return error(L: EltTyLoc, Msg: "invalid element type for struct" ); |
3514 | |
3515 | while (EatIfPresent(T: lltok::comma)) { |
3516 | EltTyLoc = Lex.getLoc(); |
3517 | if (parseType(Result&: Ty)) |
3518 | return true; |
3519 | |
3520 | if (!StructType::isValidElementType(ElemTy: Ty)) |
3521 | return error(L: EltTyLoc, Msg: "invalid element type for struct" ); |
3522 | |
3523 | Body.push_back(Elt: Ty); |
3524 | } |
3525 | |
3526 | return parseToken(T: lltok::rbrace, ErrMsg: "expected '}' at end of struct" ); |
3527 | } |
3528 | |
3529 | /// parseArrayVectorType - parse an array or vector type, assuming the first |
3530 | /// token has already been consumed. |
3531 | /// Type |
3532 | /// ::= '[' APSINTVAL 'x' Types ']' |
3533 | /// ::= '<' APSINTVAL 'x' Types '>' |
3534 | /// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>' |
3535 | bool LLParser::parseArrayVectorType(Type *&Result, bool IsVector) { |
3536 | bool Scalable = false; |
3537 | |
3538 | if (IsVector && Lex.getKind() == lltok::kw_vscale) { |
3539 | Lex.Lex(); // consume the 'vscale' |
3540 | if (parseToken(T: lltok::kw_x, ErrMsg: "expected 'x' after vscale" )) |
3541 | return true; |
3542 | |
3543 | Scalable = true; |
3544 | } |
3545 | |
3546 | if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() || |
3547 | Lex.getAPSIntVal().getBitWidth() > 64) |
3548 | return tokError(Msg: "expected number in address space" ); |
3549 | |
3550 | LocTy SizeLoc = Lex.getLoc(); |
3551 | uint64_t Size = Lex.getAPSIntVal().getZExtValue(); |
3552 | Lex.Lex(); |
3553 | |
3554 | if (parseToken(T: lltok::kw_x, ErrMsg: "expected 'x' after element count" )) |
3555 | return true; |
3556 | |
3557 | LocTy TypeLoc = Lex.getLoc(); |
3558 | Type *EltTy = nullptr; |
3559 | if (parseType(Result&: EltTy)) |
3560 | return true; |
3561 | |
3562 | if (parseToken(T: IsVector ? lltok::greater : lltok::rsquare, |
3563 | ErrMsg: "expected end of sequential type" )) |
3564 | return true; |
3565 | |
3566 | if (IsVector) { |
3567 | if (Size == 0) |
3568 | return error(L: SizeLoc, Msg: "zero element vector is illegal" ); |
3569 | if ((unsigned)Size != Size) |
3570 | return error(L: SizeLoc, Msg: "size too large for vector" ); |
3571 | if (!VectorType::isValidElementType(ElemTy: EltTy)) |
3572 | return error(L: TypeLoc, Msg: "invalid vector element type" ); |
3573 | Result = VectorType::get(ElementType: EltTy, NumElements: unsigned(Size), Scalable); |
3574 | } else { |
3575 | if (!ArrayType::isValidElementType(ElemTy: EltTy)) |
3576 | return error(L: TypeLoc, Msg: "invalid array element type" ); |
3577 | Result = ArrayType::get(ElementType: EltTy, NumElements: Size); |
3578 | } |
3579 | return false; |
3580 | } |
3581 | |
3582 | /// parseTargetExtType - handle target extension type syntax |
3583 | /// TargetExtType |
3584 | /// ::= 'target' '(' STRINGCONSTANT TargetExtTypeParams TargetExtIntParams ')' |
3585 | /// |
3586 | /// TargetExtTypeParams |
3587 | /// ::= /*empty*/ |
3588 | /// ::= ',' Type TargetExtTypeParams |
3589 | /// |
3590 | /// TargetExtIntParams |
3591 | /// ::= /*empty*/ |
3592 | /// ::= ',' uint32 TargetExtIntParams |
3593 | bool LLParser::parseTargetExtType(Type *&Result) { |
3594 | Lex.Lex(); // Eat the 'target' keyword. |
3595 | |
3596 | // Get the mandatory type name. |
3597 | std::string TypeName; |
3598 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in target extension type" ) || |
3599 | parseStringConstant(Result&: TypeName)) |
3600 | return true; |
3601 | |
3602 | // Parse all of the integer and type parameters at the same time; the use of |
3603 | // SeenInt will allow us to catch cases where type parameters follow integer |
3604 | // parameters. |
3605 | SmallVector<Type *> TypeParams; |
3606 | SmallVector<unsigned> IntParams; |
3607 | bool SeenInt = false; |
3608 | while (Lex.getKind() == lltok::comma) { |
3609 | Lex.Lex(); // Eat the comma. |
3610 | |
3611 | if (Lex.getKind() == lltok::APSInt) { |
3612 | SeenInt = true; |
3613 | unsigned IntVal; |
3614 | if (parseUInt32(Val&: IntVal)) |
3615 | return true; |
3616 | IntParams.push_back(Elt: IntVal); |
3617 | } else if (SeenInt) { |
3618 | // The only other kind of parameter we support is type parameters, which |
3619 | // must precede the integer parameters. This is therefore an error. |
3620 | return tokError(Msg: "expected uint32 param" ); |
3621 | } else { |
3622 | Type *TypeParam; |
3623 | if (parseType(Result&: TypeParam, /*AllowVoid=*/true)) |
3624 | return true; |
3625 | TypeParams.push_back(Elt: TypeParam); |
3626 | } |
3627 | } |
3628 | |
3629 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in target extension type" )) |
3630 | return true; |
3631 | |
3632 | auto TTy = |
3633 | TargetExtType::getOrError(Context, Name: TypeName, Types: TypeParams, Ints: IntParams); |
3634 | if (auto E = TTy.takeError()) |
3635 | return tokError(Msg: toString(E: std::move(E))); |
3636 | |
3637 | Result = *TTy; |
3638 | return false; |
3639 | } |
3640 | |
3641 | //===----------------------------------------------------------------------===// |
3642 | // Function Semantic Analysis. |
3643 | //===----------------------------------------------------------------------===// |
3644 | |
3645 | LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f, |
3646 | int functionNumber, |
3647 | ArrayRef<unsigned> UnnamedArgNums) |
3648 | : P(p), F(f), FunctionNumber(functionNumber) { |
3649 | |
3650 | // Insert unnamed arguments into the NumberedVals list. |
3651 | auto It = UnnamedArgNums.begin(); |
3652 | for (Argument &A : F.args()) { |
3653 | if (!A.hasName()) { |
3654 | unsigned ArgNum = *It++; |
3655 | NumberedVals.add(ID: ArgNum, V: &A); |
3656 | } |
3657 | } |
3658 | } |
3659 | |
3660 | LLParser::PerFunctionState::~PerFunctionState() { |
3661 | // If there were any forward referenced non-basicblock values, delete them. |
3662 | |
3663 | for (const auto &P : ForwardRefVals) { |
3664 | if (isa<BasicBlock>(Val: P.second.first)) |
3665 | continue; |
3666 | P.second.first->replaceAllUsesWith( |
3667 | V: PoisonValue::get(T: P.second.first->getType())); |
3668 | P.second.first->deleteValue(); |
3669 | } |
3670 | |
3671 | for (const auto &P : ForwardRefValIDs) { |
3672 | if (isa<BasicBlock>(Val: P.second.first)) |
3673 | continue; |
3674 | P.second.first->replaceAllUsesWith( |
3675 | V: PoisonValue::get(T: P.second.first->getType())); |
3676 | P.second.first->deleteValue(); |
3677 | } |
3678 | } |
3679 | |
3680 | bool LLParser::PerFunctionState::finishFunction() { |
3681 | if (!ForwardRefVals.empty()) |
3682 | return P.error(L: ForwardRefVals.begin()->second.second, |
3683 | Msg: "use of undefined value '%" + ForwardRefVals.begin()->first + |
3684 | "'" ); |
3685 | if (!ForwardRefValIDs.empty()) |
3686 | return P.error(L: ForwardRefValIDs.begin()->second.second, |
3687 | Msg: "use of undefined value '%" + |
3688 | Twine(ForwardRefValIDs.begin()->first) + "'" ); |
3689 | return false; |
3690 | } |
3691 | |
3692 | /// getVal - Get a value with the specified name or ID, creating a |
3693 | /// forward reference record if needed. This can return null if the value |
3694 | /// exists but does not have the right type. |
3695 | Value *LLParser::PerFunctionState::getVal(const std::string &Name, Type *Ty, |
3696 | LocTy Loc) { |
3697 | // Look this name up in the normal function symbol table. |
3698 | Value *Val = F.getValueSymbolTable()->lookup(Name); |
3699 | |
3700 | // If this is a forward reference for the value, see if we already created a |
3701 | // forward ref record. |
3702 | if (!Val) { |
3703 | auto I = ForwardRefVals.find(x: Name); |
3704 | if (I != ForwardRefVals.end()) |
3705 | Val = I->second.first; |
3706 | } |
3707 | |
3708 | // If we have the value in the symbol table or fwd-ref table, return it. |
3709 | if (Val) |
3710 | return P.checkValidVariableType(Loc, Name: "%" + Name, Ty, Val); |
3711 | |
3712 | // Don't make placeholders with invalid type. |
3713 | if (!Ty->isFirstClassType()) { |
3714 | P.error(L: Loc, Msg: "invalid use of a non-first-class type" ); |
3715 | return nullptr; |
3716 | } |
3717 | |
3718 | // Otherwise, create a new forward reference for this value and remember it. |
3719 | Value *FwdVal; |
3720 | if (Ty->isLabelTy()) { |
3721 | FwdVal = BasicBlock::Create(Context&: F.getContext(), Name, Parent: &F); |
3722 | } else { |
3723 | FwdVal = new Argument(Ty, Name); |
3724 | } |
3725 | if (FwdVal->getName() != Name) { |
3726 | P.error(L: Loc, Msg: "name is too long which can result in name collisions, " |
3727 | "consider making the name shorter or " |
3728 | "increasing -non-global-value-max-name-size" ); |
3729 | return nullptr; |
3730 | } |
3731 | |
3732 | ForwardRefVals[Name] = std::make_pair(x&: FwdVal, y&: Loc); |
3733 | return FwdVal; |
3734 | } |
3735 | |
3736 | Value *LLParser::PerFunctionState::getVal(unsigned ID, Type *Ty, LocTy Loc) { |
3737 | // Look this name up in the normal function symbol table. |
3738 | Value *Val = NumberedVals.get(ID); |
3739 | |
3740 | // If this is a forward reference for the value, see if we already created a |
3741 | // forward ref record. |
3742 | if (!Val) { |
3743 | auto I = ForwardRefValIDs.find(x: ID); |
3744 | if (I != ForwardRefValIDs.end()) |
3745 | Val = I->second.first; |
3746 | } |
3747 | |
3748 | // If we have the value in the symbol table or fwd-ref table, return it. |
3749 | if (Val) |
3750 | return P.checkValidVariableType(Loc, Name: "%" + Twine(ID), Ty, Val); |
3751 | |
3752 | if (!Ty->isFirstClassType()) { |
3753 | P.error(L: Loc, Msg: "invalid use of a non-first-class type" ); |
3754 | return nullptr; |
3755 | } |
3756 | |
3757 | // Otherwise, create a new forward reference for this value and remember it. |
3758 | Value *FwdVal; |
3759 | if (Ty->isLabelTy()) { |
3760 | FwdVal = BasicBlock::Create(Context&: F.getContext(), Name: "" , Parent: &F); |
3761 | } else { |
3762 | FwdVal = new Argument(Ty); |
3763 | } |
3764 | |
3765 | ForwardRefValIDs[ID] = std::make_pair(x&: FwdVal, y&: Loc); |
3766 | return FwdVal; |
3767 | } |
3768 | |
3769 | /// setInstName - After an instruction is parsed and inserted into its |
3770 | /// basic block, this installs its name. |
3771 | bool LLParser::PerFunctionState::setInstName(int NameID, |
3772 | const std::string &NameStr, |
3773 | LocTy NameLoc, Instruction *Inst) { |
3774 | // If this instruction has void type, it cannot have a name or ID specified. |
3775 | if (Inst->getType()->isVoidTy()) { |
3776 | if (NameID != -1 || !NameStr.empty()) |
3777 | return P.error(L: NameLoc, Msg: "instructions returning void cannot have a name" ); |
3778 | return false; |
3779 | } |
3780 | |
3781 | // If this was a numbered instruction, verify that the instruction is the |
3782 | // expected value and resolve any forward references. |
3783 | if (NameStr.empty()) { |
3784 | // If neither a name nor an ID was specified, just use the next ID. |
3785 | if (NameID == -1) |
3786 | NameID = NumberedVals.getNext(); |
3787 | |
3788 | if (P.checkValueID(Loc: NameLoc, Kind: "instruction" , Prefix: "%" , NextID: NumberedVals.getNext(), |
3789 | ID: NameID)) |
3790 | return true; |
3791 | |
3792 | auto FI = ForwardRefValIDs.find(x: NameID); |
3793 | if (FI != ForwardRefValIDs.end()) { |
3794 | Value *Sentinel = FI->second.first; |
3795 | if (Sentinel->getType() != Inst->getType()) |
3796 | return P.error(L: NameLoc, Msg: "instruction forward referenced with type '" + |
3797 | getTypeString(T: FI->second.first->getType()) + |
3798 | "'" ); |
3799 | |
3800 | Sentinel->replaceAllUsesWith(V: Inst); |
3801 | Sentinel->deleteValue(); |
3802 | ForwardRefValIDs.erase(position: FI); |
3803 | } |
3804 | |
3805 | NumberedVals.add(ID: NameID, V: Inst); |
3806 | return false; |
3807 | } |
3808 | |
3809 | // Otherwise, the instruction had a name. Resolve forward refs and set it. |
3810 | auto FI = ForwardRefVals.find(x: NameStr); |
3811 | if (FI != ForwardRefVals.end()) { |
3812 | Value *Sentinel = FI->second.first; |
3813 | if (Sentinel->getType() != Inst->getType()) |
3814 | return P.error(L: NameLoc, Msg: "instruction forward referenced with type '" + |
3815 | getTypeString(T: FI->second.first->getType()) + |
3816 | "'" ); |
3817 | |
3818 | Sentinel->replaceAllUsesWith(V: Inst); |
3819 | Sentinel->deleteValue(); |
3820 | ForwardRefVals.erase(position: FI); |
3821 | } |
3822 | |
3823 | // Set the name on the instruction. |
3824 | Inst->setName(NameStr); |
3825 | |
3826 | if (Inst->getName() != NameStr) |
3827 | return P.error(L: NameLoc, Msg: "multiple definition of local value named '" + |
3828 | NameStr + "'" ); |
3829 | return false; |
3830 | } |
3831 | |
3832 | /// getBB - Get a basic block with the specified name or ID, creating a |
3833 | /// forward reference record if needed. |
3834 | BasicBlock *LLParser::PerFunctionState::getBB(const std::string &Name, |
3835 | LocTy Loc) { |
3836 | return dyn_cast_or_null<BasicBlock>( |
3837 | Val: getVal(Name, Ty: Type::getLabelTy(C&: F.getContext()), Loc)); |
3838 | } |
3839 | |
3840 | BasicBlock *LLParser::PerFunctionState::getBB(unsigned ID, LocTy Loc) { |
3841 | return dyn_cast_or_null<BasicBlock>( |
3842 | Val: getVal(ID, Ty: Type::getLabelTy(C&: F.getContext()), Loc)); |
3843 | } |
3844 | |
3845 | /// defineBB - Define the specified basic block, which is either named or |
3846 | /// unnamed. If there is an error, this returns null otherwise it returns |
3847 | /// the block being defined. |
3848 | BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name, |
3849 | int NameID, LocTy Loc) { |
3850 | BasicBlock *BB; |
3851 | if (Name.empty()) { |
3852 | if (NameID != -1) { |
3853 | if (P.checkValueID(Loc, Kind: "label" , Prefix: "" , NextID: NumberedVals.getNext(), ID: NameID)) |
3854 | return nullptr; |
3855 | } else { |
3856 | NameID = NumberedVals.getNext(); |
3857 | } |
3858 | BB = getBB(ID: NameID, Loc); |
3859 | if (!BB) { |
3860 | P.error(L: Loc, Msg: "unable to create block numbered '" + Twine(NameID) + "'" ); |
3861 | return nullptr; |
3862 | } |
3863 | } else { |
3864 | BB = getBB(Name, Loc); |
3865 | if (!BB) { |
3866 | P.error(L: Loc, Msg: "unable to create block named '" + Name + "'" ); |
3867 | return nullptr; |
3868 | } |
3869 | } |
3870 | |
3871 | // Move the block to the end of the function. Forward ref'd blocks are |
3872 | // inserted wherever they happen to be referenced. |
3873 | F.splice(ToIt: F.end(), FromF: &F, FromIt: BB->getIterator()); |
3874 | |
3875 | // Remove the block from forward ref sets. |
3876 | if (Name.empty()) { |
3877 | ForwardRefValIDs.erase(x: NameID); |
3878 | NumberedVals.add(ID: NameID, V: BB); |
3879 | } else { |
3880 | // BB forward references are already in the function symbol table. |
3881 | ForwardRefVals.erase(x: Name); |
3882 | } |
3883 | |
3884 | return BB; |
3885 | } |
3886 | |
3887 | //===----------------------------------------------------------------------===// |
3888 | // Constants. |
3889 | //===----------------------------------------------------------------------===// |
3890 | |
3891 | /// parseValID - parse an abstract value that doesn't necessarily have a |
3892 | /// type implied. For example, if we parse "4" we don't know what integer type |
3893 | /// it has. The value will later be combined with its type and checked for |
3894 | /// basic correctness. PFS is used to convert function-local operands of |
3895 | /// metadata (since metadata operands are not just parsed here but also |
3896 | /// converted to values). PFS can be null when we are not parsing metadata |
3897 | /// values inside a function. |
3898 | bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { |
3899 | ID.Loc = Lex.getLoc(); |
3900 | switch (Lex.getKind()) { |
3901 | default: |
3902 | return tokError(Msg: "expected value token" ); |
3903 | case lltok::GlobalID: // @42 |
3904 | ID.UIntVal = Lex.getUIntVal(); |
3905 | ID.Kind = ValID::t_GlobalID; |
3906 | break; |
3907 | case lltok::GlobalVar: // @foo |
3908 | ID.StrVal = Lex.getStrVal(); |
3909 | ID.Kind = ValID::t_GlobalName; |
3910 | break; |
3911 | case lltok::LocalVarID: // %42 |
3912 | ID.UIntVal = Lex.getUIntVal(); |
3913 | ID.Kind = ValID::t_LocalID; |
3914 | break; |
3915 | case lltok::LocalVar: // %foo |
3916 | ID.StrVal = Lex.getStrVal(); |
3917 | ID.Kind = ValID::t_LocalName; |
3918 | break; |
3919 | case lltok::APSInt: |
3920 | ID.APSIntVal = Lex.getAPSIntVal(); |
3921 | ID.Kind = ValID::t_APSInt; |
3922 | break; |
3923 | case lltok::APFloat: |
3924 | ID.APFloatVal = Lex.getAPFloatVal(); |
3925 | ID.Kind = ValID::t_APFloat; |
3926 | break; |
3927 | case lltok::kw_true: |
3928 | ID.ConstantVal = ConstantInt::getTrue(Context); |
3929 | ID.Kind = ValID::t_Constant; |
3930 | break; |
3931 | case lltok::kw_false: |
3932 | ID.ConstantVal = ConstantInt::getFalse(Context); |
3933 | ID.Kind = ValID::t_Constant; |
3934 | break; |
3935 | case lltok::kw_null: ID.Kind = ValID::t_Null; break; |
3936 | case lltok::kw_undef: ID.Kind = ValID::t_Undef; break; |
3937 | case lltok::kw_poison: ID.Kind = ValID::t_Poison; break; |
3938 | case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break; |
3939 | case lltok::kw_none: ID.Kind = ValID::t_None; break; |
3940 | |
3941 | case lltok::lbrace: { |
3942 | // ValID ::= '{' ConstVector '}' |
3943 | Lex.Lex(); |
3944 | SmallVector<Constant*, 16> Elts; |
3945 | if (parseGlobalValueVector(Elts) || |
3946 | parseToken(T: lltok::rbrace, ErrMsg: "expected end of struct constant" )) |
3947 | return true; |
3948 | |
3949 | ID.ConstantStructElts = std::make_unique<Constant *[]>(num: Elts.size()); |
3950 | ID.UIntVal = Elts.size(); |
3951 | memcpy(dest: ID.ConstantStructElts.get(), src: Elts.data(), |
3952 | n: Elts.size() * sizeof(Elts[0])); |
3953 | ID.Kind = ValID::t_ConstantStruct; |
3954 | return false; |
3955 | } |
3956 | case lltok::less: { |
3957 | // ValID ::= '<' ConstVector '>' --> Vector. |
3958 | // ValID ::= '<' '{' ConstVector '}' '>' --> Packed Struct. |
3959 | Lex.Lex(); |
3960 | bool isPackedStruct = EatIfPresent(T: lltok::lbrace); |
3961 | |
3962 | SmallVector<Constant*, 16> Elts; |
3963 | LocTy FirstEltLoc = Lex.getLoc(); |
3964 | if (parseGlobalValueVector(Elts) || |
3965 | (isPackedStruct && |
3966 | parseToken(T: lltok::rbrace, ErrMsg: "expected end of packed struct" )) || |
3967 | parseToken(T: lltok::greater, ErrMsg: "expected end of constant" )) |
3968 | return true; |
3969 | |
3970 | if (isPackedStruct) { |
3971 | ID.ConstantStructElts = std::make_unique<Constant *[]>(num: Elts.size()); |
3972 | memcpy(dest: ID.ConstantStructElts.get(), src: Elts.data(), |
3973 | n: Elts.size() * sizeof(Elts[0])); |
3974 | ID.UIntVal = Elts.size(); |
3975 | ID.Kind = ValID::t_PackedConstantStruct; |
3976 | return false; |
3977 | } |
3978 | |
3979 | if (Elts.empty()) |
3980 | return error(L: ID.Loc, Msg: "constant vector must not be empty" ); |
3981 | |
3982 | if (!Elts[0]->getType()->isIntegerTy() && |
3983 | !Elts[0]->getType()->isFloatingPointTy() && |
3984 | !Elts[0]->getType()->isPointerTy()) |
3985 | return error( |
3986 | L: FirstEltLoc, |
3987 | Msg: "vector elements must have integer, pointer or floating point type" ); |
3988 | |
3989 | // Verify that all the vector elements have the same type. |
3990 | for (unsigned i = 1, e = Elts.size(); i != e; ++i) |
3991 | if (Elts[i]->getType() != Elts[0]->getType()) |
3992 | return error(L: FirstEltLoc, Msg: "vector element #" + Twine(i) + |
3993 | " is not of type '" + |
3994 | getTypeString(T: Elts[0]->getType())); |
3995 | |
3996 | ID.ConstantVal = ConstantVector::get(V: Elts); |
3997 | ID.Kind = ValID::t_Constant; |
3998 | return false; |
3999 | } |
4000 | case lltok::lsquare: { // Array Constant |
4001 | Lex.Lex(); |
4002 | SmallVector<Constant*, 16> Elts; |
4003 | LocTy FirstEltLoc = Lex.getLoc(); |
4004 | if (parseGlobalValueVector(Elts) || |
4005 | parseToken(T: lltok::rsquare, ErrMsg: "expected end of array constant" )) |
4006 | return true; |
4007 | |
4008 | // Handle empty element. |
4009 | if (Elts.empty()) { |
4010 | // Use undef instead of an array because it's inconvenient to determine |
4011 | // the element type at this point, there being no elements to examine. |
4012 | ID.Kind = ValID::t_EmptyArray; |
4013 | return false; |
4014 | } |
4015 | |
4016 | if (!Elts[0]->getType()->isFirstClassType()) |
4017 | return error(L: FirstEltLoc, Msg: "invalid array element type: " + |
4018 | getTypeString(T: Elts[0]->getType())); |
4019 | |
4020 | ArrayType *ATy = ArrayType::get(ElementType: Elts[0]->getType(), NumElements: Elts.size()); |
4021 | |
4022 | // Verify all elements are correct type! |
4023 | for (unsigned i = 0, e = Elts.size(); i != e; ++i) { |
4024 | if (Elts[i]->getType() != Elts[0]->getType()) |
4025 | return error(L: FirstEltLoc, Msg: "array element #" + Twine(i) + |
4026 | " is not of type '" + |
4027 | getTypeString(T: Elts[0]->getType())); |
4028 | } |
4029 | |
4030 | ID.ConstantVal = ConstantArray::get(T: ATy, V: Elts); |
4031 | ID.Kind = ValID::t_Constant; |
4032 | return false; |
4033 | } |
4034 | case lltok::kw_c: // c "foo" |
4035 | Lex.Lex(); |
4036 | ID.ConstantVal = ConstantDataArray::getString(Context, Initializer: Lex.getStrVal(), |
4037 | AddNull: false); |
4038 | if (parseToken(T: lltok::StringConstant, ErrMsg: "expected string" )) |
4039 | return true; |
4040 | ID.Kind = ValID::t_Constant; |
4041 | return false; |
4042 | |
4043 | case lltok::kw_asm: { |
4044 | // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ',' |
4045 | // STRINGCONSTANT |
4046 | bool HasSideEffect, AlignStack, AsmDialect, CanThrow; |
4047 | Lex.Lex(); |
4048 | if (parseOptionalToken(T: lltok::kw_sideeffect, Present&: HasSideEffect) || |
4049 | parseOptionalToken(T: lltok::kw_alignstack, Present&: AlignStack) || |
4050 | parseOptionalToken(T: lltok::kw_inteldialect, Present&: AsmDialect) || |
4051 | parseOptionalToken(T: lltok::kw_unwind, Present&: CanThrow) || |
4052 | parseStringConstant(Result&: ID.StrVal) || |
4053 | parseToken(T: lltok::comma, ErrMsg: "expected comma in inline asm expression" ) || |
4054 | parseToken(T: lltok::StringConstant, ErrMsg: "expected constraint string" )) |
4055 | return true; |
4056 | ID.StrVal2 = Lex.getStrVal(); |
4057 | ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack) << 1) | |
4058 | (unsigned(AsmDialect) << 2) | (unsigned(CanThrow) << 3); |
4059 | ID.Kind = ValID::t_InlineAsm; |
4060 | return false; |
4061 | } |
4062 | |
4063 | case lltok::kw_blockaddress: { |
4064 | // ValID ::= 'blockaddress' '(' @foo ',' %bar ')' |
4065 | Lex.Lex(); |
4066 | |
4067 | ValID Fn, Label; |
4068 | |
4069 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in block address expression" ) || |
4070 | parseValID(ID&: Fn, PFS) || |
4071 | parseToken(T: lltok::comma, |
4072 | ErrMsg: "expected comma in block address expression" ) || |
4073 | parseValID(ID&: Label, PFS) || |
4074 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' in block address expression" )) |
4075 | return true; |
4076 | |
4077 | if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) |
4078 | return error(L: Fn.Loc, Msg: "expected function name in blockaddress" ); |
4079 | if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) |
4080 | return error(L: Label.Loc, Msg: "expected basic block name in blockaddress" ); |
4081 | |
4082 | // Try to find the function (but skip it if it's forward-referenced). |
4083 | GlobalValue *GV = nullptr; |
4084 | if (Fn.Kind == ValID::t_GlobalID) { |
4085 | GV = NumberedVals.get(ID: Fn.UIntVal); |
4086 | } else if (!ForwardRefVals.count(x: Fn.StrVal)) { |
4087 | GV = M->getNamedValue(Name: Fn.StrVal); |
4088 | } |
4089 | Function *F = nullptr; |
4090 | if (GV) { |
4091 | // Confirm that it's actually a function with a definition. |
4092 | if (!isa<Function>(Val: GV)) |
4093 | return error(L: Fn.Loc, Msg: "expected function name in blockaddress" ); |
4094 | F = cast<Function>(Val: GV); |
4095 | if (F->isDeclaration()) |
4096 | return error(L: Fn.Loc, Msg: "cannot take blockaddress inside a declaration" ); |
4097 | } |
4098 | |
4099 | if (!F) { |
4100 | // Make a global variable as a placeholder for this reference. |
4101 | GlobalValue *&FwdRef = |
4102 | ForwardRefBlockAddresses[std::move(Fn)][std::move(Label)]; |
4103 | if (!FwdRef) { |
4104 | unsigned FwdDeclAS; |
4105 | if (ExpectedTy) { |
4106 | // If we know the type that the blockaddress is being assigned to, |
4107 | // we can use the address space of that type. |
4108 | if (!ExpectedTy->isPointerTy()) |
4109 | return error(L: ID.Loc, |
4110 | Msg: "type of blockaddress must be a pointer and not '" + |
4111 | getTypeString(T: ExpectedTy) + "'" ); |
4112 | FwdDeclAS = ExpectedTy->getPointerAddressSpace(); |
4113 | } else if (PFS) { |
4114 | // Otherwise, we default the address space of the current function. |
4115 | FwdDeclAS = PFS->getFunction().getAddressSpace(); |
4116 | } else { |
4117 | llvm_unreachable("Unknown address space for blockaddress" ); |
4118 | } |
4119 | FwdRef = new GlobalVariable( |
4120 | *M, Type::getInt8Ty(C&: Context), false, GlobalValue::InternalLinkage, |
4121 | nullptr, "" , nullptr, GlobalValue::NotThreadLocal, FwdDeclAS); |
4122 | } |
4123 | |
4124 | ID.ConstantVal = FwdRef; |
4125 | ID.Kind = ValID::t_Constant; |
4126 | return false; |
4127 | } |
4128 | |
4129 | // We found the function; now find the basic block. Don't use PFS, since we |
4130 | // might be inside a constant expression. |
4131 | BasicBlock *BB; |
4132 | if (BlockAddressPFS && F == &BlockAddressPFS->getFunction()) { |
4133 | if (Label.Kind == ValID::t_LocalID) |
4134 | BB = BlockAddressPFS->getBB(ID: Label.UIntVal, Loc: Label.Loc); |
4135 | else |
4136 | BB = BlockAddressPFS->getBB(Name: Label.StrVal, Loc: Label.Loc); |
4137 | if (!BB) |
4138 | return error(L: Label.Loc, Msg: "referenced value is not a basic block" ); |
4139 | } else { |
4140 | if (Label.Kind == ValID::t_LocalID) |
4141 | return error(L: Label.Loc, Msg: "cannot take address of numeric label after " |
4142 | "the function is defined" ); |
4143 | BB = dyn_cast_or_null<BasicBlock>( |
4144 | Val: F->getValueSymbolTable()->lookup(Name: Label.StrVal)); |
4145 | if (!BB) |
4146 | return error(L: Label.Loc, Msg: "referenced value is not a basic block" ); |
4147 | } |
4148 | |
4149 | ID.ConstantVal = BlockAddress::get(F, BB); |
4150 | ID.Kind = ValID::t_Constant; |
4151 | return false; |
4152 | } |
4153 | |
4154 | case lltok::kw_dso_local_equivalent: { |
4155 | // ValID ::= 'dso_local_equivalent' @foo |
4156 | Lex.Lex(); |
4157 | |
4158 | ValID Fn; |
4159 | |
4160 | if (parseValID(ID&: Fn, PFS)) |
4161 | return true; |
4162 | |
4163 | if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) |
4164 | return error(L: Fn.Loc, |
4165 | Msg: "expected global value name in dso_local_equivalent" ); |
4166 | |
4167 | // Try to find the function (but skip it if it's forward-referenced). |
4168 | GlobalValue *GV = nullptr; |
4169 | if (Fn.Kind == ValID::t_GlobalID) { |
4170 | GV = NumberedVals.get(ID: Fn.UIntVal); |
4171 | } else if (!ForwardRefVals.count(x: Fn.StrVal)) { |
4172 | GV = M->getNamedValue(Name: Fn.StrVal); |
4173 | } |
4174 | |
4175 | if (!GV) { |
4176 | // Make a placeholder global variable as a placeholder for this reference. |
4177 | auto &FwdRefMap = (Fn.Kind == ValID::t_GlobalID) |
4178 | ? ForwardRefDSOLocalEquivalentIDs |
4179 | : ForwardRefDSOLocalEquivalentNames; |
4180 | GlobalValue *&FwdRef = FwdRefMap[Fn]; |
4181 | if (!FwdRef) { |
4182 | FwdRef = new GlobalVariable(*M, Type::getInt8Ty(C&: Context), false, |
4183 | GlobalValue::InternalLinkage, nullptr, "" , |
4184 | nullptr, GlobalValue::NotThreadLocal); |
4185 | } |
4186 | |
4187 | ID.ConstantVal = FwdRef; |
4188 | ID.Kind = ValID::t_Constant; |
4189 | return false; |
4190 | } |
4191 | |
4192 | if (!GV->getValueType()->isFunctionTy()) |
4193 | return error(L: Fn.Loc, Msg: "expected a function, alias to function, or ifunc " |
4194 | "in dso_local_equivalent" ); |
4195 | |
4196 | ID.ConstantVal = DSOLocalEquivalent::get(GV); |
4197 | ID.Kind = ValID::t_Constant; |
4198 | return false; |
4199 | } |
4200 | |
4201 | case lltok::kw_no_cfi: { |
4202 | // ValID ::= 'no_cfi' @foo |
4203 | Lex.Lex(); |
4204 | |
4205 | if (parseValID(ID, PFS)) |
4206 | return true; |
4207 | |
4208 | if (ID.Kind != ValID::t_GlobalID && ID.Kind != ValID::t_GlobalName) |
4209 | return error(L: ID.Loc, Msg: "expected global value name in no_cfi" ); |
4210 | |
4211 | ID.NoCFI = true; |
4212 | return false; |
4213 | } |
4214 | case lltok::kw_ptrauth: { |
4215 | // ValID ::= 'ptrauth' '(' ptr @foo ',' i32 <key> |
4216 | // (',' i64 <disc> (',' ptr addrdisc)? )? ')' |
4217 | Lex.Lex(); |
4218 | |
4219 | Constant *Ptr, *Key; |
4220 | Constant *Disc = nullptr, *AddrDisc = nullptr; |
4221 | |
4222 | if (parseToken(T: lltok::lparen, |
4223 | ErrMsg: "expected '(' in constant ptrauth expression" ) || |
4224 | parseGlobalTypeAndValue(V&: Ptr) || |
4225 | parseToken(T: lltok::comma, |
4226 | ErrMsg: "expected comma in constant ptrauth expression" ) || |
4227 | parseGlobalTypeAndValue(V&: Key)) |
4228 | return true; |
4229 | // If present, parse the optional disc/addrdisc. |
4230 | if (EatIfPresent(T: lltok::comma)) |
4231 | if (parseGlobalTypeAndValue(V&: Disc) || |
4232 | (EatIfPresent(T: lltok::comma) && parseGlobalTypeAndValue(V&: AddrDisc))) |
4233 | return true; |
4234 | if (parseToken(T: lltok::rparen, |
4235 | ErrMsg: "expected ')' in constant ptrauth expression" )) |
4236 | return true; |
4237 | |
4238 | if (!Ptr->getType()->isPointerTy()) |
4239 | return error(L: ID.Loc, Msg: "constant ptrauth base pointer must be a pointer" ); |
4240 | |
4241 | auto *KeyC = dyn_cast<ConstantInt>(Val: Key); |
4242 | if (!KeyC || KeyC->getBitWidth() != 32) |
4243 | return error(L: ID.Loc, Msg: "constant ptrauth key must be i32 constant" ); |
4244 | |
4245 | ConstantInt *DiscC = nullptr; |
4246 | if (Disc) { |
4247 | DiscC = dyn_cast<ConstantInt>(Val: Disc); |
4248 | if (!DiscC || DiscC->getBitWidth() != 64) |
4249 | return error( |
4250 | L: ID.Loc, |
4251 | Msg: "constant ptrauth integer discriminator must be i64 constant" ); |
4252 | } else { |
4253 | DiscC = ConstantInt::get(Ty: Type::getInt64Ty(C&: Context), V: 0); |
4254 | } |
4255 | |
4256 | if (AddrDisc) { |
4257 | if (!AddrDisc->getType()->isPointerTy()) |
4258 | return error( |
4259 | L: ID.Loc, Msg: "constant ptrauth address discriminator must be a pointer" ); |
4260 | } else { |
4261 | AddrDisc = ConstantPointerNull::get(T: PointerType::get(C&: Context, AddressSpace: 0)); |
4262 | } |
4263 | |
4264 | ID.ConstantVal = ConstantPtrAuth::get(Ptr, Key: KeyC, Disc: DiscC, AddrDisc); |
4265 | ID.Kind = ValID::t_Constant; |
4266 | return false; |
4267 | } |
4268 | |
4269 | case lltok::kw_trunc: |
4270 | case lltok::kw_bitcast: |
4271 | case lltok::kw_addrspacecast: |
4272 | case lltok::kw_inttoptr: |
4273 | case lltok::kw_ptrtoint: { |
4274 | unsigned Opc = Lex.getUIntVal(); |
4275 | Type *DestTy = nullptr; |
4276 | Constant *SrcVal; |
4277 | Lex.Lex(); |
4278 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' after constantexpr cast" ) || |
4279 | parseGlobalTypeAndValue(V&: SrcVal) || |
4280 | parseToken(T: lltok::kw_to, ErrMsg: "expected 'to' in constantexpr cast" ) || |
4281 | parseType(Result&: DestTy) || |
4282 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' at end of constantexpr cast" )) |
4283 | return true; |
4284 | if (!CastInst::castIsValid(op: (Instruction::CastOps)Opc, S: SrcVal, DstTy: DestTy)) |
4285 | return error(L: ID.Loc, Msg: "invalid cast opcode for cast from '" + |
4286 | getTypeString(T: SrcVal->getType()) + "' to '" + |
4287 | getTypeString(T: DestTy) + "'" ); |
4288 | ID.ConstantVal = ConstantExpr::getCast(ops: (Instruction::CastOps)Opc, |
4289 | C: SrcVal, Ty: DestTy); |
4290 | ID.Kind = ValID::t_Constant; |
4291 | return false; |
4292 | } |
4293 | case lltok::kw_extractvalue: |
4294 | return error(L: ID.Loc, Msg: "extractvalue constexprs are no longer supported" ); |
4295 | case lltok::kw_insertvalue: |
4296 | return error(L: ID.Loc, Msg: "insertvalue constexprs are no longer supported" ); |
4297 | case lltok::kw_udiv: |
4298 | return error(L: ID.Loc, Msg: "udiv constexprs are no longer supported" ); |
4299 | case lltok::kw_sdiv: |
4300 | return error(L: ID.Loc, Msg: "sdiv constexprs are no longer supported" ); |
4301 | case lltok::kw_urem: |
4302 | return error(L: ID.Loc, Msg: "urem constexprs are no longer supported" ); |
4303 | case lltok::kw_srem: |
4304 | return error(L: ID.Loc, Msg: "srem constexprs are no longer supported" ); |
4305 | case lltok::kw_fadd: |
4306 | return error(L: ID.Loc, Msg: "fadd constexprs are no longer supported" ); |
4307 | case lltok::kw_fsub: |
4308 | return error(L: ID.Loc, Msg: "fsub constexprs are no longer supported" ); |
4309 | case lltok::kw_fmul: |
4310 | return error(L: ID.Loc, Msg: "fmul constexprs are no longer supported" ); |
4311 | case lltok::kw_fdiv: |
4312 | return error(L: ID.Loc, Msg: "fdiv constexprs are no longer supported" ); |
4313 | case lltok::kw_frem: |
4314 | return error(L: ID.Loc, Msg: "frem constexprs are no longer supported" ); |
4315 | case lltok::kw_and: |
4316 | return error(L: ID.Loc, Msg: "and constexprs are no longer supported" ); |
4317 | case lltok::kw_or: |
4318 | return error(L: ID.Loc, Msg: "or constexprs are no longer supported" ); |
4319 | case lltok::kw_lshr: |
4320 | return error(L: ID.Loc, Msg: "lshr constexprs are no longer supported" ); |
4321 | case lltok::kw_ashr: |
4322 | return error(L: ID.Loc, Msg: "ashr constexprs are no longer supported" ); |
4323 | case lltok::kw_shl: |
4324 | return error(L: ID.Loc, Msg: "shl constexprs are no longer supported" ); |
4325 | case lltok::kw_mul: |
4326 | return error(L: ID.Loc, Msg: "mul constexprs are no longer supported" ); |
4327 | case lltok::kw_fneg: |
4328 | return error(L: ID.Loc, Msg: "fneg constexprs are no longer supported" ); |
4329 | case lltok::kw_select: |
4330 | return error(L: ID.Loc, Msg: "select constexprs are no longer supported" ); |
4331 | case lltok::kw_zext: |
4332 | return error(L: ID.Loc, Msg: "zext constexprs are no longer supported" ); |
4333 | case lltok::kw_sext: |
4334 | return error(L: ID.Loc, Msg: "sext constexprs are no longer supported" ); |
4335 | case lltok::kw_fptrunc: |
4336 | return error(L: ID.Loc, Msg: "fptrunc constexprs are no longer supported" ); |
4337 | case lltok::kw_fpext: |
4338 | return error(L: ID.Loc, Msg: "fpext constexprs are no longer supported" ); |
4339 | case lltok::kw_uitofp: |
4340 | return error(L: ID.Loc, Msg: "uitofp constexprs are no longer supported" ); |
4341 | case lltok::kw_sitofp: |
4342 | return error(L: ID.Loc, Msg: "sitofp constexprs are no longer supported" ); |
4343 | case lltok::kw_fptoui: |
4344 | return error(L: ID.Loc, Msg: "fptoui constexprs are no longer supported" ); |
4345 | case lltok::kw_fptosi: |
4346 | return error(L: ID.Loc, Msg: "fptosi constexprs are no longer supported" ); |
4347 | case lltok::kw_icmp: |
4348 | return error(L: ID.Loc, Msg: "icmp constexprs are no longer supported" ); |
4349 | case lltok::kw_fcmp: |
4350 | return error(L: ID.Loc, Msg: "fcmp constexprs are no longer supported" ); |
4351 | |
4352 | // Binary Operators. |
4353 | case lltok::kw_add: |
4354 | case lltok::kw_sub: |
4355 | case lltok::kw_xor: { |
4356 | bool NUW = false; |
4357 | bool NSW = false; |
4358 | unsigned Opc = Lex.getUIntVal(); |
4359 | Constant *Val0, *Val1; |
4360 | Lex.Lex(); |
4361 | if (Opc == Instruction::Add || Opc == Instruction::Sub || |
4362 | Opc == Instruction::Mul) { |
4363 | if (EatIfPresent(T: lltok::kw_nuw)) |
4364 | NUW = true; |
4365 | if (EatIfPresent(T: lltok::kw_nsw)) { |
4366 | NSW = true; |
4367 | if (EatIfPresent(T: lltok::kw_nuw)) |
4368 | NUW = true; |
4369 | } |
4370 | } |
4371 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in binary constantexpr" ) || |
4372 | parseGlobalTypeAndValue(V&: Val0) || |
4373 | parseToken(T: lltok::comma, ErrMsg: "expected comma in binary constantexpr" ) || |
4374 | parseGlobalTypeAndValue(V&: Val1) || |
4375 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' in binary constantexpr" )) |
4376 | return true; |
4377 | if (Val0->getType() != Val1->getType()) |
4378 | return error(L: ID.Loc, Msg: "operands of constexpr must have same type" ); |
4379 | // Check that the type is valid for the operator. |
4380 | if (!Val0->getType()->isIntOrIntVectorTy()) |
4381 | return error(L: ID.Loc, |
4382 | Msg: "constexpr requires integer or integer vector operands" ); |
4383 | unsigned Flags = 0; |
4384 | if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap; |
4385 | if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap; |
4386 | ID.ConstantVal = ConstantExpr::get(Opcode: Opc, C1: Val0, C2: Val1, Flags); |
4387 | ID.Kind = ValID::t_Constant; |
4388 | return false; |
4389 | } |
4390 | |
4391 | case lltok::kw_splat: { |
4392 | Lex.Lex(); |
4393 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' after vector splat" )) |
4394 | return true; |
4395 | Constant *C; |
4396 | if (parseGlobalTypeAndValue(V&: C)) |
4397 | return true; |
4398 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' at end of vector splat" )) |
4399 | return true; |
4400 | |
4401 | ID.ConstantVal = C; |
4402 | ID.Kind = ValID::t_ConstantSplat; |
4403 | return false; |
4404 | } |
4405 | |
4406 | case lltok::kw_getelementptr: |
4407 | case lltok::kw_shufflevector: |
4408 | case lltok::kw_insertelement: |
4409 | case lltok::kw_extractelement: { |
4410 | unsigned Opc = Lex.getUIntVal(); |
4411 | SmallVector<Constant*, 16> Elts; |
4412 | GEPNoWrapFlags NW; |
4413 | bool HasInRange = false; |
4414 | APSInt InRangeStart; |
4415 | APSInt InRangeEnd; |
4416 | Type *Ty; |
4417 | Lex.Lex(); |
4418 | |
4419 | if (Opc == Instruction::GetElementPtr) { |
4420 | while (true) { |
4421 | if (EatIfPresent(T: lltok::kw_inbounds)) |
4422 | NW |= GEPNoWrapFlags::inBounds(); |
4423 | else if (EatIfPresent(T: lltok::kw_nusw)) |
4424 | NW |= GEPNoWrapFlags::noUnsignedSignedWrap(); |
4425 | else if (EatIfPresent(T: lltok::kw_nuw)) |
4426 | NW |= GEPNoWrapFlags::noUnsignedWrap(); |
4427 | else |
4428 | break; |
4429 | } |
4430 | |
4431 | if (EatIfPresent(T: lltok::kw_inrange)) { |
4432 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '('" )) |
4433 | return true; |
4434 | if (Lex.getKind() != lltok::APSInt) |
4435 | return tokError(Msg: "expected integer" ); |
4436 | InRangeStart = Lex.getAPSIntVal(); |
4437 | Lex.Lex(); |
4438 | if (parseToken(T: lltok::comma, ErrMsg: "expected ','" )) |
4439 | return true; |
4440 | if (Lex.getKind() != lltok::APSInt) |
4441 | return tokError(Msg: "expected integer" ); |
4442 | InRangeEnd = Lex.getAPSIntVal(); |
4443 | Lex.Lex(); |
4444 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')'" )) |
4445 | return true; |
4446 | HasInRange = true; |
4447 | } |
4448 | } |
4449 | |
4450 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in constantexpr" )) |
4451 | return true; |
4452 | |
4453 | if (Opc == Instruction::GetElementPtr) { |
4454 | if (parseType(Result&: Ty) || |
4455 | parseToken(T: lltok::comma, ErrMsg: "expected comma after getelementptr's type" )) |
4456 | return true; |
4457 | } |
4458 | |
4459 | if (parseGlobalValueVector(Elts) || |
4460 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' in constantexpr" )) |
4461 | return true; |
4462 | |
4463 | if (Opc == Instruction::GetElementPtr) { |
4464 | if (Elts.size() == 0 || |
4465 | !Elts[0]->getType()->isPtrOrPtrVectorTy()) |
4466 | return error(L: ID.Loc, Msg: "base of getelementptr must be a pointer" ); |
4467 | |
4468 | Type *BaseType = Elts[0]->getType(); |
4469 | std::optional<ConstantRange> InRange; |
4470 | if (HasInRange) { |
4471 | unsigned IndexWidth = |
4472 | M->getDataLayout().getIndexTypeSizeInBits(Ty: BaseType); |
4473 | InRangeStart = InRangeStart.extOrTrunc(width: IndexWidth); |
4474 | InRangeEnd = InRangeEnd.extOrTrunc(width: IndexWidth); |
4475 | if (InRangeStart.sge(RHS: InRangeEnd)) |
4476 | return error(L: ID.Loc, Msg: "expected end to be larger than start" ); |
4477 | InRange = ConstantRange::getNonEmpty(Lower: InRangeStart, Upper: InRangeEnd); |
4478 | } |
4479 | |
4480 | unsigned GEPWidth = |
4481 | BaseType->isVectorTy() |
4482 | ? cast<FixedVectorType>(Val: BaseType)->getNumElements() |
4483 | : 0; |
4484 | |
4485 | ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); |
4486 | for (Constant *Val : Indices) { |
4487 | Type *ValTy = Val->getType(); |
4488 | if (!ValTy->isIntOrIntVectorTy()) |
4489 | return error(L: ID.Loc, Msg: "getelementptr index must be an integer" ); |
4490 | if (auto *ValVTy = dyn_cast<VectorType>(Val: ValTy)) { |
4491 | unsigned ValNumEl = cast<FixedVectorType>(Val: ValVTy)->getNumElements(); |
4492 | if (GEPWidth && (ValNumEl != GEPWidth)) |
4493 | return error( |
4494 | L: ID.Loc, |
4495 | Msg: "getelementptr vector index has a wrong number of elements" ); |
4496 | // GEPWidth may have been unknown because the base is a scalar, |
4497 | // but it is known now. |
4498 | GEPWidth = ValNumEl; |
4499 | } |
4500 | } |
4501 | |
4502 | SmallPtrSet<Type*, 4> Visited; |
4503 | if (!Indices.empty() && !Ty->isSized(Visited: &Visited)) |
4504 | return error(L: ID.Loc, Msg: "base element of getelementptr must be sized" ); |
4505 | |
4506 | if (!GetElementPtrInst::getIndexedType(Ty, IdxList: Indices)) |
4507 | return error(L: ID.Loc, Msg: "invalid getelementptr indices" ); |
4508 | |
4509 | ID.ConstantVal = |
4510 | ConstantExpr::getGetElementPtr(Ty, C: Elts[0], IdxList: Indices, NW, InRange); |
4511 | } else if (Opc == Instruction::ShuffleVector) { |
4512 | if (Elts.size() != 3) |
4513 | return error(L: ID.Loc, Msg: "expected three operands to shufflevector" ); |
4514 | if (!ShuffleVectorInst::isValidOperands(V1: Elts[0], V2: Elts[1], Mask: Elts[2])) |
4515 | return error(L: ID.Loc, Msg: "invalid operands to shufflevector" ); |
4516 | SmallVector<int, 16> Mask; |
4517 | ShuffleVectorInst::getShuffleMask(Mask: cast<Constant>(Val: Elts[2]), Result&: Mask); |
4518 | ID.ConstantVal = ConstantExpr::getShuffleVector(V1: Elts[0], V2: Elts[1], Mask); |
4519 | } else if (Opc == Instruction::ExtractElement) { |
4520 | if (Elts.size() != 2) |
4521 | return error(L: ID.Loc, Msg: "expected two operands to extractelement" ); |
4522 | if (!ExtractElementInst::isValidOperands(Vec: Elts[0], Idx: Elts[1])) |
4523 | return error(L: ID.Loc, Msg: "invalid extractelement operands" ); |
4524 | ID.ConstantVal = ConstantExpr::getExtractElement(Vec: Elts[0], Idx: Elts[1]); |
4525 | } else { |
4526 | assert(Opc == Instruction::InsertElement && "Unknown opcode" ); |
4527 | if (Elts.size() != 3) |
4528 | return error(L: ID.Loc, Msg: "expected three operands to insertelement" ); |
4529 | if (!InsertElementInst::isValidOperands(Vec: Elts[0], NewElt: Elts[1], Idx: Elts[2])) |
4530 | return error(L: ID.Loc, Msg: "invalid insertelement operands" ); |
4531 | ID.ConstantVal = |
4532 | ConstantExpr::getInsertElement(Vec: Elts[0], Elt: Elts[1],Idx: Elts[2]); |
4533 | } |
4534 | |
4535 | ID.Kind = ValID::t_Constant; |
4536 | return false; |
4537 | } |
4538 | } |
4539 | |
4540 | Lex.Lex(); |
4541 | return false; |
4542 | } |
4543 | |
4544 | /// parseGlobalValue - parse a global value with the specified type. |
4545 | bool LLParser::parseGlobalValue(Type *Ty, Constant *&C) { |
4546 | C = nullptr; |
4547 | ValID ID; |
4548 | Value *V = nullptr; |
4549 | bool Parsed = parseValID(ID, /*PFS=*/nullptr, ExpectedTy: Ty) || |
4550 | convertValIDToValue(Ty, ID, V, PFS: nullptr); |
4551 | if (V && !(C = dyn_cast<Constant>(Val: V))) |
4552 | return error(L: ID.Loc, Msg: "global values must be constants" ); |
4553 | return Parsed; |
4554 | } |
4555 | |
4556 | bool LLParser::parseGlobalTypeAndValue(Constant *&V) { |
4557 | Type *Ty = nullptr; |
4558 | return parseType(Result&: Ty) || parseGlobalValue(Ty, C&: V); |
4559 | } |
4560 | |
4561 | bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) { |
4562 | C = nullptr; |
4563 | |
4564 | LocTy KwLoc = Lex.getLoc(); |
4565 | if (!EatIfPresent(T: lltok::kw_comdat)) |
4566 | return false; |
4567 | |
4568 | if (EatIfPresent(T: lltok::lparen)) { |
4569 | if (Lex.getKind() != lltok::ComdatVar) |
4570 | return tokError(Msg: "expected comdat variable" ); |
4571 | C = getComdat(Name: Lex.getStrVal(), Loc: Lex.getLoc()); |
4572 | Lex.Lex(); |
4573 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' after comdat var" )) |
4574 | return true; |
4575 | } else { |
4576 | if (GlobalName.empty()) |
4577 | return tokError(Msg: "comdat cannot be unnamed" ); |
4578 | C = getComdat(Name: std::string(GlobalName), Loc: KwLoc); |
4579 | } |
4580 | |
4581 | return false; |
4582 | } |
4583 | |
4584 | /// parseGlobalValueVector |
4585 | /// ::= /*empty*/ |
4586 | /// ::= TypeAndValue (',' TypeAndValue)* |
4587 | bool LLParser::parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { |
4588 | // Empty list. |
4589 | if (Lex.getKind() == lltok::rbrace || |
4590 | Lex.getKind() == lltok::rsquare || |
4591 | Lex.getKind() == lltok::greater || |
4592 | Lex.getKind() == lltok::rparen) |
4593 | return false; |
4594 | |
4595 | do { |
4596 | // Let the caller deal with inrange. |
4597 | if (Lex.getKind() == lltok::kw_inrange) |
4598 | return false; |
4599 | |
4600 | Constant *C; |
4601 | if (parseGlobalTypeAndValue(V&: C)) |
4602 | return true; |
4603 | Elts.push_back(Elt: C); |
4604 | } while (EatIfPresent(T: lltok::comma)); |
4605 | |
4606 | return false; |
4607 | } |
4608 | |
4609 | bool LLParser::parseMDTuple(MDNode *&MD, bool IsDistinct) { |
4610 | SmallVector<Metadata *, 16> Elts; |
4611 | if (parseMDNodeVector(Elts)) |
4612 | return true; |
4613 | |
4614 | MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts); |
4615 | return false; |
4616 | } |
4617 | |
4618 | /// MDNode: |
4619 | /// ::= !{ ... } |
4620 | /// ::= !7 |
4621 | /// ::= !DILocation(...) |
4622 | bool LLParser::parseMDNode(MDNode *&N) { |
4623 | if (Lex.getKind() == lltok::MetadataVar) |
4624 | return parseSpecializedMDNode(N); |
4625 | |
4626 | return parseToken(T: lltok::exclaim, ErrMsg: "expected '!' here" ) || parseMDNodeTail(N); |
4627 | } |
4628 | |
4629 | bool LLParser::parseMDNodeTail(MDNode *&N) { |
4630 | // !{ ... } |
4631 | if (Lex.getKind() == lltok::lbrace) |
4632 | return parseMDTuple(MD&: N); |
4633 | |
4634 | // !42 |
4635 | return parseMDNodeID(Result&: N); |
4636 | } |
4637 | |
4638 | namespace { |
4639 | |
4640 | /// Structure to represent an optional metadata field. |
4641 | template <class FieldTy> struct MDFieldImpl { |
4642 | typedef MDFieldImpl ImplTy; |
4643 | FieldTy Val; |
4644 | bool Seen; |
4645 | |
4646 | void assign(FieldTy Val) { |
4647 | Seen = true; |
4648 | this->Val = std::move(Val); |
4649 | } |
4650 | |
4651 | explicit MDFieldImpl(FieldTy Default) |
4652 | : Val(std::move(Default)), Seen(false) {} |
4653 | }; |
4654 | |
4655 | /// Structure to represent an optional metadata field that |
4656 | /// can be of either type (A or B) and encapsulates the |
4657 | /// MD<typeofA>Field and MD<typeofB>Field structs, so not |
4658 | /// to reimplement the specifics for representing each Field. |
4659 | template <class FieldTypeA, class FieldTypeB> struct MDEitherFieldImpl { |
4660 | typedef MDEitherFieldImpl<FieldTypeA, FieldTypeB> ImplTy; |
4661 | FieldTypeA A; |
4662 | FieldTypeB B; |
4663 | bool Seen; |
4664 | |
4665 | enum { |
4666 | IsInvalid = 0, |
4667 | IsTypeA = 1, |
4668 | IsTypeB = 2 |
4669 | } WhatIs; |
4670 | |
4671 | void assign(FieldTypeA A) { |
4672 | Seen = true; |
4673 | this->A = std::move(A); |
4674 | WhatIs = IsTypeA; |
4675 | } |
4676 | |
4677 | void assign(FieldTypeB B) { |
4678 | Seen = true; |
4679 | this->B = std::move(B); |
4680 | WhatIs = IsTypeB; |
4681 | } |
4682 | |
4683 | explicit MDEitherFieldImpl(FieldTypeA DefaultA, FieldTypeB DefaultB) |
4684 | : A(std::move(DefaultA)), B(std::move(DefaultB)), Seen(false), |
4685 | WhatIs(IsInvalid) {} |
4686 | }; |
4687 | |
4688 | struct MDUnsignedField : public MDFieldImpl<uint64_t> { |
4689 | uint64_t Max; |
4690 | |
4691 | MDUnsignedField(uint64_t Default = 0, uint64_t Max = UINT64_MAX) |
4692 | : ImplTy(Default), Max(Max) {} |
4693 | }; |
4694 | |
4695 | struct LineField : public MDUnsignedField { |
4696 | LineField() : MDUnsignedField(0, UINT32_MAX) {} |
4697 | }; |
4698 | |
4699 | struct ColumnField : public MDUnsignedField { |
4700 | ColumnField() : MDUnsignedField(0, UINT16_MAX) {} |
4701 | }; |
4702 | |
4703 | struct DwarfTagField : public MDUnsignedField { |
4704 | DwarfTagField() : MDUnsignedField(0, dwarf::DW_TAG_hi_user) {} |
4705 | DwarfTagField(dwarf::Tag DefaultTag) |
4706 | : MDUnsignedField(DefaultTag, dwarf::DW_TAG_hi_user) {} |
4707 | }; |
4708 | |
4709 | struct DwarfMacinfoTypeField : public MDUnsignedField { |
4710 | DwarfMacinfoTypeField() : MDUnsignedField(0, dwarf::DW_MACINFO_vendor_ext) {} |
4711 | DwarfMacinfoTypeField(dwarf::MacinfoRecordType DefaultType) |
4712 | : MDUnsignedField(DefaultType, dwarf::DW_MACINFO_vendor_ext) {} |
4713 | }; |
4714 | |
4715 | struct DwarfAttEncodingField : public MDUnsignedField { |
4716 | DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {} |
4717 | }; |
4718 | |
4719 | struct DwarfVirtualityField : public MDUnsignedField { |
4720 | DwarfVirtualityField() : MDUnsignedField(0, dwarf::DW_VIRTUALITY_max) {} |
4721 | }; |
4722 | |
4723 | struct DwarfLangField : public MDUnsignedField { |
4724 | DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {} |
4725 | }; |
4726 | |
4727 | struct DwarfCCField : public MDUnsignedField { |
4728 | DwarfCCField() : MDUnsignedField(0, dwarf::DW_CC_hi_user) {} |
4729 | }; |
4730 | |
4731 | struct DwarfEnumKindField : public MDUnsignedField { |
4732 | DwarfEnumKindField() |
4733 | : MDUnsignedField(dwarf::DW_APPLE_ENUM_KIND_invalid, |
4734 | dwarf::DW_APPLE_ENUM_KIND_max) {} |
4735 | }; |
4736 | |
4737 | struct EmissionKindField : public MDUnsignedField { |
4738 | EmissionKindField() : MDUnsignedField(0, DICompileUnit::LastEmissionKind) {} |
4739 | }; |
4740 | |
4741 | struct FixedPointKindField : public MDUnsignedField { |
4742 | FixedPointKindField() |
4743 | : MDUnsignedField(0, DIFixedPointType::LastFixedPointKind) {} |
4744 | }; |
4745 | |
4746 | struct NameTableKindField : public MDUnsignedField { |
4747 | NameTableKindField() |
4748 | : MDUnsignedField( |
4749 | 0, (unsigned) |
4750 | DICompileUnit::DebugNameTableKind::LastDebugNameTableKind) {} |
4751 | }; |
4752 | |
4753 | struct DIFlagField : public MDFieldImpl<DINode::DIFlags> { |
4754 | DIFlagField() : MDFieldImpl(DINode::FlagZero) {} |
4755 | }; |
4756 | |
4757 | struct DISPFlagField : public MDFieldImpl<DISubprogram::DISPFlags> { |
4758 | DISPFlagField() : MDFieldImpl(DISubprogram::SPFlagZero) {} |
4759 | }; |
4760 | |
4761 | struct MDAPSIntField : public MDFieldImpl<APSInt> { |
4762 | MDAPSIntField() : ImplTy(APSInt()) {} |
4763 | }; |
4764 | |
4765 | struct MDSignedField : public MDFieldImpl<int64_t> { |
4766 | int64_t Min = INT64_MIN; |
4767 | int64_t Max = INT64_MAX; |
4768 | |
4769 | MDSignedField(int64_t Default = 0) |
4770 | : ImplTy(Default) {} |
4771 | MDSignedField(int64_t Default, int64_t Min, int64_t Max) |
4772 | : ImplTy(Default), Min(Min), Max(Max) {} |
4773 | }; |
4774 | |
4775 | struct MDBoolField : public MDFieldImpl<bool> { |
4776 | MDBoolField(bool Default = false) : ImplTy(Default) {} |
4777 | }; |
4778 | |
4779 | struct MDField : public MDFieldImpl<Metadata *> { |
4780 | bool AllowNull; |
4781 | |
4782 | MDField(bool AllowNull = true) : ImplTy(nullptr), AllowNull(AllowNull) {} |
4783 | }; |
4784 | |
4785 | struct MDStringField : public MDFieldImpl<MDString *> { |
4786 | bool AllowEmpty; |
4787 | MDStringField(bool AllowEmpty = true) |
4788 | : ImplTy(nullptr), AllowEmpty(AllowEmpty) {} |
4789 | }; |
4790 | |
4791 | struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> { |
4792 | MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {} |
4793 | }; |
4794 | |
4795 | struct ChecksumKindField : public MDFieldImpl<DIFile::ChecksumKind> { |
4796 | ChecksumKindField(DIFile::ChecksumKind CSKind) : ImplTy(CSKind) {} |
4797 | }; |
4798 | |
4799 | struct MDSignedOrMDField : MDEitherFieldImpl<MDSignedField, MDField> { |
4800 | MDSignedOrMDField(int64_t Default = 0, bool AllowNull = true) |
4801 | : ImplTy(MDSignedField(Default), MDField(AllowNull)) {} |
4802 | |
4803 | MDSignedOrMDField(int64_t Default, int64_t Min, int64_t Max, |
4804 | bool AllowNull = true) |
4805 | : ImplTy(MDSignedField(Default, Min, Max), MDField(AllowNull)) {} |
4806 | |
4807 | bool isMDSignedField() const { return WhatIs == IsTypeA; } |
4808 | bool isMDField() const { return WhatIs == IsTypeB; } |
4809 | int64_t getMDSignedValue() const { |
4810 | assert(isMDSignedField() && "Wrong field type" ); |
4811 | return A.Val; |
4812 | } |
4813 | Metadata *getMDFieldValue() const { |
4814 | assert(isMDField() && "Wrong field type" ); |
4815 | return B.Val; |
4816 | } |
4817 | }; |
4818 | |
4819 | struct MDUnsignedOrMDField : MDEitherFieldImpl<MDUnsignedField, MDField> { |
4820 | MDUnsignedOrMDField(uint64_t Default = 0, bool AllowNull = true) |
4821 | : ImplTy(MDUnsignedField(Default), MDField(AllowNull)) {} |
4822 | |
4823 | MDUnsignedOrMDField(uint64_t Default, uint64_t Max, bool AllowNull = true) |
4824 | : ImplTy(MDUnsignedField(Default, Max), MDField(AllowNull)) {} |
4825 | |
4826 | bool isMDUnsignedField() const { return WhatIs == IsTypeA; } |
4827 | bool isMDField() const { return WhatIs == IsTypeB; } |
4828 | uint64_t getMDUnsignedValue() const { |
4829 | assert(isMDUnsignedField() && "Wrong field type" ); |
4830 | return A.Val; |
4831 | } |
4832 | Metadata *getMDFieldValue() const { |
4833 | assert(isMDField() && "Wrong field type" ); |
4834 | return B.Val; |
4835 | } |
4836 | |
4837 | Metadata *getValueAsMetadata(LLVMContext &Context) const { |
4838 | if (isMDUnsignedField()) |
4839 | return ConstantAsMetadata::get( |
4840 | C: ConstantInt::get(Ty: Type::getInt64Ty(C&: Context), V: getMDUnsignedValue())); |
4841 | if (isMDField()) |
4842 | return getMDFieldValue(); |
4843 | return nullptr; |
4844 | } |
4845 | }; |
4846 | |
4847 | } // end anonymous namespace |
4848 | |
4849 | namespace llvm { |
4850 | |
4851 | template <> |
4852 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDAPSIntField &Result) { |
4853 | if (Lex.getKind() != lltok::APSInt) |
4854 | return tokError(Msg: "expected integer" ); |
4855 | |
4856 | Result.assign(Val: Lex.getAPSIntVal()); |
4857 | Lex.Lex(); |
4858 | return false; |
4859 | } |
4860 | |
4861 | template <> |
4862 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
4863 | MDUnsignedField &Result) { |
4864 | if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) |
4865 | return tokError(Msg: "expected unsigned integer" ); |
4866 | |
4867 | auto &U = Lex.getAPSIntVal(); |
4868 | if (U.ugt(RHS: Result.Max)) |
4869 | return tokError(Msg: "value for '" + Name + "' too large, limit is " + |
4870 | Twine(Result.Max)); |
4871 | Result.assign(Val: U.getZExtValue()); |
4872 | assert(Result.Val <= Result.Max && "Expected value in range" ); |
4873 | Lex.Lex(); |
4874 | return false; |
4875 | } |
4876 | |
4877 | template <> |
4878 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, LineField &Result) { |
4879 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4880 | } |
4881 | template <> |
4882 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, ColumnField &Result) { |
4883 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4884 | } |
4885 | |
4886 | template <> |
4887 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfTagField &Result) { |
4888 | if (Lex.getKind() == lltok::APSInt) |
4889 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4890 | |
4891 | if (Lex.getKind() != lltok::DwarfTag) |
4892 | return tokError(Msg: "expected DWARF tag" ); |
4893 | |
4894 | unsigned Tag = dwarf::getTag(TagString: Lex.getStrVal()); |
4895 | if (Tag == dwarf::DW_TAG_invalid) |
4896 | return tokError(Msg: "invalid DWARF tag" + Twine(" '" ) + Lex.getStrVal() + "'" ); |
4897 | assert(Tag <= Result.Max && "Expected valid DWARF tag" ); |
4898 | |
4899 | Result.assign(Val: Tag); |
4900 | Lex.Lex(); |
4901 | return false; |
4902 | } |
4903 | |
4904 | template <> |
4905 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
4906 | DwarfMacinfoTypeField &Result) { |
4907 | if (Lex.getKind() == lltok::APSInt) |
4908 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4909 | |
4910 | if (Lex.getKind() != lltok::DwarfMacinfo) |
4911 | return tokError(Msg: "expected DWARF macinfo type" ); |
4912 | |
4913 | unsigned Macinfo = dwarf::getMacinfo(MacinfoString: Lex.getStrVal()); |
4914 | if (Macinfo == dwarf::DW_MACINFO_invalid) |
4915 | return tokError(Msg: "invalid DWARF macinfo type" + Twine(" '" ) + |
4916 | Lex.getStrVal() + "'" ); |
4917 | assert(Macinfo <= Result.Max && "Expected valid DWARF macinfo type" ); |
4918 | |
4919 | Result.assign(Val: Macinfo); |
4920 | Lex.Lex(); |
4921 | return false; |
4922 | } |
4923 | |
4924 | template <> |
4925 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
4926 | DwarfVirtualityField &Result) { |
4927 | if (Lex.getKind() == lltok::APSInt) |
4928 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4929 | |
4930 | if (Lex.getKind() != lltok::DwarfVirtuality) |
4931 | return tokError(Msg: "expected DWARF virtuality code" ); |
4932 | |
4933 | unsigned Virtuality = dwarf::getVirtuality(VirtualityString: Lex.getStrVal()); |
4934 | if (Virtuality == dwarf::DW_VIRTUALITY_invalid) |
4935 | return tokError(Msg: "invalid DWARF virtuality code" + Twine(" '" ) + |
4936 | Lex.getStrVal() + "'" ); |
4937 | assert(Virtuality <= Result.Max && "Expected valid DWARF virtuality code" ); |
4938 | Result.assign(Val: Virtuality); |
4939 | Lex.Lex(); |
4940 | return false; |
4941 | } |
4942 | |
4943 | template <> |
4944 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
4945 | DwarfEnumKindField &Result) { |
4946 | if (Lex.getKind() == lltok::APSInt) |
4947 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4948 | |
4949 | if (Lex.getKind() != lltok::DwarfEnumKind) |
4950 | return tokError(Msg: "expected DWARF enum kind code" ); |
4951 | |
4952 | unsigned EnumKind = dwarf::getEnumKind(EnumKindString: Lex.getStrVal()); |
4953 | if (EnumKind == dwarf::DW_APPLE_ENUM_KIND_invalid) |
4954 | return tokError(Msg: "invalid DWARF enum kind code" + Twine(" '" ) + |
4955 | Lex.getStrVal() + "'" ); |
4956 | assert(EnumKind <= Result.Max && "Expected valid DWARF enum kind code" ); |
4957 | Result.assign(Val: EnumKind); |
4958 | Lex.Lex(); |
4959 | return false; |
4960 | } |
4961 | |
4962 | template <> |
4963 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfLangField &Result) { |
4964 | if (Lex.getKind() == lltok::APSInt) |
4965 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4966 | |
4967 | if (Lex.getKind() != lltok::DwarfLang) |
4968 | return tokError(Msg: "expected DWARF language" ); |
4969 | |
4970 | unsigned Lang = dwarf::getLanguage(LanguageString: Lex.getStrVal()); |
4971 | if (!Lang) |
4972 | return tokError(Msg: "invalid DWARF language" + Twine(" '" ) + Lex.getStrVal() + |
4973 | "'" ); |
4974 | assert(Lang <= Result.Max && "Expected valid DWARF language" ); |
4975 | Result.assign(Val: Lang); |
4976 | Lex.Lex(); |
4977 | return false; |
4978 | } |
4979 | |
4980 | template <> |
4981 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, DwarfCCField &Result) { |
4982 | if (Lex.getKind() == lltok::APSInt) |
4983 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
4984 | |
4985 | if (Lex.getKind() != lltok::DwarfCC) |
4986 | return tokError(Msg: "expected DWARF calling convention" ); |
4987 | |
4988 | unsigned CC = dwarf::getCallingConvention(LanguageString: Lex.getStrVal()); |
4989 | if (!CC) |
4990 | return tokError(Msg: "invalid DWARF calling convention" + Twine(" '" ) + |
4991 | Lex.getStrVal() + "'" ); |
4992 | assert(CC <= Result.Max && "Expected valid DWARF calling convention" ); |
4993 | Result.assign(Val: CC); |
4994 | Lex.Lex(); |
4995 | return false; |
4996 | } |
4997 | |
4998 | template <> |
4999 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5000 | EmissionKindField &Result) { |
5001 | if (Lex.getKind() == lltok::APSInt) |
5002 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
5003 | |
5004 | if (Lex.getKind() != lltok::EmissionKind) |
5005 | return tokError(Msg: "expected emission kind" ); |
5006 | |
5007 | auto Kind = DICompileUnit::getEmissionKind(Str: Lex.getStrVal()); |
5008 | if (!Kind) |
5009 | return tokError(Msg: "invalid emission kind" + Twine(" '" ) + Lex.getStrVal() + |
5010 | "'" ); |
5011 | assert(*Kind <= Result.Max && "Expected valid emission kind" ); |
5012 | Result.assign(Val: *Kind); |
5013 | Lex.Lex(); |
5014 | return false; |
5015 | } |
5016 | |
5017 | template <> |
5018 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5019 | FixedPointKindField &Result) { |
5020 | if (Lex.getKind() == lltok::APSInt) |
5021 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
5022 | |
5023 | if (Lex.getKind() != lltok::FixedPointKind) |
5024 | return tokError(Msg: "expected fixed-point kind" ); |
5025 | |
5026 | auto Kind = DIFixedPointType::getFixedPointKind(Str: Lex.getStrVal()); |
5027 | if (!Kind) |
5028 | return tokError(Msg: "invalid fixed-point kind" + Twine(" '" ) + Lex.getStrVal() + |
5029 | "'" ); |
5030 | assert(*Kind <= Result.Max && "Expected valid fixed-point kind" ); |
5031 | Result.assign(Val: *Kind); |
5032 | Lex.Lex(); |
5033 | return false; |
5034 | } |
5035 | |
5036 | template <> |
5037 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5038 | NameTableKindField &Result) { |
5039 | if (Lex.getKind() == lltok::APSInt) |
5040 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
5041 | |
5042 | if (Lex.getKind() != lltok::NameTableKind) |
5043 | return tokError(Msg: "expected nameTable kind" ); |
5044 | |
5045 | auto Kind = DICompileUnit::getNameTableKind(Str: Lex.getStrVal()); |
5046 | if (!Kind) |
5047 | return tokError(Msg: "invalid nameTable kind" + Twine(" '" ) + Lex.getStrVal() + |
5048 | "'" ); |
5049 | assert(((unsigned)*Kind) <= Result.Max && "Expected valid nameTable kind" ); |
5050 | Result.assign(Val: (unsigned)*Kind); |
5051 | Lex.Lex(); |
5052 | return false; |
5053 | } |
5054 | |
5055 | template <> |
5056 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5057 | DwarfAttEncodingField &Result) { |
5058 | if (Lex.getKind() == lltok::APSInt) |
5059 | return parseMDField(Loc, Name, Result&: static_cast<MDUnsignedField &>(Result)); |
5060 | |
5061 | if (Lex.getKind() != lltok::DwarfAttEncoding) |
5062 | return tokError(Msg: "expected DWARF type attribute encoding" ); |
5063 | |
5064 | unsigned Encoding = dwarf::getAttributeEncoding(EncodingString: Lex.getStrVal()); |
5065 | if (!Encoding) |
5066 | return tokError(Msg: "invalid DWARF type attribute encoding" + Twine(" '" ) + |
5067 | Lex.getStrVal() + "'" ); |
5068 | assert(Encoding <= Result.Max && "Expected valid DWARF language" ); |
5069 | Result.assign(Val: Encoding); |
5070 | Lex.Lex(); |
5071 | return false; |
5072 | } |
5073 | |
5074 | /// DIFlagField |
5075 | /// ::= uint32 |
5076 | /// ::= DIFlagVector |
5077 | /// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic |
5078 | template <> |
5079 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) { |
5080 | |
5081 | // parser for a single flag. |
5082 | auto parseFlag = [&](DINode::DIFlags &Val) { |
5083 | if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) { |
5084 | uint32_t TempVal = static_cast<uint32_t>(Val); |
5085 | bool Res = parseUInt32(Val&: TempVal); |
5086 | Val = static_cast<DINode::DIFlags>(TempVal); |
5087 | return Res; |
5088 | } |
5089 | |
5090 | if (Lex.getKind() != lltok::DIFlag) |
5091 | return tokError(Msg: "expected debug info flag" ); |
5092 | |
5093 | Val = DINode::getFlag(Flag: Lex.getStrVal()); |
5094 | if (!Val) |
5095 | return tokError(Msg: Twine("invalid debug info flag '" ) + Lex.getStrVal() + |
5096 | "'" ); |
5097 | Lex.Lex(); |
5098 | return false; |
5099 | }; |
5100 | |
5101 | // parse the flags and combine them together. |
5102 | DINode::DIFlags Combined = DINode::FlagZero; |
5103 | do { |
5104 | DINode::DIFlags Val; |
5105 | if (parseFlag(Val)) |
5106 | return true; |
5107 | Combined |= Val; |
5108 | } while (EatIfPresent(T: lltok::bar)); |
5109 | |
5110 | Result.assign(Val: Combined); |
5111 | return false; |
5112 | } |
5113 | |
5114 | /// DISPFlagField |
5115 | /// ::= uint32 |
5116 | /// ::= DISPFlagVector |
5117 | /// ::= DISPFlagVector '|' DISPFlag* '|' uint32 |
5118 | template <> |
5119 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, DISPFlagField &Result) { |
5120 | |
5121 | // parser for a single flag. |
5122 | auto parseFlag = [&](DISubprogram::DISPFlags &Val) { |
5123 | if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) { |
5124 | uint32_t TempVal = static_cast<uint32_t>(Val); |
5125 | bool Res = parseUInt32(Val&: TempVal); |
5126 | Val = static_cast<DISubprogram::DISPFlags>(TempVal); |
5127 | return Res; |
5128 | } |
5129 | |
5130 | if (Lex.getKind() != lltok::DISPFlag) |
5131 | return tokError(Msg: "expected debug info flag" ); |
5132 | |
5133 | Val = DISubprogram::getFlag(Flag: Lex.getStrVal()); |
5134 | if (!Val) |
5135 | return tokError(Msg: Twine("invalid subprogram debug info flag '" ) + |
5136 | Lex.getStrVal() + "'" ); |
5137 | Lex.Lex(); |
5138 | return false; |
5139 | }; |
5140 | |
5141 | // parse the flags and combine them together. |
5142 | DISubprogram::DISPFlags Combined = DISubprogram::SPFlagZero; |
5143 | do { |
5144 | DISubprogram::DISPFlags Val; |
5145 | if (parseFlag(Val)) |
5146 | return true; |
5147 | Combined |= Val; |
5148 | } while (EatIfPresent(T: lltok::bar)); |
5149 | |
5150 | Result.assign(Val: Combined); |
5151 | return false; |
5152 | } |
5153 | |
5154 | template <> |
5155 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDSignedField &Result) { |
5156 | if (Lex.getKind() != lltok::APSInt) |
5157 | return tokError(Msg: "expected signed integer" ); |
5158 | |
5159 | auto &S = Lex.getAPSIntVal(); |
5160 | if (S < Result.Min) |
5161 | return tokError(Msg: "value for '" + Name + "' too small, limit is " + |
5162 | Twine(Result.Min)); |
5163 | if (S > Result.Max) |
5164 | return tokError(Msg: "value for '" + Name + "' too large, limit is " + |
5165 | Twine(Result.Max)); |
5166 | Result.assign(Val: S.getExtValue()); |
5167 | assert(Result.Val >= Result.Min && "Expected value in range" ); |
5168 | assert(Result.Val <= Result.Max && "Expected value in range" ); |
5169 | Lex.Lex(); |
5170 | return false; |
5171 | } |
5172 | |
5173 | template <> |
5174 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDBoolField &Result) { |
5175 | switch (Lex.getKind()) { |
5176 | default: |
5177 | return tokError(Msg: "expected 'true' or 'false'" ); |
5178 | case lltok::kw_true: |
5179 | Result.assign(Val: true); |
5180 | break; |
5181 | case lltok::kw_false: |
5182 | Result.assign(Val: false); |
5183 | break; |
5184 | } |
5185 | Lex.Lex(); |
5186 | return false; |
5187 | } |
5188 | |
5189 | template <> |
5190 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDField &Result) { |
5191 | if (Lex.getKind() == lltok::kw_null) { |
5192 | if (!Result.AllowNull) |
5193 | return tokError(Msg: "'" + Name + "' cannot be null" ); |
5194 | Lex.Lex(); |
5195 | Result.assign(Val: nullptr); |
5196 | return false; |
5197 | } |
5198 | |
5199 | Metadata *MD; |
5200 | if (parseMetadata(MD, PFS: nullptr)) |
5201 | return true; |
5202 | |
5203 | Result.assign(Val: MD); |
5204 | return false; |
5205 | } |
5206 | |
5207 | template <> |
5208 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5209 | MDSignedOrMDField &Result) { |
5210 | // Try to parse a signed int. |
5211 | if (Lex.getKind() == lltok::APSInt) { |
5212 | MDSignedField Res = Result.A; |
5213 | if (!parseMDField(Loc, Name, Result&: Res)) { |
5214 | Result.assign(A: Res); |
5215 | return false; |
5216 | } |
5217 | return true; |
5218 | } |
5219 | |
5220 | // Otherwise, try to parse as an MDField. |
5221 | MDField Res = Result.B; |
5222 | if (!parseMDField(Loc, Name, Result&: Res)) { |
5223 | Result.assign(B: Res); |
5224 | return false; |
5225 | } |
5226 | |
5227 | return true; |
5228 | } |
5229 | |
5230 | template <> |
5231 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5232 | MDUnsignedOrMDField &Result) { |
5233 | // Try to parse an unsigned int. |
5234 | if (Lex.getKind() == lltok::APSInt) { |
5235 | MDUnsignedField Res = Result.A; |
5236 | if (!parseMDField(Loc, Name, Result&: Res)) { |
5237 | Result.assign(A: Res); |
5238 | return false; |
5239 | } |
5240 | return true; |
5241 | } |
5242 | |
5243 | // Otherwise, try to parse as an MDField. |
5244 | MDField Res = Result.B; |
5245 | if (!parseMDField(Loc, Name, Result&: Res)) { |
5246 | Result.assign(B: Res); |
5247 | return false; |
5248 | } |
5249 | |
5250 | return true; |
5251 | } |
5252 | |
5253 | template <> |
5254 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDStringField &Result) { |
5255 | LocTy ValueLoc = Lex.getLoc(); |
5256 | std::string S; |
5257 | if (parseStringConstant(Result&: S)) |
5258 | return true; |
5259 | |
5260 | if (!Result.AllowEmpty && S.empty()) |
5261 | return error(L: ValueLoc, Msg: "'" + Name + "' cannot be empty" ); |
5262 | |
5263 | Result.assign(Val: S.empty() ? nullptr : MDString::get(Context, Str: S)); |
5264 | return false; |
5265 | } |
5266 | |
5267 | template <> |
5268 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, MDFieldList &Result) { |
5269 | SmallVector<Metadata *, 4> MDs; |
5270 | if (parseMDNodeVector(Elts&: MDs)) |
5271 | return true; |
5272 | |
5273 | Result.assign(Val: std::move(MDs)); |
5274 | return false; |
5275 | } |
5276 | |
5277 | template <> |
5278 | bool LLParser::parseMDField(LocTy Loc, StringRef Name, |
5279 | ChecksumKindField &Result) { |
5280 | std::optional<DIFile::ChecksumKind> CSKind = |
5281 | DIFile::getChecksumKind(CSKindStr: Lex.getStrVal()); |
5282 | |
5283 | if (Lex.getKind() != lltok::ChecksumKind || !CSKind) |
5284 | return tokError(Msg: "invalid checksum kind" + Twine(" '" ) + Lex.getStrVal() + |
5285 | "'" ); |
5286 | |
5287 | Result.assign(Val: *CSKind); |
5288 | Lex.Lex(); |
5289 | return false; |
5290 | } |
5291 | |
5292 | } // end namespace llvm |
5293 | |
5294 | template <class ParserTy> |
5295 | bool LLParser::parseMDFieldsImplBody(ParserTy ParseField) { |
5296 | do { |
5297 | if (Lex.getKind() != lltok::LabelStr) |
5298 | return tokError(Msg: "expected field label here" ); |
5299 | |
5300 | if (ParseField()) |
5301 | return true; |
5302 | } while (EatIfPresent(T: lltok::comma)); |
5303 | |
5304 | return false; |
5305 | } |
5306 | |
5307 | template <class ParserTy> |
5308 | bool LLParser::parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc) { |
5309 | assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name" ); |
5310 | Lex.Lex(); |
5311 | |
5312 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
5313 | return true; |
5314 | if (Lex.getKind() != lltok::rparen) |
5315 | if (parseMDFieldsImplBody(ParseField)) |
5316 | return true; |
5317 | |
5318 | ClosingLoc = Lex.getLoc(); |
5319 | return parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" ); |
5320 | } |
5321 | |
5322 | template <class FieldTy> |
5323 | bool LLParser::parseMDField(StringRef Name, FieldTy &Result) { |
5324 | if (Result.Seen) |
5325 | return tokError(Msg: "field '" + Name + "' cannot be specified more than once" ); |
5326 | |
5327 | LocTy Loc = Lex.getLoc(); |
5328 | Lex.Lex(); |
5329 | return parseMDField(Loc, Name, Result); |
5330 | } |
5331 | |
5332 | bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct) { |
5333 | assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name" ); |
5334 | |
5335 | #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \ |
5336 | if (Lex.getStrVal() == #CLASS) \ |
5337 | return parse##CLASS(N, IsDistinct); |
5338 | #include "llvm/IR/Metadata.def" |
5339 | |
5340 | return tokError(Msg: "expected metadata type" ); |
5341 | } |
5342 | |
5343 | #define DECLARE_FIELD(NAME, TYPE, INIT) TYPE NAME INIT |
5344 | #define NOP_FIELD(NAME, TYPE, INIT) |
5345 | #define REQUIRE_FIELD(NAME, TYPE, INIT) \ |
5346 | if (!NAME.Seen) \ |
5347 | return error(ClosingLoc, "missing required field '" #NAME "'"); |
5348 | #define PARSE_MD_FIELD(NAME, TYPE, DEFAULT) \ |
5349 | if (Lex.getStrVal() == #NAME) \ |
5350 | return parseMDField(#NAME, NAME); |
5351 | #define PARSE_MD_FIELDS() \ |
5352 | VISIT_MD_FIELDS(DECLARE_FIELD, DECLARE_FIELD) \ |
5353 | do { \ |
5354 | LocTy ClosingLoc; \ |
5355 | if (parseMDFieldsImpl( \ |
5356 | [&]() -> bool { \ |
5357 | VISIT_MD_FIELDS(PARSE_MD_FIELD, PARSE_MD_FIELD) \ |
5358 | return tokError(Twine("invalid field '") + Lex.getStrVal() + \ |
5359 | "'"); \ |
5360 | }, \ |
5361 | ClosingLoc)) \ |
5362 | return true; \ |
5363 | VISIT_MD_FIELDS(NOP_FIELD, REQUIRE_FIELD) \ |
5364 | } while (false) |
5365 | #define GET_OR_DISTINCT(CLASS, ARGS) \ |
5366 | (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS) |
5367 | |
5368 | /// parseDILocationFields: |
5369 | /// ::= !DILocation(line: 43, column: 8, scope: !5, inlinedAt: !6, |
5370 | /// isImplicitCode: true, atomGroup: 1, atomRank: 1) |
5371 | bool LLParser::parseDILocation(MDNode *&Result, bool IsDistinct) { |
5372 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5373 | OPTIONAL(line, LineField, ); \ |
5374 | OPTIONAL(column, ColumnField, ); \ |
5375 | REQUIRED(scope, MDField, (/* AllowNull */ false)); \ |
5376 | OPTIONAL(inlinedAt, MDField, ); \ |
5377 | OPTIONAL(isImplicitCode, MDBoolField, (false)); \ |
5378 | OPTIONAL(atomGroup, MDUnsignedField, (0, UINT64_MAX)); \ |
5379 | OPTIONAL(atomRank, MDUnsignedField, (0, UINT8_MAX)); |
5380 | PARSE_MD_FIELDS(); |
5381 | #undef VISIT_MD_FIELDS |
5382 | |
5383 | Result = GET_OR_DISTINCT( |
5384 | DILocation, (Context, line.Val, column.Val, scope.Val, inlinedAt.Val, |
5385 | isImplicitCode.Val, atomGroup.Val, atomRank.Val)); |
5386 | return false; |
5387 | } |
5388 | |
5389 | /// parseDIAssignID: |
5390 | /// ::= distinct !DIAssignID() |
5391 | bool LLParser::parseDIAssignID(MDNode *&Result, bool IsDistinct) { |
5392 | if (!IsDistinct) |
5393 | return tokError(Msg: "missing 'distinct', required for !DIAssignID()" ); |
5394 | |
5395 | Lex.Lex(); |
5396 | |
5397 | // Now eat the parens. |
5398 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
5399 | return true; |
5400 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
5401 | return true; |
5402 | |
5403 | Result = DIAssignID::getDistinct(Context); |
5404 | return false; |
5405 | } |
5406 | |
5407 | /// parseGenericDINode: |
5408 | /// ::= !GenericDINode(tag: 15, header: "...", operands: {...}) |
5409 | bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) { |
5410 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5411 | REQUIRED(tag, DwarfTagField, ); \ |
5412 | OPTIONAL(, MDStringField, ); \ |
5413 | OPTIONAL(operands, MDFieldList, ); |
5414 | PARSE_MD_FIELDS(); |
5415 | #undef VISIT_MD_FIELDS |
5416 | |
5417 | Result = GET_OR_DISTINCT(GenericDINode, |
5418 | (Context, tag.Val, header.Val, operands.Val)); |
5419 | return false; |
5420 | } |
5421 | |
5422 | /// parseDISubrangeType: |
5423 | /// ::= !DISubrangeType(name: "whatever", file: !0, |
5424 | /// line: 7, scope: !1, baseType: !2, size: 32, |
5425 | /// align: 32, flags: 0, lowerBound: !3 |
5426 | /// upperBound: !4, stride: !5, bias: !6) |
5427 | bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) { |
5428 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5429 | OPTIONAL(name, MDStringField, ); \ |
5430 | OPTIONAL(file, MDField, ); \ |
5431 | OPTIONAL(line, LineField, ); \ |
5432 | OPTIONAL(scope, MDField, ); \ |
5433 | OPTIONAL(baseType, MDField, ); \ |
5434 | OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5435 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
5436 | OPTIONAL(flags, DIFlagField, ); \ |
5437 | OPTIONAL(lowerBound, MDSignedOrMDField, ); \ |
5438 | OPTIONAL(upperBound, MDSignedOrMDField, ); \ |
5439 | OPTIONAL(stride, MDSignedOrMDField, ); \ |
5440 | OPTIONAL(bias, MDSignedOrMDField, ); |
5441 | PARSE_MD_FIELDS(); |
5442 | #undef VISIT_MD_FIELDS |
5443 | |
5444 | auto convToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * { |
5445 | if (Bound.isMDSignedField()) |
5446 | return ConstantAsMetadata::get(C: ConstantInt::getSigned( |
5447 | Ty: Type::getInt64Ty(C&: Context), V: Bound.getMDSignedValue())); |
5448 | if (Bound.isMDField()) |
5449 | return Bound.getMDFieldValue(); |
5450 | return nullptr; |
5451 | }; |
5452 | |
5453 | Metadata *LowerBound = convToMetadata(lowerBound); |
5454 | Metadata *UpperBound = convToMetadata(upperBound); |
5455 | Metadata *Stride = convToMetadata(stride); |
5456 | Metadata *Bias = convToMetadata(bias); |
5457 | |
5458 | Result = GET_OR_DISTINCT( |
5459 | DISubrangeType, (Context, name.Val, file.Val, line.Val, scope.Val, |
5460 | size.getValueAsMetadata(Context), align.Val, flags.Val, |
5461 | baseType.Val, LowerBound, UpperBound, Stride, Bias)); |
5462 | |
5463 | return false; |
5464 | } |
5465 | |
5466 | /// parseDISubrange: |
5467 | /// ::= !DISubrange(count: 30, lowerBound: 2) |
5468 | /// ::= !DISubrange(count: !node, lowerBound: 2) |
5469 | /// ::= !DISubrange(lowerBound: !node1, upperBound: !node2, stride: !node3) |
5470 | bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) { |
5471 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5472 | OPTIONAL(count, MDSignedOrMDField, (-1, -1, INT64_MAX, false)); \ |
5473 | OPTIONAL(lowerBound, MDSignedOrMDField, ); \ |
5474 | OPTIONAL(upperBound, MDSignedOrMDField, ); \ |
5475 | OPTIONAL(stride, MDSignedOrMDField, ); |
5476 | PARSE_MD_FIELDS(); |
5477 | #undef VISIT_MD_FIELDS |
5478 | |
5479 | Metadata *Count = nullptr; |
5480 | Metadata *LowerBound = nullptr; |
5481 | Metadata *UpperBound = nullptr; |
5482 | Metadata *Stride = nullptr; |
5483 | |
5484 | auto convToMetadata = [&](const MDSignedOrMDField &Bound) -> Metadata * { |
5485 | if (Bound.isMDSignedField()) |
5486 | return ConstantAsMetadata::get(C: ConstantInt::getSigned( |
5487 | Ty: Type::getInt64Ty(C&: Context), V: Bound.getMDSignedValue())); |
5488 | if (Bound.isMDField()) |
5489 | return Bound.getMDFieldValue(); |
5490 | return nullptr; |
5491 | }; |
5492 | |
5493 | Count = convToMetadata(count); |
5494 | LowerBound = convToMetadata(lowerBound); |
5495 | UpperBound = convToMetadata(upperBound); |
5496 | Stride = convToMetadata(stride); |
5497 | |
5498 | Result = GET_OR_DISTINCT(DISubrange, |
5499 | (Context, Count, LowerBound, UpperBound, Stride)); |
5500 | |
5501 | return false; |
5502 | } |
5503 | |
5504 | /// parseDIGenericSubrange: |
5505 | /// ::= !DIGenericSubrange(lowerBound: !node1, upperBound: !node2, stride: |
5506 | /// !node3) |
5507 | bool LLParser::parseDIGenericSubrange(MDNode *&Result, bool IsDistinct) { |
5508 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5509 | OPTIONAL(count, MDSignedOrMDField, ); \ |
5510 | OPTIONAL(lowerBound, MDSignedOrMDField, ); \ |
5511 | OPTIONAL(upperBound, MDSignedOrMDField, ); \ |
5512 | OPTIONAL(stride, MDSignedOrMDField, ); |
5513 | PARSE_MD_FIELDS(); |
5514 | #undef VISIT_MD_FIELDS |
5515 | |
5516 | auto ConvToMetadata = [&](const MDSignedOrMDField &Bound) -> Metadata * { |
5517 | if (Bound.isMDSignedField()) |
5518 | return DIExpression::get( |
5519 | Context, Elements: {dwarf::DW_OP_consts, |
5520 | static_cast<uint64_t>(Bound.getMDSignedValue())}); |
5521 | if (Bound.isMDField()) |
5522 | return Bound.getMDFieldValue(); |
5523 | return nullptr; |
5524 | }; |
5525 | |
5526 | Metadata *Count = ConvToMetadata(count); |
5527 | Metadata *LowerBound = ConvToMetadata(lowerBound); |
5528 | Metadata *UpperBound = ConvToMetadata(upperBound); |
5529 | Metadata *Stride = ConvToMetadata(stride); |
5530 | |
5531 | Result = GET_OR_DISTINCT(DIGenericSubrange, |
5532 | (Context, Count, LowerBound, UpperBound, Stride)); |
5533 | |
5534 | return false; |
5535 | } |
5536 | |
5537 | /// parseDIEnumerator: |
5538 | /// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind") |
5539 | bool LLParser::parseDIEnumerator(MDNode *&Result, bool IsDistinct) { |
5540 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5541 | REQUIRED(name, MDStringField, ); \ |
5542 | REQUIRED(value, MDAPSIntField, ); \ |
5543 | OPTIONAL(isUnsigned, MDBoolField, (false)); |
5544 | PARSE_MD_FIELDS(); |
5545 | #undef VISIT_MD_FIELDS |
5546 | |
5547 | if (isUnsigned.Val && value.Val.isNegative()) |
5548 | return tokError(Msg: "unsigned enumerator with negative value" ); |
5549 | |
5550 | APSInt Value(value.Val); |
5551 | // Add a leading zero so that unsigned values with the msb set are not |
5552 | // mistaken for negative values when used for signed enumerators. |
5553 | if (!isUnsigned.Val && value.Val.isUnsigned() && value.Val.isSignBitSet()) |
5554 | Value = Value.zext(width: Value.getBitWidth() + 1); |
5555 | |
5556 | Result = |
5557 | GET_OR_DISTINCT(DIEnumerator, (Context, Value, isUnsigned.Val, name.Val)); |
5558 | |
5559 | return false; |
5560 | } |
5561 | |
5562 | /// parseDIBasicType: |
5563 | /// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, |
5564 | /// encoding: DW_ATE_encoding, flags: 0) |
5565 | bool LLParser::parseDIBasicType(MDNode *&Result, bool IsDistinct) { |
5566 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5567 | OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ |
5568 | OPTIONAL(name, MDStringField, ); \ |
5569 | OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5570 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
5571 | OPTIONAL(encoding, DwarfAttEncodingField, ); \ |
5572 | OPTIONAL(, MDUnsignedField, (0, UINT32_MAX)); \ |
5573 | OPTIONAL(flags, DIFlagField, ); |
5574 | PARSE_MD_FIELDS(); |
5575 | #undef VISIT_MD_FIELDS |
5576 | |
5577 | Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, |
5578 | size.getValueAsMetadata(Context), |
5579 | align.Val, encoding.Val, |
5580 | num_extra_inhabitants.Val, flags.Val)); |
5581 | return false; |
5582 | } |
5583 | |
5584 | /// parseDIFixedPointType: |
5585 | /// ::= !DIFixedPointType(tag: DW_TAG_base_type, name: "xyz", size: 32, |
5586 | /// align: 32, encoding: DW_ATE_signed_fixed, |
5587 | /// flags: 0, kind: Rational, factor: 3, numerator: 1, |
5588 | /// denominator: 8) |
5589 | bool LLParser::parseDIFixedPointType(MDNode *&Result, bool IsDistinct) { |
5590 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5591 | OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \ |
5592 | OPTIONAL(name, MDStringField, ); \ |
5593 | OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5594 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
5595 | OPTIONAL(encoding, DwarfAttEncodingField, ); \ |
5596 | OPTIONAL(flags, DIFlagField, ); \ |
5597 | OPTIONAL(kind, FixedPointKindField, ); \ |
5598 | OPTIONAL(factor, MDSignedField, ); \ |
5599 | OPTIONAL(numerator, MDAPSIntField, ); \ |
5600 | OPTIONAL(denominator, MDAPSIntField, ); |
5601 | PARSE_MD_FIELDS(); |
5602 | #undef VISIT_MD_FIELDS |
5603 | |
5604 | Result = GET_OR_DISTINCT(DIFixedPointType, |
5605 | (Context, tag.Val, name.Val, |
5606 | size.getValueAsMetadata(Context), align.Val, |
5607 | encoding.Val, flags.Val, kind.Val, factor.Val, |
5608 | numerator.Val, denominator.Val)); |
5609 | return false; |
5610 | } |
5611 | |
5612 | /// parseDIStringType: |
5613 | /// ::= !DIStringType(name: "character(4)", size: 32, align: 32) |
5614 | bool LLParser::parseDIStringType(MDNode *&Result, bool IsDistinct) { |
5615 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5616 | OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_string_type)); \ |
5617 | OPTIONAL(name, MDStringField, ); \ |
5618 | OPTIONAL(stringLength, MDField, ); \ |
5619 | OPTIONAL(stringLengthExpression, MDField, ); \ |
5620 | OPTIONAL(stringLocationExpression, MDField, ); \ |
5621 | OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5622 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
5623 | OPTIONAL(encoding, DwarfAttEncodingField, ); |
5624 | PARSE_MD_FIELDS(); |
5625 | #undef VISIT_MD_FIELDS |
5626 | |
5627 | Result = GET_OR_DISTINCT( |
5628 | DIStringType, |
5629 | (Context, tag.Val, name.Val, stringLength.Val, stringLengthExpression.Val, |
5630 | stringLocationExpression.Val, size.getValueAsMetadata(Context), |
5631 | align.Val, encoding.Val)); |
5632 | return false; |
5633 | } |
5634 | |
5635 | /// parseDIDerivedType: |
5636 | /// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0, |
5637 | /// line: 7, scope: !1, baseType: !2, size: 32, |
5638 | /// align: 32, offset: 0, flags: 0, extraData: !3, |
5639 | /// dwarfAddressSpace: 3, ptrAuthKey: 1, |
5640 | /// ptrAuthIsAddressDiscriminated: true, |
5641 | /// ptrAuthExtraDiscriminator: 0x1234, |
5642 | /// ptrAuthIsaPointer: 1, ptrAuthAuthenticatesNullValues:1 |
5643 | /// ) |
5644 | bool LLParser::parseDIDerivedType(MDNode *&Result, bool IsDistinct) { |
5645 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5646 | REQUIRED(tag, DwarfTagField, ); \ |
5647 | OPTIONAL(name, MDStringField, ); \ |
5648 | OPTIONAL(file, MDField, ); \ |
5649 | OPTIONAL(line, LineField, ); \ |
5650 | OPTIONAL(scope, MDField, ); \ |
5651 | REQUIRED(baseType, MDField, ); \ |
5652 | OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5653 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
5654 | OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5655 | OPTIONAL(flags, DIFlagField, ); \ |
5656 | OPTIONAL(, MDField, ); \ |
5657 | OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX)); \ |
5658 | OPTIONAL(annotations, MDField, ); \ |
5659 | OPTIONAL(ptrAuthKey, MDUnsignedField, (0, 7)); \ |
5660 | OPTIONAL(ptrAuthIsAddressDiscriminated, MDBoolField, ); \ |
5661 | OPTIONAL(, MDUnsignedField, (0, 0xffff)); \ |
5662 | OPTIONAL(ptrAuthIsaPointer, MDBoolField, ); \ |
5663 | OPTIONAL(ptrAuthAuthenticatesNullValues, MDBoolField, ); |
5664 | PARSE_MD_FIELDS(); |
5665 | #undef VISIT_MD_FIELDS |
5666 | |
5667 | std::optional<unsigned> DWARFAddressSpace; |
5668 | if (dwarfAddressSpace.Val != UINT32_MAX) |
5669 | DWARFAddressSpace = dwarfAddressSpace.Val; |
5670 | std::optional<DIDerivedType::PtrAuthData> PtrAuthData; |
5671 | if (ptrAuthKey.Val) |
5672 | PtrAuthData.emplace( |
5673 | args: (unsigned)ptrAuthKey.Val, args&: ptrAuthIsAddressDiscriminated.Val, |
5674 | args: (unsigned)ptrAuthExtraDiscriminator.Val, args&: ptrAuthIsaPointer.Val, |
5675 | args&: ptrAuthAuthenticatesNullValues.Val); |
5676 | |
5677 | Result = GET_OR_DISTINCT( |
5678 | DIDerivedType, (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, |
5679 | baseType.Val, size.getValueAsMetadata(Context), align.Val, |
5680 | offset.getValueAsMetadata(Context), DWARFAddressSpace, |
5681 | PtrAuthData, flags.Val, extraData.Val, annotations.Val)); |
5682 | return false; |
5683 | } |
5684 | |
5685 | bool LLParser::parseDICompositeType(MDNode *&Result, bool IsDistinct) { |
5686 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5687 | REQUIRED(tag, DwarfTagField, ); \ |
5688 | OPTIONAL(name, MDStringField, ); \ |
5689 | OPTIONAL(file, MDField, ); \ |
5690 | OPTIONAL(line, LineField, ); \ |
5691 | OPTIONAL(scope, MDField, ); \ |
5692 | OPTIONAL(baseType, MDField, ); \ |
5693 | OPTIONAL(size, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5694 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
5695 | OPTIONAL(offset, MDUnsignedOrMDField, (0, UINT64_MAX)); \ |
5696 | OPTIONAL(flags, DIFlagField, ); \ |
5697 | OPTIONAL(elements, MDField, ); \ |
5698 | OPTIONAL(runtimeLang, DwarfLangField, ); \ |
5699 | OPTIONAL(enumKind, DwarfEnumKindField, ); \ |
5700 | OPTIONAL(vtableHolder, MDField, ); \ |
5701 | OPTIONAL(templateParams, MDField, ); \ |
5702 | OPTIONAL(identifier, MDStringField, ); \ |
5703 | OPTIONAL(discriminator, MDField, ); \ |
5704 | OPTIONAL(dataLocation, MDField, ); \ |
5705 | OPTIONAL(associated, MDField, ); \ |
5706 | OPTIONAL(allocated, MDField, ); \ |
5707 | OPTIONAL(rank, MDSignedOrMDField, ); \ |
5708 | OPTIONAL(annotations, MDField, ); \ |
5709 | OPTIONAL(, MDUnsignedField, (0, UINT32_MAX)); \ |
5710 | OPTIONAL(specification, MDField, ); \ |
5711 | OPTIONAL(bitStride, MDField, ); |
5712 | PARSE_MD_FIELDS(); |
5713 | #undef VISIT_MD_FIELDS |
5714 | |
5715 | Metadata *Rank = nullptr; |
5716 | if (rank.isMDSignedField()) |
5717 | Rank = ConstantAsMetadata::get(C: ConstantInt::getSigned( |
5718 | Ty: Type::getInt64Ty(C&: Context), V: rank.getMDSignedValue())); |
5719 | else if (rank.isMDField()) |
5720 | Rank = rank.getMDFieldValue(); |
5721 | |
5722 | std::optional<unsigned> EnumKind; |
5723 | if (enumKind.Val != dwarf::DW_APPLE_ENUM_KIND_invalid) |
5724 | EnumKind = enumKind.Val; |
5725 | |
5726 | // If this has an identifier try to build an ODR type. |
5727 | if (identifier.Val) |
5728 | if (auto *CT = DICompositeType::buildODRType( |
5729 | Context, Identifier&: *identifier.Val, Tag: tag.Val, Name: name.Val, File: file.Val, Line: line.Val, |
5730 | Scope: scope.Val, BaseType: baseType.Val, SizeInBits: size.getValueAsMetadata(Context), |
5731 | AlignInBits: align.Val, OffsetInBits: offset.getValueAsMetadata(Context), Specification: specification.Val, |
5732 | NumExtraInhabitants: num_extra_inhabitants.Val, Flags: flags.Val, Elements: elements.Val, RuntimeLang: runtimeLang.Val, |
5733 | EnumKind, VTableHolder: vtableHolder.Val, TemplateParams: templateParams.Val, Discriminator: discriminator.Val, |
5734 | DataLocation: dataLocation.Val, Associated: associated.Val, Allocated: allocated.Val, Rank, |
5735 | Annotations: annotations.Val, BitStride: bitStride.Val)) { |
5736 | Result = CT; |
5737 | return false; |
5738 | } |
5739 | |
5740 | // Create a new node, and save it in the context if it belongs in the type |
5741 | // map. |
5742 | Result = GET_OR_DISTINCT( |
5743 | DICompositeType, |
5744 | (Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val, |
5745 | size.getValueAsMetadata(Context), align.Val, |
5746 | offset.getValueAsMetadata(Context), flags.Val, elements.Val, |
5747 | runtimeLang.Val, EnumKind, vtableHolder.Val, templateParams.Val, |
5748 | identifier.Val, discriminator.Val, dataLocation.Val, associated.Val, |
5749 | allocated.Val, Rank, annotations.Val, specification.Val, |
5750 | num_extra_inhabitants.Val, bitStride.Val)); |
5751 | return false; |
5752 | } |
5753 | |
5754 | bool LLParser::parseDISubroutineType(MDNode *&Result, bool IsDistinct) { |
5755 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5756 | OPTIONAL(flags, DIFlagField, ); \ |
5757 | OPTIONAL(cc, DwarfCCField, ); \ |
5758 | REQUIRED(types, MDField, ); |
5759 | PARSE_MD_FIELDS(); |
5760 | #undef VISIT_MD_FIELDS |
5761 | |
5762 | Result = GET_OR_DISTINCT(DISubroutineType, |
5763 | (Context, flags.Val, cc.Val, types.Val)); |
5764 | return false; |
5765 | } |
5766 | |
5767 | /// parseDIFileType: |
5768 | /// ::= !DIFileType(filename: "path/to/file", directory: "/path/to/dir", |
5769 | /// checksumkind: CSK_MD5, |
5770 | /// checksum: "000102030405060708090a0b0c0d0e0f", |
5771 | /// source: "source file contents") |
5772 | bool LLParser::parseDIFile(MDNode *&Result, bool IsDistinct) { |
5773 | // The default constructed value for checksumkind is required, but will never |
5774 | // be used, as the parser checks if the field was actually Seen before using |
5775 | // the Val. |
5776 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5777 | REQUIRED(filename, MDStringField, ); \ |
5778 | REQUIRED(directory, MDStringField, ); \ |
5779 | OPTIONAL(checksumkind, ChecksumKindField, (DIFile::CSK_MD5)); \ |
5780 | OPTIONAL(checksum, MDStringField, ); \ |
5781 | OPTIONAL(source, MDStringField, ); |
5782 | PARSE_MD_FIELDS(); |
5783 | #undef VISIT_MD_FIELDS |
5784 | |
5785 | std::optional<DIFile::ChecksumInfo<MDString *>> OptChecksum; |
5786 | if (checksumkind.Seen && checksum.Seen) |
5787 | OptChecksum.emplace(args&: checksumkind.Val, args&: checksum.Val); |
5788 | else if (checksumkind.Seen || checksum.Seen) |
5789 | return tokError(Msg: "'checksumkind' and 'checksum' must be provided together" ); |
5790 | |
5791 | MDString *Source = nullptr; |
5792 | if (source.Seen) |
5793 | Source = source.Val; |
5794 | Result = GET_OR_DISTINCT( |
5795 | DIFile, (Context, filename.Val, directory.Val, OptChecksum, Source)); |
5796 | return false; |
5797 | } |
5798 | |
5799 | /// parseDICompileUnit: |
5800 | /// ::= !DICompileUnit(language: DW_LANG_C99, file: !0, producer: "clang", |
5801 | /// isOptimized: true, flags: "-O2", runtimeVersion: 1, |
5802 | /// splitDebugFilename: "abc.debug", |
5803 | /// emissionKind: FullDebug, enums: !1, retainedTypes: !2, |
5804 | /// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd, |
5805 | /// sysroot: "/", sdk: "MacOSX.sdk") |
5806 | bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) { |
5807 | if (!IsDistinct) |
5808 | return tokError(Msg: "missing 'distinct', required for !DICompileUnit" ); |
5809 | |
5810 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5811 | REQUIRED(language, DwarfLangField, ); \ |
5812 | REQUIRED(file, MDField, (/* AllowNull */ false)); \ |
5813 | OPTIONAL(producer, MDStringField, ); \ |
5814 | OPTIONAL(isOptimized, MDBoolField, ); \ |
5815 | OPTIONAL(flags, MDStringField, ); \ |
5816 | OPTIONAL(runtimeVersion, MDUnsignedField, (0, UINT32_MAX)); \ |
5817 | OPTIONAL(splitDebugFilename, MDStringField, ); \ |
5818 | OPTIONAL(emissionKind, EmissionKindField, ); \ |
5819 | OPTIONAL(enums, MDField, ); \ |
5820 | OPTIONAL(retainedTypes, MDField, ); \ |
5821 | OPTIONAL(globals, MDField, ); \ |
5822 | OPTIONAL(imports, MDField, ); \ |
5823 | OPTIONAL(macros, MDField, ); \ |
5824 | OPTIONAL(dwoId, MDUnsignedField, ); \ |
5825 | OPTIONAL(splitDebugInlining, MDBoolField, = true); \ |
5826 | OPTIONAL(debugInfoForProfiling, MDBoolField, = false); \ |
5827 | OPTIONAL(nameTableKind, NameTableKindField, ); \ |
5828 | OPTIONAL(rangesBaseAddress, MDBoolField, = false); \ |
5829 | OPTIONAL(sysroot, MDStringField, ); \ |
5830 | OPTIONAL(sdk, MDStringField, ); |
5831 | PARSE_MD_FIELDS(); |
5832 | #undef VISIT_MD_FIELDS |
5833 | |
5834 | Result = DICompileUnit::getDistinct( |
5835 | Context, SourceLanguage: language.Val, File: file.Val, Producer: producer.Val, IsOptimized: isOptimized.Val, Flags: flags.Val, |
5836 | RuntimeVersion: runtimeVersion.Val, SplitDebugFilename: splitDebugFilename.Val, EmissionKind: emissionKind.Val, EnumTypes: enums.Val, |
5837 | RetainedTypes: retainedTypes.Val, GlobalVariables: globals.Val, ImportedEntities: imports.Val, Macros: macros.Val, DWOId: dwoId.Val, |
5838 | SplitDebugInlining: splitDebugInlining.Val, DebugInfoForProfiling: debugInfoForProfiling.Val, NameTableKind: nameTableKind.Val, |
5839 | RangesBaseAddress: rangesBaseAddress.Val, SysRoot: sysroot.Val, SDK: sdk.Val); |
5840 | return false; |
5841 | } |
5842 | |
5843 | /// parseDISubprogram: |
5844 | /// ::= !DISubprogram(scope: !0, name: "foo", linkageName: "_Zfoo", |
5845 | /// file: !1, line: 7, type: !2, isLocal: false, |
5846 | /// isDefinition: true, scopeLine: 8, containingType: !3, |
5847 | /// virtuality: DW_VIRTUALTIY_pure_virtual, |
5848 | /// virtualIndex: 10, thisAdjustment: 4, flags: 11, |
5849 | /// spFlags: 10, isOptimized: false, templateParams: !4, |
5850 | /// declaration: !5, retainedNodes: !6, thrownTypes: !7, |
5851 | /// annotations: !8) |
5852 | bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { |
5853 | auto Loc = Lex.getLoc(); |
5854 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5855 | OPTIONAL(scope, MDField, ); \ |
5856 | OPTIONAL(name, MDStringField, ); \ |
5857 | OPTIONAL(linkageName, MDStringField, ); \ |
5858 | OPTIONAL(file, MDField, ); \ |
5859 | OPTIONAL(line, LineField, ); \ |
5860 | OPTIONAL(type, MDField, ); \ |
5861 | OPTIONAL(isLocal, MDBoolField, ); \ |
5862 | OPTIONAL(isDefinition, MDBoolField, (true)); \ |
5863 | OPTIONAL(scopeLine, LineField, ); \ |
5864 | OPTIONAL(containingType, MDField, ); \ |
5865 | OPTIONAL(virtuality, DwarfVirtualityField, ); \ |
5866 | OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \ |
5867 | OPTIONAL(thisAdjustment, MDSignedField, (0, INT32_MIN, INT32_MAX)); \ |
5868 | OPTIONAL(flags, DIFlagField, ); \ |
5869 | OPTIONAL(spFlags, DISPFlagField, ); \ |
5870 | OPTIONAL(isOptimized, MDBoolField, ); \ |
5871 | OPTIONAL(unit, MDField, ); \ |
5872 | OPTIONAL(templateParams, MDField, ); \ |
5873 | OPTIONAL(declaration, MDField, ); \ |
5874 | OPTIONAL(retainedNodes, MDField, ); \ |
5875 | OPTIONAL(thrownTypes, MDField, ); \ |
5876 | OPTIONAL(annotations, MDField, ); \ |
5877 | OPTIONAL(targetFuncName, MDStringField, ); \ |
5878 | OPTIONAL(keyInstructions, MDBoolField, ); |
5879 | PARSE_MD_FIELDS(); |
5880 | #undef VISIT_MD_FIELDS |
5881 | |
5882 | // An explicit spFlags field takes precedence over individual fields in |
5883 | // older IR versions. |
5884 | DISubprogram::DISPFlags SPFlags = |
5885 | spFlags.Seen ? spFlags.Val |
5886 | : DISubprogram::toSPFlags(IsLocalToUnit: isLocal.Val, IsDefinition: isDefinition.Val, |
5887 | IsOptimized: isOptimized.Val, Virtuality: virtuality.Val); |
5888 | if ((SPFlags & DISubprogram::SPFlagDefinition) && !IsDistinct) |
5889 | return error( |
5890 | L: Loc, |
5891 | Msg: "missing 'distinct', required for !DISubprogram that is a Definition" ); |
5892 | Result = GET_OR_DISTINCT( |
5893 | DISubprogram, |
5894 | (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, |
5895 | type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val, |
5896 | thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val, |
5897 | declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val, |
5898 | targetFuncName.Val, keyInstructions.Val)); |
5899 | return false; |
5900 | } |
5901 | |
5902 | /// parseDILexicalBlock: |
5903 | /// ::= !DILexicalBlock(scope: !0, file: !2, line: 7, column: 9) |
5904 | bool LLParser::parseDILexicalBlock(MDNode *&Result, bool IsDistinct) { |
5905 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5906 | REQUIRED(scope, MDField, (/* AllowNull */ false)); \ |
5907 | OPTIONAL(file, MDField, ); \ |
5908 | OPTIONAL(line, LineField, ); \ |
5909 | OPTIONAL(column, ColumnField, ); |
5910 | PARSE_MD_FIELDS(); |
5911 | #undef VISIT_MD_FIELDS |
5912 | |
5913 | Result = GET_OR_DISTINCT( |
5914 | DILexicalBlock, (Context, scope.Val, file.Val, line.Val, column.Val)); |
5915 | return false; |
5916 | } |
5917 | |
5918 | /// parseDILexicalBlockFile: |
5919 | /// ::= !DILexicalBlockFile(scope: !0, file: !2, discriminator: 9) |
5920 | bool LLParser::parseDILexicalBlockFile(MDNode *&Result, bool IsDistinct) { |
5921 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5922 | REQUIRED(scope, MDField, (/* AllowNull */ false)); \ |
5923 | OPTIONAL(file, MDField, ); \ |
5924 | REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX)); |
5925 | PARSE_MD_FIELDS(); |
5926 | #undef VISIT_MD_FIELDS |
5927 | |
5928 | Result = GET_OR_DISTINCT(DILexicalBlockFile, |
5929 | (Context, scope.Val, file.Val, discriminator.Val)); |
5930 | return false; |
5931 | } |
5932 | |
5933 | /// parseDICommonBlock: |
5934 | /// ::= !DICommonBlock(scope: !0, file: !2, name: "COMMON name", line: 9) |
5935 | bool LLParser::parseDICommonBlock(MDNode *&Result, bool IsDistinct) { |
5936 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5937 | REQUIRED(scope, MDField, ); \ |
5938 | OPTIONAL(declaration, MDField, ); \ |
5939 | OPTIONAL(name, MDStringField, ); \ |
5940 | OPTIONAL(file, MDField, ); \ |
5941 | OPTIONAL(line, LineField, ); |
5942 | PARSE_MD_FIELDS(); |
5943 | #undef VISIT_MD_FIELDS |
5944 | |
5945 | Result = GET_OR_DISTINCT(DICommonBlock, |
5946 | (Context, scope.Val, declaration.Val, name.Val, |
5947 | file.Val, line.Val)); |
5948 | return false; |
5949 | } |
5950 | |
5951 | /// parseDINamespace: |
5952 | /// ::= !DINamespace(scope: !0, file: !2, name: "SomeNamespace", line: 9) |
5953 | bool LLParser::parseDINamespace(MDNode *&Result, bool IsDistinct) { |
5954 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5955 | REQUIRED(scope, MDField, ); \ |
5956 | OPTIONAL(name, MDStringField, ); \ |
5957 | OPTIONAL(exportSymbols, MDBoolField, ); |
5958 | PARSE_MD_FIELDS(); |
5959 | #undef VISIT_MD_FIELDS |
5960 | |
5961 | Result = GET_OR_DISTINCT(DINamespace, |
5962 | (Context, scope.Val, name.Val, exportSymbols.Val)); |
5963 | return false; |
5964 | } |
5965 | |
5966 | /// parseDIMacro: |
5967 | /// ::= !DIMacro(macinfo: type, line: 9, name: "SomeMacro", value: |
5968 | /// "SomeValue") |
5969 | bool LLParser::parseDIMacro(MDNode *&Result, bool IsDistinct) { |
5970 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5971 | REQUIRED(type, DwarfMacinfoTypeField, ); \ |
5972 | OPTIONAL(line, LineField, ); \ |
5973 | REQUIRED(name, MDStringField, ); \ |
5974 | OPTIONAL(value, MDStringField, ); |
5975 | PARSE_MD_FIELDS(); |
5976 | #undef VISIT_MD_FIELDS |
5977 | |
5978 | Result = GET_OR_DISTINCT(DIMacro, |
5979 | (Context, type.Val, line.Val, name.Val, value.Val)); |
5980 | return false; |
5981 | } |
5982 | |
5983 | /// parseDIMacroFile: |
5984 | /// ::= !DIMacroFile(line: 9, file: !2, nodes: !3) |
5985 | bool LLParser::parseDIMacroFile(MDNode *&Result, bool IsDistinct) { |
5986 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
5987 | OPTIONAL(type, DwarfMacinfoTypeField, (dwarf::DW_MACINFO_start_file)); \ |
5988 | OPTIONAL(line, LineField, ); \ |
5989 | REQUIRED(file, MDField, ); \ |
5990 | OPTIONAL(nodes, MDField, ); |
5991 | PARSE_MD_FIELDS(); |
5992 | #undef VISIT_MD_FIELDS |
5993 | |
5994 | Result = GET_OR_DISTINCT(DIMacroFile, |
5995 | (Context, type.Val, line.Val, file.Val, nodes.Val)); |
5996 | return false; |
5997 | } |
5998 | |
5999 | /// parseDIModule: |
6000 | /// ::= !DIModule(scope: !0, name: "SomeModule", configMacros: |
6001 | /// "-DNDEBUG", includePath: "/usr/include", apinotes: "module.apinotes", |
6002 | /// file: !1, line: 4, isDecl: false) |
6003 | bool LLParser::parseDIModule(MDNode *&Result, bool IsDistinct) { |
6004 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6005 | REQUIRED(scope, MDField, ); \ |
6006 | REQUIRED(name, MDStringField, ); \ |
6007 | OPTIONAL(configMacros, MDStringField, ); \ |
6008 | OPTIONAL(includePath, MDStringField, ); \ |
6009 | OPTIONAL(apinotes, MDStringField, ); \ |
6010 | OPTIONAL(file, MDField, ); \ |
6011 | OPTIONAL(line, LineField, ); \ |
6012 | OPTIONAL(isDecl, MDBoolField, ); |
6013 | PARSE_MD_FIELDS(); |
6014 | #undef VISIT_MD_FIELDS |
6015 | |
6016 | Result = GET_OR_DISTINCT(DIModule, (Context, file.Val, scope.Val, name.Val, |
6017 | configMacros.Val, includePath.Val, |
6018 | apinotes.Val, line.Val, isDecl.Val)); |
6019 | return false; |
6020 | } |
6021 | |
6022 | /// parseDITemplateTypeParameter: |
6023 | /// ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false) |
6024 | bool LLParser::parseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) { |
6025 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6026 | OPTIONAL(name, MDStringField, ); \ |
6027 | REQUIRED(type, MDField, ); \ |
6028 | OPTIONAL(defaulted, MDBoolField, ); |
6029 | PARSE_MD_FIELDS(); |
6030 | #undef VISIT_MD_FIELDS |
6031 | |
6032 | Result = GET_OR_DISTINCT(DITemplateTypeParameter, |
6033 | (Context, name.Val, type.Val, defaulted.Val)); |
6034 | return false; |
6035 | } |
6036 | |
6037 | /// parseDITemplateValueParameter: |
6038 | /// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, |
6039 | /// name: "V", type: !1, defaulted: false, |
6040 | /// value: i32 7) |
6041 | bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { |
6042 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6043 | OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \ |
6044 | OPTIONAL(name, MDStringField, ); \ |
6045 | OPTIONAL(type, MDField, ); \ |
6046 | OPTIONAL(defaulted, MDBoolField, ); \ |
6047 | REQUIRED(value, MDField, ); |
6048 | |
6049 | PARSE_MD_FIELDS(); |
6050 | #undef VISIT_MD_FIELDS |
6051 | |
6052 | Result = GET_OR_DISTINCT( |
6053 | DITemplateValueParameter, |
6054 | (Context, tag.Val, name.Val, type.Val, defaulted.Val, value.Val)); |
6055 | return false; |
6056 | } |
6057 | |
6058 | /// parseDIGlobalVariable: |
6059 | /// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo", |
6060 | /// file: !1, line: 7, type: !2, isLocal: false, |
6061 | /// isDefinition: true, templateParams: !3, |
6062 | /// declaration: !4, align: 8) |
6063 | bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { |
6064 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6065 | OPTIONAL(name, MDStringField, (/* AllowEmpty */ false)); \ |
6066 | OPTIONAL(scope, MDField, ); \ |
6067 | OPTIONAL(linkageName, MDStringField, ); \ |
6068 | OPTIONAL(file, MDField, ); \ |
6069 | OPTIONAL(line, LineField, ); \ |
6070 | OPTIONAL(type, MDField, ); \ |
6071 | OPTIONAL(isLocal, MDBoolField, ); \ |
6072 | OPTIONAL(isDefinition, MDBoolField, (true)); \ |
6073 | OPTIONAL(templateParams, MDField, ); \ |
6074 | OPTIONAL(declaration, MDField, ); \ |
6075 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
6076 | OPTIONAL(annotations, MDField, ); |
6077 | PARSE_MD_FIELDS(); |
6078 | #undef VISIT_MD_FIELDS |
6079 | |
6080 | Result = |
6081 | GET_OR_DISTINCT(DIGlobalVariable, |
6082 | (Context, scope.Val, name.Val, linkageName.Val, file.Val, |
6083 | line.Val, type.Val, isLocal.Val, isDefinition.Val, |
6084 | declaration.Val, templateParams.Val, align.Val, |
6085 | annotations.Val)); |
6086 | return false; |
6087 | } |
6088 | |
6089 | /// parseDILocalVariable: |
6090 | /// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo", |
6091 | /// file: !1, line: 7, type: !2, arg: 2, flags: 7, |
6092 | /// align: 8) |
6093 | /// ::= !DILocalVariable(scope: !0, name: "foo", |
6094 | /// file: !1, line: 7, type: !2, arg: 2, flags: 7, |
6095 | /// align: 8) |
6096 | bool LLParser::parseDILocalVariable(MDNode *&Result, bool IsDistinct) { |
6097 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6098 | REQUIRED(scope, MDField, (/* AllowNull */ false)); \ |
6099 | OPTIONAL(name, MDStringField, ); \ |
6100 | OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \ |
6101 | OPTIONAL(file, MDField, ); \ |
6102 | OPTIONAL(line, LineField, ); \ |
6103 | OPTIONAL(type, MDField, ); \ |
6104 | OPTIONAL(flags, DIFlagField, ); \ |
6105 | OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ |
6106 | OPTIONAL(annotations, MDField, ); |
6107 | PARSE_MD_FIELDS(); |
6108 | #undef VISIT_MD_FIELDS |
6109 | |
6110 | Result = GET_OR_DISTINCT(DILocalVariable, |
6111 | (Context, scope.Val, name.Val, file.Val, line.Val, |
6112 | type.Val, arg.Val, flags.Val, align.Val, |
6113 | annotations.Val)); |
6114 | return false; |
6115 | } |
6116 | |
6117 | /// parseDILabel: |
6118 | /// ::= !DILabel(scope: !0, name: "foo", file: !1, line: 7, column: 4) |
6119 | bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) { |
6120 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6121 | REQUIRED(scope, MDField, (/* AllowNull */ false)); \ |
6122 | REQUIRED(name, MDStringField, ); \ |
6123 | REQUIRED(file, MDField, ); \ |
6124 | REQUIRED(line, LineField, ); \ |
6125 | OPTIONAL(column, ColumnField, ); \ |
6126 | OPTIONAL(isArtificial, MDBoolField, ); \ |
6127 | OPTIONAL(coroSuspendIdx, MDUnsignedField, ); |
6128 | PARSE_MD_FIELDS(); |
6129 | #undef VISIT_MD_FIELDS |
6130 | |
6131 | std::optional<unsigned> CoroSuspendIdx = |
6132 | coroSuspendIdx.Seen ? std::optional<unsigned>(coroSuspendIdx.Val) |
6133 | : std::nullopt; |
6134 | |
6135 | Result = GET_OR_DISTINCT(DILabel, |
6136 | (Context, scope.Val, name.Val, file.Val, line.Val, |
6137 | column.Val, isArtificial.Val, CoroSuspendIdx)); |
6138 | return false; |
6139 | } |
6140 | |
6141 | /// parseDIExpressionBody: |
6142 | /// ::= (0, 7, -1) |
6143 | bool LLParser::parseDIExpressionBody(MDNode *&Result, bool IsDistinct) { |
6144 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
6145 | return true; |
6146 | |
6147 | SmallVector<uint64_t, 8> Elements; |
6148 | if (Lex.getKind() != lltok::rparen) |
6149 | do { |
6150 | if (Lex.getKind() == lltok::DwarfOp) { |
6151 | if (unsigned Op = dwarf::getOperationEncoding(OperationEncodingString: Lex.getStrVal())) { |
6152 | Lex.Lex(); |
6153 | Elements.push_back(Elt: Op); |
6154 | continue; |
6155 | } |
6156 | return tokError(Msg: Twine("invalid DWARF op '" ) + Lex.getStrVal() + "'" ); |
6157 | } |
6158 | |
6159 | if (Lex.getKind() == lltok::DwarfAttEncoding) { |
6160 | if (unsigned Op = dwarf::getAttributeEncoding(EncodingString: Lex.getStrVal())) { |
6161 | Lex.Lex(); |
6162 | Elements.push_back(Elt: Op); |
6163 | continue; |
6164 | } |
6165 | return tokError(Msg: Twine("invalid DWARF attribute encoding '" ) + |
6166 | Lex.getStrVal() + "'" ); |
6167 | } |
6168 | |
6169 | if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) |
6170 | return tokError(Msg: "expected unsigned integer" ); |
6171 | |
6172 | auto &U = Lex.getAPSIntVal(); |
6173 | if (U.ugt(UINT64_MAX)) |
6174 | return tokError(Msg: "element too large, limit is " + Twine(UINT64_MAX)); |
6175 | Elements.push_back(Elt: U.getZExtValue()); |
6176 | Lex.Lex(); |
6177 | } while (EatIfPresent(T: lltok::comma)); |
6178 | |
6179 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
6180 | return true; |
6181 | |
6182 | Result = GET_OR_DISTINCT(DIExpression, (Context, Elements)); |
6183 | return false; |
6184 | } |
6185 | |
6186 | /// parseDIExpression: |
6187 | /// ::= !DIExpression(0, 7, -1) |
6188 | bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) { |
6189 | assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name" ); |
6190 | assert(Lex.getStrVal() == "DIExpression" && "Expected '!DIExpression'" ); |
6191 | Lex.Lex(); |
6192 | |
6193 | return parseDIExpressionBody(Result, IsDistinct); |
6194 | } |
6195 | |
6196 | /// ParseDIArgList: |
6197 | /// ::= !DIArgList(i32 7, i64 %0) |
6198 | bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) { |
6199 | assert(PFS && "Expected valid function state" ); |
6200 | assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name" ); |
6201 | Lex.Lex(); |
6202 | |
6203 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
6204 | return true; |
6205 | |
6206 | SmallVector<ValueAsMetadata *, 4> Args; |
6207 | if (Lex.getKind() != lltok::rparen) |
6208 | do { |
6209 | Metadata *MD; |
6210 | if (parseValueAsMetadata(MD, TypeMsg: "expected value-as-metadata operand" , PFS)) |
6211 | return true; |
6212 | Args.push_back(Elt: dyn_cast<ValueAsMetadata>(Val: MD)); |
6213 | } while (EatIfPresent(T: lltok::comma)); |
6214 | |
6215 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
6216 | return true; |
6217 | |
6218 | MD = DIArgList::get(Context, Args); |
6219 | return false; |
6220 | } |
6221 | |
6222 | /// parseDIGlobalVariableExpression: |
6223 | /// ::= !DIGlobalVariableExpression(var: !0, expr: !1) |
6224 | bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result, |
6225 | bool IsDistinct) { |
6226 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6227 | REQUIRED(var, MDField, ); \ |
6228 | REQUIRED(expr, MDField, ); |
6229 | PARSE_MD_FIELDS(); |
6230 | #undef VISIT_MD_FIELDS |
6231 | |
6232 | Result = |
6233 | GET_OR_DISTINCT(DIGlobalVariableExpression, (Context, var.Val, expr.Val)); |
6234 | return false; |
6235 | } |
6236 | |
6237 | /// parseDIObjCProperty: |
6238 | /// ::= !DIObjCProperty(name: "foo", file: !1, line: 7, setter: "setFoo", |
6239 | /// getter: "getFoo", attributes: 7, type: !2) |
6240 | bool LLParser::parseDIObjCProperty(MDNode *&Result, bool IsDistinct) { |
6241 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6242 | OPTIONAL(name, MDStringField, ); \ |
6243 | OPTIONAL(file, MDField, ); \ |
6244 | OPTIONAL(line, LineField, ); \ |
6245 | OPTIONAL(setter, MDStringField, ); \ |
6246 | OPTIONAL(getter, MDStringField, ); \ |
6247 | OPTIONAL(attributes, MDUnsignedField, (0, UINT32_MAX)); \ |
6248 | OPTIONAL(type, MDField, ); |
6249 | PARSE_MD_FIELDS(); |
6250 | #undef VISIT_MD_FIELDS |
6251 | |
6252 | Result = GET_OR_DISTINCT(DIObjCProperty, |
6253 | (Context, name.Val, file.Val, line.Val, setter.Val, |
6254 | getter.Val, attributes.Val, type.Val)); |
6255 | return false; |
6256 | } |
6257 | |
6258 | /// parseDIImportedEntity: |
6259 | /// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1, |
6260 | /// line: 7, name: "foo", elements: !2) |
6261 | bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) { |
6262 | #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ |
6263 | REQUIRED(tag, DwarfTagField, ); \ |
6264 | REQUIRED(scope, MDField, ); \ |
6265 | OPTIONAL(entity, MDField, ); \ |
6266 | OPTIONAL(file, MDField, ); \ |
6267 | OPTIONAL(line, LineField, ); \ |
6268 | OPTIONAL(name, MDStringField, ); \ |
6269 | OPTIONAL(elements, MDField, ); |
6270 | PARSE_MD_FIELDS(); |
6271 | #undef VISIT_MD_FIELDS |
6272 | |
6273 | Result = GET_OR_DISTINCT(DIImportedEntity, |
6274 | (Context, tag.Val, scope.Val, entity.Val, file.Val, |
6275 | line.Val, name.Val, elements.Val)); |
6276 | return false; |
6277 | } |
6278 | |
6279 | #undef PARSE_MD_FIELD |
6280 | #undef NOP_FIELD |
6281 | #undef REQUIRE_FIELD |
6282 | #undef DECLARE_FIELD |
6283 | |
6284 | /// parseMetadataAsValue |
6285 | /// ::= metadata i32 %local |
6286 | /// ::= metadata i32 @global |
6287 | /// ::= metadata i32 7 |
6288 | /// ::= metadata !0 |
6289 | /// ::= metadata !{...} |
6290 | /// ::= metadata !"string" |
6291 | bool LLParser::parseMetadataAsValue(Value *&V, PerFunctionState &PFS) { |
6292 | // Note: the type 'metadata' has already been parsed. |
6293 | Metadata *MD; |
6294 | if (parseMetadata(MD, PFS: &PFS)) |
6295 | return true; |
6296 | |
6297 | V = MetadataAsValue::get(Context, MD); |
6298 | return false; |
6299 | } |
6300 | |
6301 | /// parseValueAsMetadata |
6302 | /// ::= i32 %local |
6303 | /// ::= i32 @global |
6304 | /// ::= i32 7 |
6305 | bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, |
6306 | PerFunctionState *PFS) { |
6307 | Type *Ty; |
6308 | LocTy Loc; |
6309 | if (parseType(Result&: Ty, Msg: TypeMsg, Loc)) |
6310 | return true; |
6311 | if (Ty->isMetadataTy()) |
6312 | return error(L: Loc, Msg: "invalid metadata-value-metadata roundtrip" ); |
6313 | |
6314 | Value *V; |
6315 | if (parseValue(Ty, V, PFS)) |
6316 | return true; |
6317 | |
6318 | MD = ValueAsMetadata::get(V); |
6319 | return false; |
6320 | } |
6321 | |
6322 | /// parseMetadata |
6323 | /// ::= i32 %local |
6324 | /// ::= i32 @global |
6325 | /// ::= i32 7 |
6326 | /// ::= !42 |
6327 | /// ::= !{...} |
6328 | /// ::= !"string" |
6329 | /// ::= !DILocation(...) |
6330 | bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) { |
6331 | if (Lex.getKind() == lltok::MetadataVar) { |
6332 | // DIArgLists are a special case, as they are a list of ValueAsMetadata and |
6333 | // so parsing this requires a Function State. |
6334 | if (Lex.getStrVal() == "DIArgList" ) { |
6335 | Metadata *AL; |
6336 | if (parseDIArgList(MD&: AL, PFS)) |
6337 | return true; |
6338 | MD = AL; |
6339 | return false; |
6340 | } |
6341 | MDNode *N; |
6342 | if (parseSpecializedMDNode(N)) { |
6343 | return true; |
6344 | } |
6345 | MD = N; |
6346 | return false; |
6347 | } |
6348 | |
6349 | // ValueAsMetadata: |
6350 | // <type> <value> |
6351 | if (Lex.getKind() != lltok::exclaim) |
6352 | return parseValueAsMetadata(MD, TypeMsg: "expected metadata operand" , PFS); |
6353 | |
6354 | // '!'. |
6355 | assert(Lex.getKind() == lltok::exclaim && "Expected '!' here" ); |
6356 | Lex.Lex(); |
6357 | |
6358 | // MDString: |
6359 | // ::= '!' STRINGCONSTANT |
6360 | if (Lex.getKind() == lltok::StringConstant) { |
6361 | MDString *S; |
6362 | if (parseMDString(Result&: S)) |
6363 | return true; |
6364 | MD = S; |
6365 | return false; |
6366 | } |
6367 | |
6368 | // MDNode: |
6369 | // !{ ... } |
6370 | // !7 |
6371 | MDNode *N; |
6372 | if (parseMDNodeTail(N)) |
6373 | return true; |
6374 | MD = N; |
6375 | return false; |
6376 | } |
6377 | |
6378 | //===----------------------------------------------------------------------===// |
6379 | // Function Parsing. |
6380 | //===----------------------------------------------------------------------===// |
6381 | |
6382 | bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V, |
6383 | PerFunctionState *PFS) { |
6384 | if (Ty->isFunctionTy()) |
6385 | return error(L: ID.Loc, Msg: "functions are not values, refer to them as pointers" ); |
6386 | |
6387 | switch (ID.Kind) { |
6388 | case ValID::t_LocalID: |
6389 | if (!PFS) |
6390 | return error(L: ID.Loc, Msg: "invalid use of function-local name" ); |
6391 | V = PFS->getVal(ID: ID.UIntVal, Ty, Loc: ID.Loc); |
6392 | return V == nullptr; |
6393 | case ValID::t_LocalName: |
6394 | if (!PFS) |
6395 | return error(L: ID.Loc, Msg: "invalid use of function-local name" ); |
6396 | V = PFS->getVal(Name: ID.StrVal, Ty, Loc: ID.Loc); |
6397 | return V == nullptr; |
6398 | case ValID::t_InlineAsm: { |
6399 | if (!ID.FTy) |
6400 | return error(L: ID.Loc, Msg: "invalid type for inline asm constraint string" ); |
6401 | if (Error Err = InlineAsm::verify(Ty: ID.FTy, Constraints: ID.StrVal2)) |
6402 | return error(L: ID.Loc, Msg: toString(E: std::move(Err))); |
6403 | V = InlineAsm::get( |
6404 | Ty: ID.FTy, AsmString: ID.StrVal, Constraints: ID.StrVal2, hasSideEffects: ID.UIntVal & 1, isAlignStack: (ID.UIntVal >> 1) & 1, |
6405 | asmDialect: InlineAsm::AsmDialect((ID.UIntVal >> 2) & 1), canThrow: (ID.UIntVal >> 3) & 1); |
6406 | return false; |
6407 | } |
6408 | case ValID::t_GlobalName: |
6409 | V = getGlobalVal(Name: ID.StrVal, Ty, Loc: ID.Loc); |
6410 | if (V && ID.NoCFI) |
6411 | V = NoCFIValue::get(GV: cast<GlobalValue>(Val: V)); |
6412 | return V == nullptr; |
6413 | case ValID::t_GlobalID: |
6414 | V = getGlobalVal(ID: ID.UIntVal, Ty, Loc: ID.Loc); |
6415 | if (V && ID.NoCFI) |
6416 | V = NoCFIValue::get(GV: cast<GlobalValue>(Val: V)); |
6417 | return V == nullptr; |
6418 | case ValID::t_APSInt: |
6419 | if (!Ty->isIntegerTy()) |
6420 | return error(L: ID.Loc, Msg: "integer constant must have integer type" ); |
6421 | ID.APSIntVal = ID.APSIntVal.extOrTrunc(width: Ty->getPrimitiveSizeInBits()); |
6422 | V = ConstantInt::get(Context, V: ID.APSIntVal); |
6423 | return false; |
6424 | case ValID::t_APFloat: |
6425 | if (!Ty->isFloatingPointTy() || |
6426 | !ConstantFP::isValueValidForType(Ty, V: ID.APFloatVal)) |
6427 | return error(L: ID.Loc, Msg: "floating point constant invalid for type" ); |
6428 | |
6429 | // The lexer has no type info, so builds all half, bfloat, float, and double |
6430 | // FP constants as double. Fix this here. Long double does not need this. |
6431 | if (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble()) { |
6432 | // Check for signaling before potentially converting and losing that info. |
6433 | bool IsSNAN = ID.APFloatVal.isSignaling(); |
6434 | bool Ignored; |
6435 | if (Ty->isHalfTy()) |
6436 | ID.APFloatVal.convert(ToSemantics: APFloat::IEEEhalf(), RM: APFloat::rmNearestTiesToEven, |
6437 | losesInfo: &Ignored); |
6438 | else if (Ty->isBFloatTy()) |
6439 | ID.APFloatVal.convert(ToSemantics: APFloat::BFloat(), RM: APFloat::rmNearestTiesToEven, |
6440 | losesInfo: &Ignored); |
6441 | else if (Ty->isFloatTy()) |
6442 | ID.APFloatVal.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, |
6443 | losesInfo: &Ignored); |
6444 | if (IsSNAN) { |
6445 | // The convert call above may quiet an SNaN, so manufacture another |
6446 | // SNaN. The bitcast works because the payload (significand) parameter |
6447 | // is truncated to fit. |
6448 | APInt Payload = ID.APFloatVal.bitcastToAPInt(); |
6449 | ID.APFloatVal = APFloat::getSNaN(Sem: ID.APFloatVal.getSemantics(), |
6450 | Negative: ID.APFloatVal.isNegative(), payload: &Payload); |
6451 | } |
6452 | } |
6453 | V = ConstantFP::get(Context, V: ID.APFloatVal); |
6454 | |
6455 | if (V->getType() != Ty) |
6456 | return error(L: ID.Loc, Msg: "floating point constant does not have type '" + |
6457 | getTypeString(T: Ty) + "'" ); |
6458 | |
6459 | return false; |
6460 | case ValID::t_Null: |
6461 | if (!Ty->isPointerTy()) |
6462 | return error(L: ID.Loc, Msg: "null must be a pointer type" ); |
6463 | V = ConstantPointerNull::get(T: cast<PointerType>(Val: Ty)); |
6464 | return false; |
6465 | case ValID::t_Undef: |
6466 | // FIXME: LabelTy should not be a first-class type. |
6467 | if (!Ty->isFirstClassType() || Ty->isLabelTy()) |
6468 | return error(L: ID.Loc, Msg: "invalid type for undef constant" ); |
6469 | V = UndefValue::get(T: Ty); |
6470 | return false; |
6471 | case ValID::t_EmptyArray: |
6472 | if (!Ty->isArrayTy() || cast<ArrayType>(Val: Ty)->getNumElements() != 0) |
6473 | return error(L: ID.Loc, Msg: "invalid empty array initializer" ); |
6474 | V = PoisonValue::get(T: Ty); |
6475 | return false; |
6476 | case ValID::t_Zero: |
6477 | // FIXME: LabelTy should not be a first-class type. |
6478 | if (!Ty->isFirstClassType() || Ty->isLabelTy()) |
6479 | return error(L: ID.Loc, Msg: "invalid type for null constant" ); |
6480 | if (auto *TETy = dyn_cast<TargetExtType>(Val: Ty)) |
6481 | if (!TETy->hasProperty(Prop: TargetExtType::HasZeroInit)) |
6482 | return error(L: ID.Loc, Msg: "invalid type for null constant" ); |
6483 | V = Constant::getNullValue(Ty); |
6484 | return false; |
6485 | case ValID::t_None: |
6486 | if (!Ty->isTokenTy()) |
6487 | return error(L: ID.Loc, Msg: "invalid type for none constant" ); |
6488 | V = Constant::getNullValue(Ty); |
6489 | return false; |
6490 | case ValID::t_Poison: |
6491 | // FIXME: LabelTy should not be a first-class type. |
6492 | if (!Ty->isFirstClassType() || Ty->isLabelTy()) |
6493 | return error(L: ID.Loc, Msg: "invalid type for poison constant" ); |
6494 | V = PoisonValue::get(T: Ty); |
6495 | return false; |
6496 | case ValID::t_Constant: |
6497 | if (ID.ConstantVal->getType() != Ty) |
6498 | return error(L: ID.Loc, Msg: "constant expression type mismatch: got type '" + |
6499 | getTypeString(T: ID.ConstantVal->getType()) + |
6500 | "' but expected '" + getTypeString(T: Ty) + "'" ); |
6501 | V = ID.ConstantVal; |
6502 | return false; |
6503 | case ValID::t_ConstantSplat: |
6504 | if (!Ty->isVectorTy()) |
6505 | return error(L: ID.Loc, Msg: "vector constant must have vector type" ); |
6506 | if (ID.ConstantVal->getType() != Ty->getScalarType()) |
6507 | return error(L: ID.Loc, Msg: "constant expression type mismatch: got type '" + |
6508 | getTypeString(T: ID.ConstantVal->getType()) + |
6509 | "' but expected '" + |
6510 | getTypeString(T: Ty->getScalarType()) + "'" ); |
6511 | V = ConstantVector::getSplat(EC: cast<VectorType>(Val: Ty)->getElementCount(), |
6512 | Elt: ID.ConstantVal); |
6513 | return false; |
6514 | case ValID::t_ConstantStruct: |
6515 | case ValID::t_PackedConstantStruct: |
6516 | if (StructType *ST = dyn_cast<StructType>(Val: Ty)) { |
6517 | if (ST->getNumElements() != ID.UIntVal) |
6518 | return error(L: ID.Loc, |
6519 | Msg: "initializer with struct type has wrong # elements" ); |
6520 | if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct)) |
6521 | return error(L: ID.Loc, Msg: "packed'ness of initializer and type don't match" ); |
6522 | |
6523 | // Verify that the elements are compatible with the structtype. |
6524 | for (unsigned i = 0, e = ID.UIntVal; i != e; ++i) |
6525 | if (ID.ConstantStructElts[i]->getType() != ST->getElementType(N: i)) |
6526 | return error( |
6527 | L: ID.Loc, |
6528 | Msg: "element " + Twine(i) + |
6529 | " of struct initializer doesn't match struct element type" ); |
6530 | |
6531 | V = ConstantStruct::get( |
6532 | T: ST, V: ArrayRef(ID.ConstantStructElts.get(), ID.UIntVal)); |
6533 | } else |
6534 | return error(L: ID.Loc, Msg: "constant expression type mismatch" ); |
6535 | return false; |
6536 | } |
6537 | llvm_unreachable("Invalid ValID" ); |
6538 | } |
6539 | |
6540 | bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { |
6541 | C = nullptr; |
6542 | ValID ID; |
6543 | auto Loc = Lex.getLoc(); |
6544 | if (parseValID(ID, /*PFS=*/nullptr)) |
6545 | return true; |
6546 | switch (ID.Kind) { |
6547 | case ValID::t_APSInt: |
6548 | case ValID::t_APFloat: |
6549 | case ValID::t_Undef: |
6550 | case ValID::t_Poison: |
6551 | case ValID::t_Zero: |
6552 | case ValID::t_Constant: |
6553 | case ValID::t_ConstantSplat: |
6554 | case ValID::t_ConstantStruct: |
6555 | case ValID::t_PackedConstantStruct: { |
6556 | Value *V; |
6557 | if (convertValIDToValue(Ty, ID, V, /*PFS=*/nullptr)) |
6558 | return true; |
6559 | assert(isa<Constant>(V) && "Expected a constant value" ); |
6560 | C = cast<Constant>(Val: V); |
6561 | return false; |
6562 | } |
6563 | case ValID::t_Null: |
6564 | C = Constant::getNullValue(Ty); |
6565 | return false; |
6566 | default: |
6567 | return error(L: Loc, Msg: "expected a constant value" ); |
6568 | } |
6569 | } |
6570 | |
6571 | bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { |
6572 | V = nullptr; |
6573 | ValID ID; |
6574 | return parseValID(ID, PFS, ExpectedTy: Ty) || |
6575 | convertValIDToValue(Ty, ID, V, PFS); |
6576 | } |
6577 | |
6578 | bool LLParser::parseTypeAndValue(Value *&V, PerFunctionState *PFS) { |
6579 | Type *Ty = nullptr; |
6580 | return parseType(Result&: Ty) || parseValue(Ty, V, PFS); |
6581 | } |
6582 | |
6583 | bool LLParser::parseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, |
6584 | PerFunctionState &PFS) { |
6585 | Value *V; |
6586 | Loc = Lex.getLoc(); |
6587 | if (parseTypeAndValue(V, PFS)) |
6588 | return true; |
6589 | if (!isa<BasicBlock>(Val: V)) |
6590 | return error(L: Loc, Msg: "expected a basic block" ); |
6591 | BB = cast<BasicBlock>(Val: V); |
6592 | return false; |
6593 | } |
6594 | |
6595 | bool isOldDbgFormatIntrinsic(StringRef Name) { |
6596 | // Exit early for the common (non-debug-intrinsic) case. |
6597 | // We can make this the only check when we begin supporting all "llvm.dbg" |
6598 | // intrinsics in the new debug info format. |
6599 | if (!Name.starts_with(Prefix: "llvm.dbg." )) |
6600 | return false; |
6601 | Intrinsic::ID FnID = Intrinsic::lookupIntrinsicID(Name); |
6602 | return FnID == Intrinsic::dbg_declare || FnID == Intrinsic::dbg_value || |
6603 | FnID == Intrinsic::dbg_assign; |
6604 | } |
6605 | |
6606 | /// FunctionHeader |
6607 | /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility |
6608 | /// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName |
6609 | /// '(' ArgList ')' OptAddrSpace OptFuncAttrs OptSection OptionalAlign |
6610 | /// OptGC OptionalPrefix OptionalPrologue OptPersonalityFn |
6611 | bool LLParser::(Function *&Fn, bool IsDefine, |
6612 | unsigned &FunctionNumber, |
6613 | SmallVectorImpl<unsigned> &UnnamedArgNums) { |
6614 | // parse the linkage. |
6615 | LocTy LinkageLoc = Lex.getLoc(); |
6616 | unsigned Linkage; |
6617 | unsigned Visibility; |
6618 | unsigned DLLStorageClass; |
6619 | bool DSOLocal; |
6620 | AttrBuilder RetAttrs(M->getContext()); |
6621 | unsigned CC; |
6622 | bool HasLinkage; |
6623 | Type *RetType = nullptr; |
6624 | LocTy RetTypeLoc = Lex.getLoc(); |
6625 | if (parseOptionalLinkage(Res&: Linkage, HasLinkage, Visibility, DLLStorageClass, |
6626 | DSOLocal) || |
6627 | parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(B&: RetAttrs) || |
6628 | parseType(Result&: RetType, Loc&: RetTypeLoc, AllowVoid: true /*void allowed*/)) |
6629 | return true; |
6630 | |
6631 | // Verify that the linkage is ok. |
6632 | switch ((GlobalValue::LinkageTypes)Linkage) { |
6633 | case GlobalValue::ExternalLinkage: |
6634 | break; // always ok. |
6635 | case GlobalValue::ExternalWeakLinkage: |
6636 | if (IsDefine) |
6637 | return error(L: LinkageLoc, Msg: "invalid linkage for function definition" ); |
6638 | break; |
6639 | case GlobalValue::PrivateLinkage: |
6640 | case GlobalValue::InternalLinkage: |
6641 | case GlobalValue::AvailableExternallyLinkage: |
6642 | case GlobalValue::LinkOnceAnyLinkage: |
6643 | case GlobalValue::LinkOnceODRLinkage: |
6644 | case GlobalValue::WeakAnyLinkage: |
6645 | case GlobalValue::WeakODRLinkage: |
6646 | if (!IsDefine) |
6647 | return error(L: LinkageLoc, Msg: "invalid linkage for function declaration" ); |
6648 | break; |
6649 | case GlobalValue::AppendingLinkage: |
6650 | case GlobalValue::CommonLinkage: |
6651 | return error(L: LinkageLoc, Msg: "invalid function linkage type" ); |
6652 | } |
6653 | |
6654 | if (!isValidVisibilityForLinkage(V: Visibility, L: Linkage)) |
6655 | return error(L: LinkageLoc, |
6656 | Msg: "symbol with local linkage must have default visibility" ); |
6657 | |
6658 | if (!isValidDLLStorageClassForLinkage(S: DLLStorageClass, L: Linkage)) |
6659 | return error(L: LinkageLoc, |
6660 | Msg: "symbol with local linkage cannot have a DLL storage class" ); |
6661 | |
6662 | if (!FunctionType::isValidReturnType(RetTy: RetType)) |
6663 | return error(L: RetTypeLoc, Msg: "invalid function return type" ); |
6664 | |
6665 | LocTy NameLoc = Lex.getLoc(); |
6666 | |
6667 | std::string FunctionName; |
6668 | if (Lex.getKind() == lltok::GlobalVar) { |
6669 | FunctionName = Lex.getStrVal(); |
6670 | } else if (Lex.getKind() == lltok::GlobalID) { // @42 is ok. |
6671 | FunctionNumber = Lex.getUIntVal(); |
6672 | if (checkValueID(Loc: NameLoc, Kind: "function" , Prefix: "@" , NextID: NumberedVals.getNext(), |
6673 | ID: FunctionNumber)) |
6674 | return true; |
6675 | } else { |
6676 | return tokError(Msg: "expected function name" ); |
6677 | } |
6678 | |
6679 | Lex.Lex(); |
6680 | |
6681 | if (Lex.getKind() != lltok::lparen) |
6682 | return tokError(Msg: "expected '(' in function argument list" ); |
6683 | |
6684 | SmallVector<ArgInfo, 8> ArgList; |
6685 | bool IsVarArg; |
6686 | AttrBuilder FuncAttrs(M->getContext()); |
6687 | std::vector<unsigned> FwdRefAttrGrps; |
6688 | LocTy BuiltinLoc; |
6689 | std::string Section; |
6690 | std::string Partition; |
6691 | MaybeAlign Alignment; |
6692 | std::string GC; |
6693 | GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; |
6694 | unsigned AddrSpace = 0; |
6695 | Constant *Prefix = nullptr; |
6696 | Constant *Prologue = nullptr; |
6697 | Constant *PersonalityFn = nullptr; |
6698 | Comdat *C; |
6699 | |
6700 | if (parseArgumentList(ArgList, UnnamedArgNums, IsVarArg) || |
6701 | parseOptionalUnnamedAddr(UnnamedAddr) || |
6702 | parseOptionalProgramAddrSpace(AddrSpace) || |
6703 | parseFnAttributeValuePairs(B&: FuncAttrs, FwdRefAttrGrps, InAttrGrp: false, |
6704 | BuiltinLoc) || |
6705 | (EatIfPresent(T: lltok::kw_section) && parseStringConstant(Result&: Section)) || |
6706 | (EatIfPresent(T: lltok::kw_partition) && parseStringConstant(Result&: Partition)) || |
6707 | parseOptionalComdat(GlobalName: FunctionName, C) || |
6708 | parseOptionalAlignment(Alignment) || |
6709 | (EatIfPresent(T: lltok::kw_gc) && parseStringConstant(Result&: GC)) || |
6710 | (EatIfPresent(T: lltok::kw_prefix) && parseGlobalTypeAndValue(V&: Prefix)) || |
6711 | (EatIfPresent(T: lltok::kw_prologue) && parseGlobalTypeAndValue(V&: Prologue)) || |
6712 | (EatIfPresent(T: lltok::kw_personality) && |
6713 | parseGlobalTypeAndValue(V&: PersonalityFn))) |
6714 | return true; |
6715 | |
6716 | if (FuncAttrs.contains(A: Attribute::Builtin)) |
6717 | return error(L: BuiltinLoc, Msg: "'builtin' attribute not valid on function" ); |
6718 | |
6719 | // If the alignment was parsed as an attribute, move to the alignment field. |
6720 | if (MaybeAlign A = FuncAttrs.getAlignment()) { |
6721 | Alignment = A; |
6722 | FuncAttrs.removeAttribute(Val: Attribute::Alignment); |
6723 | } |
6724 | |
6725 | // Okay, if we got here, the function is syntactically valid. Convert types |
6726 | // and do semantic checks. |
6727 | std::vector<Type*> ParamTypeList; |
6728 | SmallVector<AttributeSet, 8> Attrs; |
6729 | |
6730 | for (const ArgInfo &Arg : ArgList) { |
6731 | ParamTypeList.push_back(x: Arg.Ty); |
6732 | Attrs.push_back(Elt: Arg.Attrs); |
6733 | } |
6734 | |
6735 | AttributeList PAL = |
6736 | AttributeList::get(C&: Context, FnAttrs: AttributeSet::get(C&: Context, B: FuncAttrs), |
6737 | RetAttrs: AttributeSet::get(C&: Context, B: RetAttrs), ArgAttrs: Attrs); |
6738 | |
6739 | if (PAL.hasParamAttr(ArgNo: 0, Kind: Attribute::StructRet) && !RetType->isVoidTy()) |
6740 | return error(L: RetTypeLoc, Msg: "functions with 'sret' argument must return void" ); |
6741 | |
6742 | FunctionType *FT = FunctionType::get(Result: RetType, Params: ParamTypeList, isVarArg: IsVarArg); |
6743 | PointerType *PFT = PointerType::get(C&: Context, AddressSpace: AddrSpace); |
6744 | |
6745 | Fn = nullptr; |
6746 | GlobalValue *FwdFn = nullptr; |
6747 | if (!FunctionName.empty()) { |
6748 | // If this was a definition of a forward reference, remove the definition |
6749 | // from the forward reference table and fill in the forward ref. |
6750 | auto FRVI = ForwardRefVals.find(x: FunctionName); |
6751 | if (FRVI != ForwardRefVals.end()) { |
6752 | FwdFn = FRVI->second.first; |
6753 | if (FwdFn->getType() != PFT) |
6754 | return error(L: FRVI->second.second, |
6755 | Msg: "invalid forward reference to " |
6756 | "function '" + |
6757 | FunctionName + |
6758 | "' with wrong type: " |
6759 | "expected '" + |
6760 | getTypeString(T: PFT) + "' but was '" + |
6761 | getTypeString(T: FwdFn->getType()) + "'" ); |
6762 | ForwardRefVals.erase(position: FRVI); |
6763 | } else if ((Fn = M->getFunction(Name: FunctionName))) { |
6764 | // Reject redefinitions. |
6765 | return error(L: NameLoc, |
6766 | Msg: "invalid redefinition of function '" + FunctionName + "'" ); |
6767 | } else if (M->getNamedValue(Name: FunctionName)) { |
6768 | return error(L: NameLoc, Msg: "redefinition of function '@" + FunctionName + "'" ); |
6769 | } |
6770 | |
6771 | } else { |
6772 | // Handle @"", where a name is syntactically specified, but semantically |
6773 | // missing. |
6774 | if (FunctionNumber == (unsigned)-1) |
6775 | FunctionNumber = NumberedVals.getNext(); |
6776 | |
6777 | // If this is a definition of a forward referenced function, make sure the |
6778 | // types agree. |
6779 | auto I = ForwardRefValIDs.find(x: FunctionNumber); |
6780 | if (I != ForwardRefValIDs.end()) { |
6781 | FwdFn = I->second.first; |
6782 | if (FwdFn->getType() != PFT) |
6783 | return error(L: NameLoc, Msg: "type of definition and forward reference of '@" + |
6784 | Twine(FunctionNumber) + |
6785 | "' disagree: " |
6786 | "expected '" + |
6787 | getTypeString(T: PFT) + "' but was '" + |
6788 | getTypeString(T: FwdFn->getType()) + "'" ); |
6789 | ForwardRefValIDs.erase(position: I); |
6790 | } |
6791 | } |
6792 | |
6793 | Fn = Function::Create(Ty: FT, Linkage: GlobalValue::ExternalLinkage, AddrSpace, |
6794 | N: FunctionName, M); |
6795 | |
6796 | assert(Fn->getAddressSpace() == AddrSpace && "Created function in wrong AS" ); |
6797 | |
6798 | if (FunctionName.empty()) |
6799 | NumberedVals.add(ID: FunctionNumber, V: Fn); |
6800 | |
6801 | Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); |
6802 | maybeSetDSOLocal(DSOLocal, GV&: *Fn); |
6803 | Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); |
6804 | Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); |
6805 | Fn->setCallingConv(CC); |
6806 | Fn->setAttributes(PAL); |
6807 | Fn->setUnnamedAddr(UnnamedAddr); |
6808 | if (Alignment) |
6809 | Fn->setAlignment(*Alignment); |
6810 | Fn->setSection(Section); |
6811 | Fn->setPartition(Partition); |
6812 | Fn->setComdat(C); |
6813 | Fn->setPersonalityFn(PersonalityFn); |
6814 | if (!GC.empty()) Fn->setGC(GC); |
6815 | Fn->setPrefixData(Prefix); |
6816 | Fn->setPrologueData(Prologue); |
6817 | ForwardRefAttrGroups[Fn] = FwdRefAttrGrps; |
6818 | |
6819 | // Add all of the arguments we parsed to the function. |
6820 | Function::arg_iterator ArgIt = Fn->arg_begin(); |
6821 | for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) { |
6822 | // If the argument has a name, insert it into the argument symbol table. |
6823 | if (ArgList[i].Name.empty()) continue; |
6824 | |
6825 | // Set the name, if it conflicted, it will be auto-renamed. |
6826 | ArgIt->setName(ArgList[i].Name); |
6827 | |
6828 | if (ArgIt->getName() != ArgList[i].Name) |
6829 | return error(L: ArgList[i].Loc, |
6830 | Msg: "redefinition of argument '%" + ArgList[i].Name + "'" ); |
6831 | } |
6832 | |
6833 | if (FwdFn) { |
6834 | FwdFn->replaceAllUsesWith(V: Fn); |
6835 | FwdFn->eraseFromParent(); |
6836 | } |
6837 | |
6838 | if (IsDefine) |
6839 | return false; |
6840 | |
6841 | // Check the declaration has no block address forward references. |
6842 | ValID ID; |
6843 | if (FunctionName.empty()) { |
6844 | ID.Kind = ValID::t_GlobalID; |
6845 | ID.UIntVal = FunctionNumber; |
6846 | } else { |
6847 | ID.Kind = ValID::t_GlobalName; |
6848 | ID.StrVal = FunctionName; |
6849 | } |
6850 | auto Blocks = ForwardRefBlockAddresses.find(x: ID); |
6851 | if (Blocks != ForwardRefBlockAddresses.end()) |
6852 | return error(L: Blocks->first.Loc, |
6853 | Msg: "cannot take blockaddress inside a declaration" ); |
6854 | return false; |
6855 | } |
6856 | |
6857 | bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() { |
6858 | ValID ID; |
6859 | if (FunctionNumber == -1) { |
6860 | ID.Kind = ValID::t_GlobalName; |
6861 | ID.StrVal = std::string(F.getName()); |
6862 | } else { |
6863 | ID.Kind = ValID::t_GlobalID; |
6864 | ID.UIntVal = FunctionNumber; |
6865 | } |
6866 | |
6867 | auto Blocks = P.ForwardRefBlockAddresses.find(x: ID); |
6868 | if (Blocks == P.ForwardRefBlockAddresses.end()) |
6869 | return false; |
6870 | |
6871 | for (const auto &I : Blocks->second) { |
6872 | const ValID &BBID = I.first; |
6873 | GlobalValue *GV = I.second; |
6874 | |
6875 | assert((BBID.Kind == ValID::t_LocalID || BBID.Kind == ValID::t_LocalName) && |
6876 | "Expected local id or name" ); |
6877 | BasicBlock *BB; |
6878 | if (BBID.Kind == ValID::t_LocalName) |
6879 | BB = getBB(Name: BBID.StrVal, Loc: BBID.Loc); |
6880 | else |
6881 | BB = getBB(ID: BBID.UIntVal, Loc: BBID.Loc); |
6882 | if (!BB) |
6883 | return P.error(L: BBID.Loc, Msg: "referenced value is not a basic block" ); |
6884 | |
6885 | Value *ResolvedVal = BlockAddress::get(F: &F, BB); |
6886 | ResolvedVal = P.checkValidVariableType(Loc: BBID.Loc, Name: BBID.StrVal, Ty: GV->getType(), |
6887 | Val: ResolvedVal); |
6888 | if (!ResolvedVal) |
6889 | return true; |
6890 | GV->replaceAllUsesWith(V: ResolvedVal); |
6891 | GV->eraseFromParent(); |
6892 | } |
6893 | |
6894 | P.ForwardRefBlockAddresses.erase(position: Blocks); |
6895 | return false; |
6896 | } |
6897 | |
6898 | /// parseFunctionBody |
6899 | /// ::= '{' BasicBlock+ UseListOrderDirective* '}' |
6900 | bool LLParser::parseFunctionBody(Function &Fn, unsigned FunctionNumber, |
6901 | ArrayRef<unsigned> UnnamedArgNums) { |
6902 | if (Lex.getKind() != lltok::lbrace) |
6903 | return tokError(Msg: "expected '{' in function body" ); |
6904 | Lex.Lex(); // eat the {. |
6905 | |
6906 | PerFunctionState PFS(*this, Fn, FunctionNumber, UnnamedArgNums); |
6907 | |
6908 | // Resolve block addresses and allow basic blocks to be forward-declared |
6909 | // within this function. |
6910 | if (PFS.resolveForwardRefBlockAddresses()) |
6911 | return true; |
6912 | SaveAndRestore ScopeExit(BlockAddressPFS, &PFS); |
6913 | |
6914 | // We need at least one basic block. |
6915 | if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_uselistorder) |
6916 | return tokError(Msg: "function body requires at least one basic block" ); |
6917 | |
6918 | while (Lex.getKind() != lltok::rbrace && |
6919 | Lex.getKind() != lltok::kw_uselistorder) |
6920 | if (parseBasicBlock(PFS)) |
6921 | return true; |
6922 | |
6923 | while (Lex.getKind() != lltok::rbrace) |
6924 | if (parseUseListOrder(PFS: &PFS)) |
6925 | return true; |
6926 | |
6927 | // Eat the }. |
6928 | Lex.Lex(); |
6929 | |
6930 | // Verify function is ok. |
6931 | return PFS.finishFunction(); |
6932 | } |
6933 | |
6934 | /// parseBasicBlock |
6935 | /// ::= (LabelStr|LabelID)? Instruction* |
6936 | bool LLParser::parseBasicBlock(PerFunctionState &PFS) { |
6937 | // If this basic block starts out with a name, remember it. |
6938 | std::string Name; |
6939 | int NameID = -1; |
6940 | LocTy NameLoc = Lex.getLoc(); |
6941 | if (Lex.getKind() == lltok::LabelStr) { |
6942 | Name = Lex.getStrVal(); |
6943 | Lex.Lex(); |
6944 | } else if (Lex.getKind() == lltok::LabelID) { |
6945 | NameID = Lex.getUIntVal(); |
6946 | Lex.Lex(); |
6947 | } |
6948 | |
6949 | BasicBlock *BB = PFS.defineBB(Name, NameID, Loc: NameLoc); |
6950 | if (!BB) |
6951 | return true; |
6952 | |
6953 | std::string NameStr; |
6954 | |
6955 | // Parse the instructions and debug values in this block until we get a |
6956 | // terminator. |
6957 | Instruction *Inst; |
6958 | auto DeleteDbgRecord = [](DbgRecord *DR) { DR->deleteRecord(); }; |
6959 | using DbgRecordPtr = std::unique_ptr<DbgRecord, decltype(DeleteDbgRecord)>; |
6960 | SmallVector<DbgRecordPtr> TrailingDbgRecord; |
6961 | do { |
6962 | // Handle debug records first - there should always be an instruction |
6963 | // following the debug records, i.e. they cannot appear after the block |
6964 | // terminator. |
6965 | while (Lex.getKind() == lltok::hash) { |
6966 | if (SeenOldDbgInfoFormat) |
6967 | return error(L: Lex.getLoc(), Msg: "debug record should not appear in a module " |
6968 | "containing debug info intrinsics" ); |
6969 | SeenNewDbgInfoFormat = true; |
6970 | Lex.Lex(); |
6971 | |
6972 | DbgRecord *DR; |
6973 | if (parseDebugRecord(DR, PFS)) |
6974 | return true; |
6975 | TrailingDbgRecord.emplace_back(Args&: DR, Args&: DeleteDbgRecord); |
6976 | } |
6977 | |
6978 | // This instruction may have three possibilities for a name: a) none |
6979 | // specified, b) name specified "%foo =", c) number specified: "%4 =". |
6980 | LocTy NameLoc = Lex.getLoc(); |
6981 | int NameID = -1; |
6982 | NameStr = "" ; |
6983 | |
6984 | if (Lex.getKind() == lltok::LocalVarID) { |
6985 | NameID = Lex.getUIntVal(); |
6986 | Lex.Lex(); |
6987 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after instruction id" )) |
6988 | return true; |
6989 | } else if (Lex.getKind() == lltok::LocalVar) { |
6990 | NameStr = Lex.getStrVal(); |
6991 | Lex.Lex(); |
6992 | if (parseToken(T: lltok::equal, ErrMsg: "expected '=' after instruction name" )) |
6993 | return true; |
6994 | } |
6995 | |
6996 | switch (parseInstruction(Inst, BB, PFS)) { |
6997 | default: |
6998 | llvm_unreachable("Unknown parseInstruction result!" ); |
6999 | case InstError: return true; |
7000 | case InstNormal: |
7001 | Inst->insertInto(ParentBB: BB, It: BB->end()); |
7002 | |
7003 | // With a normal result, we check to see if the instruction is followed by |
7004 | // a comma and metadata. |
7005 | if (EatIfPresent(T: lltok::comma)) |
7006 | if (parseInstructionMetadata(Inst&: *Inst)) |
7007 | return true; |
7008 | break; |
7009 | case InstExtraComma: |
7010 | Inst->insertInto(ParentBB: BB, It: BB->end()); |
7011 | |
7012 | // If the instruction parser ate an extra comma at the end of it, it |
7013 | // *must* be followed by metadata. |
7014 | if (parseInstructionMetadata(Inst&: *Inst)) |
7015 | return true; |
7016 | break; |
7017 | } |
7018 | |
7019 | // Set the name on the instruction. |
7020 | if (PFS.setInstName(NameID, NameStr, NameLoc, Inst)) |
7021 | return true; |
7022 | |
7023 | // Attach any preceding debug values to this instruction. |
7024 | for (DbgRecordPtr &DR : TrailingDbgRecord) |
7025 | BB->insertDbgRecordBefore(DR: DR.release(), Here: Inst->getIterator()); |
7026 | TrailingDbgRecord.clear(); |
7027 | } while (!Inst->isTerminator()); |
7028 | |
7029 | assert(TrailingDbgRecord.empty() && |
7030 | "All debug values should have been attached to an instruction." ); |
7031 | |
7032 | return false; |
7033 | } |
7034 | |
7035 | /// parseDebugRecord |
7036 | /// ::= #dbg_label '(' MDNode ')' |
7037 | /// ::= #dbg_type '(' Metadata ',' MDNode ',' Metadata ',' |
7038 | /// (MDNode ',' Metadata ',' Metadata ',')? MDNode ')' |
7039 | bool LLParser::parseDebugRecord(DbgRecord *&DR, PerFunctionState &PFS) { |
7040 | using RecordKind = DbgRecord::Kind; |
7041 | using LocType = DbgVariableRecord::LocationType; |
7042 | LocTy DVRLoc = Lex.getLoc(); |
7043 | if (Lex.getKind() != lltok::DbgRecordType) |
7044 | return error(L: DVRLoc, Msg: "expected debug record type here" ); |
7045 | RecordKind RecordType = StringSwitch<RecordKind>(Lex.getStrVal()) |
7046 | .Case(S: "declare" , Value: RecordKind::ValueKind) |
7047 | .Case(S: "value" , Value: RecordKind::ValueKind) |
7048 | .Case(S: "assign" , Value: RecordKind::ValueKind) |
7049 | .Case(S: "label" , Value: RecordKind::LabelKind); |
7050 | |
7051 | // Parsing labels is trivial; parse here and early exit, otherwise go into the |
7052 | // full DbgVariableRecord processing stage. |
7053 | if (RecordType == RecordKind::LabelKind) { |
7054 | Lex.Lex(); |
7055 | if (parseToken(T: lltok::lparen, ErrMsg: "Expected '(' here" )) |
7056 | return true; |
7057 | MDNode *Label; |
7058 | if (parseMDNode(N&: Label)) |
7059 | return true; |
7060 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7061 | return true; |
7062 | MDNode *DbgLoc; |
7063 | if (parseMDNode(N&: DbgLoc)) |
7064 | return true; |
7065 | if (parseToken(T: lltok::rparen, ErrMsg: "Expected ')' here" )) |
7066 | return true; |
7067 | DR = DbgLabelRecord::createUnresolvedDbgLabelRecord(Label, DL: DbgLoc); |
7068 | return false; |
7069 | } |
7070 | |
7071 | LocType ValueType = StringSwitch<LocType>(Lex.getStrVal()) |
7072 | .Case(S: "declare" , Value: LocType::Declare) |
7073 | .Case(S: "value" , Value: LocType::Value) |
7074 | .Case(S: "assign" , Value: LocType::Assign); |
7075 | |
7076 | Lex.Lex(); |
7077 | if (parseToken(T: lltok::lparen, ErrMsg: "Expected '(' here" )) |
7078 | return true; |
7079 | |
7080 | // Parse Value field. |
7081 | Metadata *ValLocMD; |
7082 | if (parseMetadata(MD&: ValLocMD, PFS: &PFS)) |
7083 | return true; |
7084 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7085 | return true; |
7086 | |
7087 | // Parse Variable field. |
7088 | MDNode *Variable; |
7089 | if (parseMDNode(N&: Variable)) |
7090 | return true; |
7091 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7092 | return true; |
7093 | |
7094 | // Parse Expression field. |
7095 | MDNode *Expression; |
7096 | if (parseMDNode(N&: Expression)) |
7097 | return true; |
7098 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7099 | return true; |
7100 | |
7101 | // Parse additional fields for #dbg_assign. |
7102 | MDNode *AssignID = nullptr; |
7103 | Metadata *AddressLocation = nullptr; |
7104 | MDNode *AddressExpression = nullptr; |
7105 | if (ValueType == LocType::Assign) { |
7106 | // Parse DIAssignID. |
7107 | if (parseMDNode(N&: AssignID)) |
7108 | return true; |
7109 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7110 | return true; |
7111 | |
7112 | // Parse address ValueAsMetadata. |
7113 | if (parseMetadata(MD&: AddressLocation, PFS: &PFS)) |
7114 | return true; |
7115 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7116 | return true; |
7117 | |
7118 | // Parse address DIExpression. |
7119 | if (parseMDNode(N&: AddressExpression)) |
7120 | return true; |
7121 | if (parseToken(T: lltok::comma, ErrMsg: "Expected ',' here" )) |
7122 | return true; |
7123 | } |
7124 | |
7125 | /// Parse DILocation. |
7126 | MDNode *DebugLoc; |
7127 | if (parseMDNode(N&: DebugLoc)) |
7128 | return true; |
7129 | |
7130 | if (parseToken(T: lltok::rparen, ErrMsg: "Expected ')' here" )) |
7131 | return true; |
7132 | DR = DbgVariableRecord::createUnresolvedDbgVariableRecord( |
7133 | Type: ValueType, Val: ValLocMD, Variable, Expression, AssignID, Address: AddressLocation, |
7134 | AddressExpression, DI: DebugLoc); |
7135 | return false; |
7136 | } |
7137 | //===----------------------------------------------------------------------===// |
7138 | // Instruction Parsing. |
7139 | //===----------------------------------------------------------------------===// |
7140 | |
7141 | /// parseInstruction - parse one of the many different instructions. |
7142 | /// |
7143 | int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB, |
7144 | PerFunctionState &PFS) { |
7145 | lltok::Kind Token = Lex.getKind(); |
7146 | if (Token == lltok::Eof) |
7147 | return tokError(Msg: "found end of file when expecting more instructions" ); |
7148 | LocTy Loc = Lex.getLoc(); |
7149 | unsigned KeywordVal = Lex.getUIntVal(); |
7150 | Lex.Lex(); // Eat the keyword. |
7151 | |
7152 | switch (Token) { |
7153 | default: |
7154 | return error(L: Loc, Msg: "expected instruction opcode" ); |
7155 | // Terminator Instructions. |
7156 | case lltok::kw_unreachable: Inst = new UnreachableInst(Context); return false; |
7157 | case lltok::kw_ret: |
7158 | return parseRet(Inst, BB, PFS); |
7159 | case lltok::kw_br: |
7160 | return parseBr(Inst, PFS); |
7161 | case lltok::kw_switch: |
7162 | return parseSwitch(Inst, PFS); |
7163 | case lltok::kw_indirectbr: |
7164 | return parseIndirectBr(Inst, PFS); |
7165 | case lltok::kw_invoke: |
7166 | return parseInvoke(Inst, PFS); |
7167 | case lltok::kw_resume: |
7168 | return parseResume(Inst, PFS); |
7169 | case lltok::kw_cleanupret: |
7170 | return parseCleanupRet(Inst, PFS); |
7171 | case lltok::kw_catchret: |
7172 | return parseCatchRet(Inst, PFS); |
7173 | case lltok::kw_catchswitch: |
7174 | return parseCatchSwitch(Inst, PFS); |
7175 | case lltok::kw_catchpad: |
7176 | return parseCatchPad(Inst, PFS); |
7177 | case lltok::kw_cleanuppad: |
7178 | return parseCleanupPad(Inst, PFS); |
7179 | case lltok::kw_callbr: |
7180 | return parseCallBr(Inst, PFS); |
7181 | // Unary Operators. |
7182 | case lltok::kw_fneg: { |
7183 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
7184 | int Res = parseUnaryOp(Inst, PFS, Opc: KeywordVal, /*IsFP*/ true); |
7185 | if (Res != 0) |
7186 | return Res; |
7187 | if (FMF.any()) |
7188 | Inst->setFastMathFlags(FMF); |
7189 | return false; |
7190 | } |
7191 | // Binary Operators. |
7192 | case lltok::kw_add: |
7193 | case lltok::kw_sub: |
7194 | case lltok::kw_mul: |
7195 | case lltok::kw_shl: { |
7196 | bool NUW = EatIfPresent(T: lltok::kw_nuw); |
7197 | bool NSW = EatIfPresent(T: lltok::kw_nsw); |
7198 | if (!NUW) NUW = EatIfPresent(T: lltok::kw_nuw); |
7199 | |
7200 | if (parseArithmetic(Inst, PFS, Opc: KeywordVal, /*IsFP*/ false)) |
7201 | return true; |
7202 | |
7203 | if (NUW) cast<BinaryOperator>(Val: Inst)->setHasNoUnsignedWrap(true); |
7204 | if (NSW) cast<BinaryOperator>(Val: Inst)->setHasNoSignedWrap(true); |
7205 | return false; |
7206 | } |
7207 | case lltok::kw_fadd: |
7208 | case lltok::kw_fsub: |
7209 | case lltok::kw_fmul: |
7210 | case lltok::kw_fdiv: |
7211 | case lltok::kw_frem: { |
7212 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
7213 | int Res = parseArithmetic(Inst, PFS, Opc: KeywordVal, /*IsFP*/ true); |
7214 | if (Res != 0) |
7215 | return Res; |
7216 | if (FMF.any()) |
7217 | Inst->setFastMathFlags(FMF); |
7218 | return 0; |
7219 | } |
7220 | |
7221 | case lltok::kw_sdiv: |
7222 | case lltok::kw_udiv: |
7223 | case lltok::kw_lshr: |
7224 | case lltok::kw_ashr: { |
7225 | bool Exact = EatIfPresent(T: lltok::kw_exact); |
7226 | |
7227 | if (parseArithmetic(Inst, PFS, Opc: KeywordVal, /*IsFP*/ false)) |
7228 | return true; |
7229 | if (Exact) cast<BinaryOperator>(Val: Inst)->setIsExact(true); |
7230 | return false; |
7231 | } |
7232 | |
7233 | case lltok::kw_urem: |
7234 | case lltok::kw_srem: |
7235 | return parseArithmetic(Inst, PFS, Opc: KeywordVal, |
7236 | /*IsFP*/ false); |
7237 | case lltok::kw_or: { |
7238 | bool Disjoint = EatIfPresent(T: lltok::kw_disjoint); |
7239 | if (parseLogical(Inst, PFS, Opc: KeywordVal)) |
7240 | return true; |
7241 | if (Disjoint) |
7242 | cast<PossiblyDisjointInst>(Val: Inst)->setIsDisjoint(true); |
7243 | return false; |
7244 | } |
7245 | case lltok::kw_and: |
7246 | case lltok::kw_xor: |
7247 | return parseLogical(Inst, PFS, Opc: KeywordVal); |
7248 | case lltok::kw_icmp: { |
7249 | bool SameSign = EatIfPresent(T: lltok::kw_samesign); |
7250 | if (parseCompare(Inst, PFS, Opc: KeywordVal)) |
7251 | return true; |
7252 | if (SameSign) |
7253 | cast<ICmpInst>(Val: Inst)->setSameSign(); |
7254 | return false; |
7255 | } |
7256 | case lltok::kw_fcmp: { |
7257 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
7258 | int Res = parseCompare(Inst, PFS, Opc: KeywordVal); |
7259 | if (Res != 0) |
7260 | return Res; |
7261 | if (FMF.any()) |
7262 | Inst->setFastMathFlags(FMF); |
7263 | return 0; |
7264 | } |
7265 | |
7266 | // Casts. |
7267 | case lltok::kw_uitofp: |
7268 | case lltok::kw_zext: { |
7269 | bool NonNeg = EatIfPresent(T: lltok::kw_nneg); |
7270 | bool Res = parseCast(Inst, PFS, Opc: KeywordVal); |
7271 | if (Res != 0) |
7272 | return Res; |
7273 | if (NonNeg) |
7274 | Inst->setNonNeg(); |
7275 | return 0; |
7276 | } |
7277 | case lltok::kw_trunc: { |
7278 | bool NUW = EatIfPresent(T: lltok::kw_nuw); |
7279 | bool NSW = EatIfPresent(T: lltok::kw_nsw); |
7280 | if (!NUW) |
7281 | NUW = EatIfPresent(T: lltok::kw_nuw); |
7282 | if (parseCast(Inst, PFS, Opc: KeywordVal)) |
7283 | return true; |
7284 | if (NUW) |
7285 | cast<TruncInst>(Val: Inst)->setHasNoUnsignedWrap(true); |
7286 | if (NSW) |
7287 | cast<TruncInst>(Val: Inst)->setHasNoSignedWrap(true); |
7288 | return false; |
7289 | } |
7290 | case lltok::kw_sext: |
7291 | case lltok::kw_bitcast: |
7292 | case lltok::kw_addrspacecast: |
7293 | case lltok::kw_sitofp: |
7294 | case lltok::kw_fptoui: |
7295 | case lltok::kw_fptosi: |
7296 | case lltok::kw_inttoptr: |
7297 | case lltok::kw_ptrtoint: |
7298 | return parseCast(Inst, PFS, Opc: KeywordVal); |
7299 | case lltok::kw_fptrunc: |
7300 | case lltok::kw_fpext: { |
7301 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
7302 | if (parseCast(Inst, PFS, Opc: KeywordVal)) |
7303 | return true; |
7304 | if (FMF.any()) |
7305 | Inst->setFastMathFlags(FMF); |
7306 | return false; |
7307 | } |
7308 | |
7309 | // Other. |
7310 | case lltok::kw_select: { |
7311 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
7312 | int Res = parseSelect(Inst, PFS); |
7313 | if (Res != 0) |
7314 | return Res; |
7315 | if (FMF.any()) { |
7316 | if (!isa<FPMathOperator>(Val: Inst)) |
7317 | return error(L: Loc, Msg: "fast-math-flags specified for select without " |
7318 | "floating-point scalar or vector return type" ); |
7319 | Inst->setFastMathFlags(FMF); |
7320 | } |
7321 | return 0; |
7322 | } |
7323 | case lltok::kw_va_arg: |
7324 | return parseVAArg(Inst, PFS); |
7325 | case lltok::kw_extractelement: |
7326 | return parseExtractElement(Inst, PFS); |
7327 | case lltok::kw_insertelement: |
7328 | return parseInsertElement(Inst, PFS); |
7329 | case lltok::kw_shufflevector: |
7330 | return parseShuffleVector(Inst, PFS); |
7331 | case lltok::kw_phi: { |
7332 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
7333 | int Res = parsePHI(Inst, PFS); |
7334 | if (Res != 0) |
7335 | return Res; |
7336 | if (FMF.any()) { |
7337 | if (!isa<FPMathOperator>(Val: Inst)) |
7338 | return error(L: Loc, Msg: "fast-math-flags specified for phi without " |
7339 | "floating-point scalar or vector return type" ); |
7340 | Inst->setFastMathFlags(FMF); |
7341 | } |
7342 | return 0; |
7343 | } |
7344 | case lltok::kw_landingpad: |
7345 | return parseLandingPad(Inst, PFS); |
7346 | case lltok::kw_freeze: |
7347 | return parseFreeze(I&: Inst, PFS); |
7348 | // Call. |
7349 | case lltok::kw_call: |
7350 | return parseCall(Inst, PFS, TCK: CallInst::TCK_None); |
7351 | case lltok::kw_tail: |
7352 | return parseCall(Inst, PFS, TCK: CallInst::TCK_Tail); |
7353 | case lltok::kw_musttail: |
7354 | return parseCall(Inst, PFS, TCK: CallInst::TCK_MustTail); |
7355 | case lltok::kw_notail: |
7356 | return parseCall(Inst, PFS, TCK: CallInst::TCK_NoTail); |
7357 | // Memory. |
7358 | case lltok::kw_alloca: |
7359 | return parseAlloc(Inst, PFS); |
7360 | case lltok::kw_load: |
7361 | return parseLoad(Inst, PFS); |
7362 | case lltok::kw_store: |
7363 | return parseStore(Inst, PFS); |
7364 | case lltok::kw_cmpxchg: |
7365 | return parseCmpXchg(Inst, PFS); |
7366 | case lltok::kw_atomicrmw: |
7367 | return parseAtomicRMW(Inst, PFS); |
7368 | case lltok::kw_fence: |
7369 | return parseFence(Inst, PFS); |
7370 | case lltok::kw_getelementptr: |
7371 | return parseGetElementPtr(Inst, PFS); |
7372 | case lltok::kw_extractvalue: |
7373 | return parseExtractValue(Inst, PFS); |
7374 | case lltok::kw_insertvalue: |
7375 | return parseInsertValue(Inst, PFS); |
7376 | } |
7377 | } |
7378 | |
7379 | /// parseCmpPredicate - parse an integer or fp predicate, based on Kind. |
7380 | bool LLParser::parseCmpPredicate(unsigned &P, unsigned Opc) { |
7381 | if (Opc == Instruction::FCmp) { |
7382 | switch (Lex.getKind()) { |
7383 | default: |
7384 | return tokError(Msg: "expected fcmp predicate (e.g. 'oeq')" ); |
7385 | case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break; |
7386 | case lltok::kw_one: P = CmpInst::FCMP_ONE; break; |
7387 | case lltok::kw_olt: P = CmpInst::FCMP_OLT; break; |
7388 | case lltok::kw_ogt: P = CmpInst::FCMP_OGT; break; |
7389 | case lltok::kw_ole: P = CmpInst::FCMP_OLE; break; |
7390 | case lltok::kw_oge: P = CmpInst::FCMP_OGE; break; |
7391 | case lltok::kw_ord: P = CmpInst::FCMP_ORD; break; |
7392 | case lltok::kw_uno: P = CmpInst::FCMP_UNO; break; |
7393 | case lltok::kw_ueq: P = CmpInst::FCMP_UEQ; break; |
7394 | case lltok::kw_une: P = CmpInst::FCMP_UNE; break; |
7395 | case lltok::kw_ult: P = CmpInst::FCMP_ULT; break; |
7396 | case lltok::kw_ugt: P = CmpInst::FCMP_UGT; break; |
7397 | case lltok::kw_ule: P = CmpInst::FCMP_ULE; break; |
7398 | case lltok::kw_uge: P = CmpInst::FCMP_UGE; break; |
7399 | case lltok::kw_true: P = CmpInst::FCMP_TRUE; break; |
7400 | case lltok::kw_false: P = CmpInst::FCMP_FALSE; break; |
7401 | } |
7402 | } else { |
7403 | switch (Lex.getKind()) { |
7404 | default: |
7405 | return tokError(Msg: "expected icmp predicate (e.g. 'eq')" ); |
7406 | case lltok::kw_eq: P = CmpInst::ICMP_EQ; break; |
7407 | case lltok::kw_ne: P = CmpInst::ICMP_NE; break; |
7408 | case lltok::kw_slt: P = CmpInst::ICMP_SLT; break; |
7409 | case lltok::kw_sgt: P = CmpInst::ICMP_SGT; break; |
7410 | case lltok::kw_sle: P = CmpInst::ICMP_SLE; break; |
7411 | case lltok::kw_sge: P = CmpInst::ICMP_SGE; break; |
7412 | case lltok::kw_ult: P = CmpInst::ICMP_ULT; break; |
7413 | case lltok::kw_ugt: P = CmpInst::ICMP_UGT; break; |
7414 | case lltok::kw_ule: P = CmpInst::ICMP_ULE; break; |
7415 | case lltok::kw_uge: P = CmpInst::ICMP_UGE; break; |
7416 | } |
7417 | } |
7418 | Lex.Lex(); |
7419 | return false; |
7420 | } |
7421 | |
7422 | //===----------------------------------------------------------------------===// |
7423 | // Terminator Instructions. |
7424 | //===----------------------------------------------------------------------===// |
7425 | |
7426 | /// parseRet - parse a return instruction. |
7427 | /// ::= 'ret' void (',' !dbg, !1)* |
7428 | /// ::= 'ret' TypeAndValue (',' !dbg, !1)* |
7429 | bool LLParser::parseRet(Instruction *&Inst, BasicBlock *BB, |
7430 | PerFunctionState &PFS) { |
7431 | SMLoc TypeLoc = Lex.getLoc(); |
7432 | Type *Ty = nullptr; |
7433 | if (parseType(Result&: Ty, AllowVoid: true /*void allowed*/)) |
7434 | return true; |
7435 | |
7436 | Type *ResType = PFS.getFunction().getReturnType(); |
7437 | |
7438 | if (Ty->isVoidTy()) { |
7439 | if (!ResType->isVoidTy()) |
7440 | return error(L: TypeLoc, Msg: "value doesn't match function result type '" + |
7441 | getTypeString(T: ResType) + "'" ); |
7442 | |
7443 | Inst = ReturnInst::Create(C&: Context); |
7444 | return false; |
7445 | } |
7446 | |
7447 | Value *RV; |
7448 | if (parseValue(Ty, V&: RV, PFS)) |
7449 | return true; |
7450 | |
7451 | if (ResType != RV->getType()) |
7452 | return error(L: TypeLoc, Msg: "value doesn't match function result type '" + |
7453 | getTypeString(T: ResType) + "'" ); |
7454 | |
7455 | Inst = ReturnInst::Create(C&: Context, retVal: RV); |
7456 | return false; |
7457 | } |
7458 | |
7459 | /// parseBr |
7460 | /// ::= 'br' TypeAndValue |
7461 | /// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue |
7462 | bool LLParser::parseBr(Instruction *&Inst, PerFunctionState &PFS) { |
7463 | LocTy Loc, Loc2; |
7464 | Value *Op0; |
7465 | BasicBlock *Op1, *Op2; |
7466 | if (parseTypeAndValue(V&: Op0, Loc, PFS)) |
7467 | return true; |
7468 | |
7469 | if (BasicBlock *BB = dyn_cast<BasicBlock>(Val: Op0)) { |
7470 | Inst = BranchInst::Create(IfTrue: BB); |
7471 | return false; |
7472 | } |
7473 | |
7474 | if (Op0->getType() != Type::getInt1Ty(C&: Context)) |
7475 | return error(L: Loc, Msg: "branch condition must have 'i1' type" ); |
7476 | |
7477 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' after branch condition" ) || |
7478 | parseTypeAndBasicBlock(BB&: Op1, Loc, PFS) || |
7479 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after true destination" ) || |
7480 | parseTypeAndBasicBlock(BB&: Op2, Loc&: Loc2, PFS)) |
7481 | return true; |
7482 | |
7483 | Inst = BranchInst::Create(IfTrue: Op1, IfFalse: Op2, Cond: Op0); |
7484 | return false; |
7485 | } |
7486 | |
7487 | /// parseSwitch |
7488 | /// Instruction |
7489 | /// ::= 'switch' TypeAndValue ',' TypeAndValue '[' JumpTable ']' |
7490 | /// JumpTable |
7491 | /// ::= (TypeAndValue ',' TypeAndValue)* |
7492 | bool LLParser::parseSwitch(Instruction *&Inst, PerFunctionState &PFS) { |
7493 | LocTy CondLoc, BBLoc; |
7494 | Value *Cond; |
7495 | BasicBlock *DefaultBB; |
7496 | if (parseTypeAndValue(V&: Cond, Loc&: CondLoc, PFS) || |
7497 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after switch condition" ) || |
7498 | parseTypeAndBasicBlock(BB&: DefaultBB, Loc&: BBLoc, PFS) || |
7499 | parseToken(T: lltok::lsquare, ErrMsg: "expected '[' with switch table" )) |
7500 | return true; |
7501 | |
7502 | if (!Cond->getType()->isIntegerTy()) |
7503 | return error(L: CondLoc, Msg: "switch condition must have integer type" ); |
7504 | |
7505 | // parse the jump table pairs. |
7506 | SmallPtrSet<Value*, 32> SeenCases; |
7507 | SmallVector<std::pair<ConstantInt*, BasicBlock*>, 32> Table; |
7508 | while (Lex.getKind() != lltok::rsquare) { |
7509 | Value *Constant; |
7510 | BasicBlock *DestBB; |
7511 | |
7512 | if (parseTypeAndValue(V&: Constant, Loc&: CondLoc, PFS) || |
7513 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after case value" ) || |
7514 | parseTypeAndBasicBlock(BB&: DestBB, PFS)) |
7515 | return true; |
7516 | |
7517 | if (!SeenCases.insert(Ptr: Constant).second) |
7518 | return error(L: CondLoc, Msg: "duplicate case value in switch" ); |
7519 | if (!isa<ConstantInt>(Val: Constant)) |
7520 | return error(L: CondLoc, Msg: "case value is not a constant integer" ); |
7521 | |
7522 | Table.push_back(Elt: std::make_pair(x: cast<ConstantInt>(Val: Constant), y&: DestBB)); |
7523 | } |
7524 | |
7525 | Lex.Lex(); // Eat the ']'. |
7526 | |
7527 | SwitchInst *SI = SwitchInst::Create(Value: Cond, Default: DefaultBB, NumCases: Table.size()); |
7528 | for (const auto &[OnVal, Dest] : Table) |
7529 | SI->addCase(OnVal, Dest); |
7530 | Inst = SI; |
7531 | return false; |
7532 | } |
7533 | |
7534 | /// parseIndirectBr |
7535 | /// Instruction |
7536 | /// ::= 'indirectbr' TypeAndValue ',' '[' LabelList ']' |
7537 | bool LLParser::parseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { |
7538 | LocTy AddrLoc; |
7539 | Value *Address; |
7540 | if (parseTypeAndValue(V&: Address, Loc&: AddrLoc, PFS) || |
7541 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after indirectbr address" ) || |
7542 | parseToken(T: lltok::lsquare, ErrMsg: "expected '[' with indirectbr" )) |
7543 | return true; |
7544 | |
7545 | if (!Address->getType()->isPointerTy()) |
7546 | return error(L: AddrLoc, Msg: "indirectbr address must have pointer type" ); |
7547 | |
7548 | // parse the destination list. |
7549 | SmallVector<BasicBlock*, 16> DestList; |
7550 | |
7551 | if (Lex.getKind() != lltok::rsquare) { |
7552 | BasicBlock *DestBB; |
7553 | if (parseTypeAndBasicBlock(BB&: DestBB, PFS)) |
7554 | return true; |
7555 | DestList.push_back(Elt: DestBB); |
7556 | |
7557 | while (EatIfPresent(T: lltok::comma)) { |
7558 | if (parseTypeAndBasicBlock(BB&: DestBB, PFS)) |
7559 | return true; |
7560 | DestList.push_back(Elt: DestBB); |
7561 | } |
7562 | } |
7563 | |
7564 | if (parseToken(T: lltok::rsquare, ErrMsg: "expected ']' at end of block list" )) |
7565 | return true; |
7566 | |
7567 | IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests: DestList.size()); |
7568 | for (BasicBlock *Dest : DestList) |
7569 | IBI->addDestination(Dest); |
7570 | Inst = IBI; |
7571 | return false; |
7572 | } |
7573 | |
7574 | // If RetType is a non-function pointer type, then this is the short syntax |
7575 | // for the call, which means that RetType is just the return type. Infer the |
7576 | // rest of the function argument types from the arguments that are present. |
7577 | bool LLParser::resolveFunctionType(Type *RetType, ArrayRef<ParamInfo> ArgList, |
7578 | FunctionType *&FuncTy) { |
7579 | FuncTy = dyn_cast<FunctionType>(Val: RetType); |
7580 | if (!FuncTy) { |
7581 | // Pull out the types of all of the arguments... |
7582 | SmallVector<Type *, 8> ParamTypes; |
7583 | ParamTypes.reserve(N: ArgList.size()); |
7584 | for (const ParamInfo &Arg : ArgList) |
7585 | ParamTypes.push_back(Elt: Arg.V->getType()); |
7586 | |
7587 | if (!FunctionType::isValidReturnType(RetTy: RetType)) |
7588 | return true; |
7589 | |
7590 | FuncTy = FunctionType::get(Result: RetType, Params: ParamTypes, isVarArg: false); |
7591 | } |
7592 | return false; |
7593 | } |
7594 | |
7595 | /// parseInvoke |
7596 | /// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList |
7597 | /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue |
7598 | bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) { |
7599 | LocTy CallLoc = Lex.getLoc(); |
7600 | AttrBuilder RetAttrs(M->getContext()), FnAttrs(M->getContext()); |
7601 | std::vector<unsigned> FwdRefAttrGrps; |
7602 | LocTy NoBuiltinLoc; |
7603 | unsigned CC; |
7604 | unsigned InvokeAddrSpace; |
7605 | Type *RetType = nullptr; |
7606 | LocTy RetTypeLoc; |
7607 | ValID CalleeID; |
7608 | SmallVector<ParamInfo, 16> ArgList; |
7609 | SmallVector<OperandBundleDef, 2> BundleList; |
7610 | |
7611 | BasicBlock *NormalBB, *UnwindBB; |
7612 | if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(B&: RetAttrs) || |
7613 | parseOptionalProgramAddrSpace(AddrSpace&: InvokeAddrSpace) || |
7614 | parseType(Result&: RetType, Loc&: RetTypeLoc, AllowVoid: true /*void allowed*/) || |
7615 | parseValID(ID&: CalleeID, PFS: &PFS) || parseParameterList(ArgList, PFS) || |
7616 | parseFnAttributeValuePairs(B&: FnAttrs, FwdRefAttrGrps, InAttrGrp: false, |
7617 | BuiltinLoc&: NoBuiltinLoc) || |
7618 | parseOptionalOperandBundles(BundleList, PFS) || |
7619 | parseToken(T: lltok::kw_to, ErrMsg: "expected 'to' in invoke" ) || |
7620 | parseTypeAndBasicBlock(BB&: NormalBB, PFS) || |
7621 | parseToken(T: lltok::kw_unwind, ErrMsg: "expected 'unwind' in invoke" ) || |
7622 | parseTypeAndBasicBlock(BB&: UnwindBB, PFS)) |
7623 | return true; |
7624 | |
7625 | // If RetType is a non-function pointer type, then this is the short syntax |
7626 | // for the call, which means that RetType is just the return type. Infer the |
7627 | // rest of the function argument types from the arguments that are present. |
7628 | FunctionType *Ty; |
7629 | if (resolveFunctionType(RetType, ArgList, FuncTy&: Ty)) |
7630 | return error(L: RetTypeLoc, Msg: "Invalid result type for LLVM function" ); |
7631 | |
7632 | CalleeID.FTy = Ty; |
7633 | |
7634 | // Look up the callee. |
7635 | Value *Callee; |
7636 | if (convertValIDToValue(Ty: PointerType::get(C&: Context, AddressSpace: InvokeAddrSpace), ID&: CalleeID, |
7637 | V&: Callee, PFS: &PFS)) |
7638 | return true; |
7639 | |
7640 | // Set up the Attribute for the function. |
7641 | SmallVector<Value *, 8> Args; |
7642 | SmallVector<AttributeSet, 8> ArgAttrs; |
7643 | |
7644 | // Loop through FunctionType's arguments and ensure they are specified |
7645 | // correctly. Also, gather any parameter attributes. |
7646 | FunctionType::param_iterator I = Ty->param_begin(); |
7647 | FunctionType::param_iterator E = Ty->param_end(); |
7648 | for (const ParamInfo &Arg : ArgList) { |
7649 | Type *ExpectedTy = nullptr; |
7650 | if (I != E) { |
7651 | ExpectedTy = *I++; |
7652 | } else if (!Ty->isVarArg()) { |
7653 | return error(L: Arg.Loc, Msg: "too many arguments specified" ); |
7654 | } |
7655 | |
7656 | if (ExpectedTy && ExpectedTy != Arg.V->getType()) |
7657 | return error(L: Arg.Loc, Msg: "argument is not of expected type '" + |
7658 | getTypeString(T: ExpectedTy) + "'" ); |
7659 | Args.push_back(Elt: Arg.V); |
7660 | ArgAttrs.push_back(Elt: Arg.Attrs); |
7661 | } |
7662 | |
7663 | if (I != E) |
7664 | return error(L: CallLoc, Msg: "not enough parameters specified for call" ); |
7665 | |
7666 | // Finish off the Attribute and check them |
7667 | AttributeList PAL = |
7668 | AttributeList::get(C&: Context, FnAttrs: AttributeSet::get(C&: Context, B: FnAttrs), |
7669 | RetAttrs: AttributeSet::get(C&: Context, B: RetAttrs), ArgAttrs); |
7670 | |
7671 | InvokeInst *II = |
7672 | InvokeInst::Create(Ty, Func: Callee, IfNormal: NormalBB, IfException: UnwindBB, Args, Bundles: BundleList); |
7673 | II->setCallingConv(CC); |
7674 | II->setAttributes(PAL); |
7675 | ForwardRefAttrGroups[II] = FwdRefAttrGrps; |
7676 | Inst = II; |
7677 | return false; |
7678 | } |
7679 | |
7680 | /// parseResume |
7681 | /// ::= 'resume' TypeAndValue |
7682 | bool LLParser::parseResume(Instruction *&Inst, PerFunctionState &PFS) { |
7683 | Value *Exn; LocTy ExnLoc; |
7684 | if (parseTypeAndValue(V&: Exn, Loc&: ExnLoc, PFS)) |
7685 | return true; |
7686 | |
7687 | ResumeInst *RI = ResumeInst::Create(Exn); |
7688 | Inst = RI; |
7689 | return false; |
7690 | } |
7691 | |
7692 | bool LLParser::parseExceptionArgs(SmallVectorImpl<Value *> &Args, |
7693 | PerFunctionState &PFS) { |
7694 | if (parseToken(T: lltok::lsquare, ErrMsg: "expected '[' in catchpad/cleanuppad" )) |
7695 | return true; |
7696 | |
7697 | while (Lex.getKind() != lltok::rsquare) { |
7698 | // If this isn't the first argument, we need a comma. |
7699 | if (!Args.empty() && |
7700 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in argument list" )) |
7701 | return true; |
7702 | |
7703 | // parse the argument. |
7704 | LocTy ArgLoc; |
7705 | Type *ArgTy = nullptr; |
7706 | if (parseType(Result&: ArgTy, Loc&: ArgLoc)) |
7707 | return true; |
7708 | |
7709 | Value *V; |
7710 | if (ArgTy->isMetadataTy()) { |
7711 | if (parseMetadataAsValue(V, PFS)) |
7712 | return true; |
7713 | } else { |
7714 | if (parseValue(Ty: ArgTy, V, PFS)) |
7715 | return true; |
7716 | } |
7717 | Args.push_back(Elt: V); |
7718 | } |
7719 | |
7720 | Lex.Lex(); // Lex the ']'. |
7721 | return false; |
7722 | } |
7723 | |
7724 | /// parseCleanupRet |
7725 | /// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue) |
7726 | bool LLParser::parseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { |
7727 | Value *CleanupPad = nullptr; |
7728 | |
7729 | if (parseToken(T: lltok::kw_from, ErrMsg: "expected 'from' after cleanupret" )) |
7730 | return true; |
7731 | |
7732 | if (parseValue(Ty: Type::getTokenTy(C&: Context), V&: CleanupPad, PFS)) |
7733 | return true; |
7734 | |
7735 | if (parseToken(T: lltok::kw_unwind, ErrMsg: "expected 'unwind' in cleanupret" )) |
7736 | return true; |
7737 | |
7738 | BasicBlock *UnwindBB = nullptr; |
7739 | if (Lex.getKind() == lltok::kw_to) { |
7740 | Lex.Lex(); |
7741 | if (parseToken(T: lltok::kw_caller, ErrMsg: "expected 'caller' in cleanupret" )) |
7742 | return true; |
7743 | } else { |
7744 | if (parseTypeAndBasicBlock(BB&: UnwindBB, PFS)) { |
7745 | return true; |
7746 | } |
7747 | } |
7748 | |
7749 | Inst = CleanupReturnInst::Create(CleanupPad, UnwindBB); |
7750 | return false; |
7751 | } |
7752 | |
7753 | /// parseCatchRet |
7754 | /// ::= 'catchret' from Parent Value 'to' TypeAndValue |
7755 | bool LLParser::parseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { |
7756 | Value *CatchPad = nullptr; |
7757 | |
7758 | if (parseToken(T: lltok::kw_from, ErrMsg: "expected 'from' after catchret" )) |
7759 | return true; |
7760 | |
7761 | if (parseValue(Ty: Type::getTokenTy(C&: Context), V&: CatchPad, PFS)) |
7762 | return true; |
7763 | |
7764 | BasicBlock *BB; |
7765 | if (parseToken(T: lltok::kw_to, ErrMsg: "expected 'to' in catchret" ) || |
7766 | parseTypeAndBasicBlock(BB, PFS)) |
7767 | return true; |
7768 | |
7769 | Inst = CatchReturnInst::Create(CatchPad, BB); |
7770 | return false; |
7771 | } |
7772 | |
7773 | /// parseCatchSwitch |
7774 | /// ::= 'catchswitch' within Parent |
7775 | bool LLParser::parseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) { |
7776 | Value *ParentPad; |
7777 | |
7778 | if (parseToken(T: lltok::kw_within, ErrMsg: "expected 'within' after catchswitch" )) |
7779 | return true; |
7780 | |
7781 | if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && |
7782 | Lex.getKind() != lltok::LocalVarID) |
7783 | return tokError(Msg: "expected scope value for catchswitch" ); |
7784 | |
7785 | if (parseValue(Ty: Type::getTokenTy(C&: Context), V&: ParentPad, PFS)) |
7786 | return true; |
7787 | |
7788 | if (parseToken(T: lltok::lsquare, ErrMsg: "expected '[' with catchswitch labels" )) |
7789 | return true; |
7790 | |
7791 | SmallVector<BasicBlock *, 32> Table; |
7792 | do { |
7793 | BasicBlock *DestBB; |
7794 | if (parseTypeAndBasicBlock(BB&: DestBB, PFS)) |
7795 | return true; |
7796 | Table.push_back(Elt: DestBB); |
7797 | } while (EatIfPresent(T: lltok::comma)); |
7798 | |
7799 | if (parseToken(T: lltok::rsquare, ErrMsg: "expected ']' after catchswitch labels" )) |
7800 | return true; |
7801 | |
7802 | if (parseToken(T: lltok::kw_unwind, ErrMsg: "expected 'unwind' after catchswitch scope" )) |
7803 | return true; |
7804 | |
7805 | BasicBlock *UnwindBB = nullptr; |
7806 | if (EatIfPresent(T: lltok::kw_to)) { |
7807 | if (parseToken(T: lltok::kw_caller, ErrMsg: "expected 'caller' in catchswitch" )) |
7808 | return true; |
7809 | } else { |
7810 | if (parseTypeAndBasicBlock(BB&: UnwindBB, PFS)) |
7811 | return true; |
7812 | } |
7813 | |
7814 | auto *CatchSwitch = |
7815 | CatchSwitchInst::Create(ParentPad, UnwindDest: UnwindBB, NumHandlers: Table.size()); |
7816 | for (BasicBlock *DestBB : Table) |
7817 | CatchSwitch->addHandler(Dest: DestBB); |
7818 | Inst = CatchSwitch; |
7819 | return false; |
7820 | } |
7821 | |
7822 | /// parseCatchPad |
7823 | /// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue |
7824 | bool LLParser::parseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { |
7825 | Value *CatchSwitch = nullptr; |
7826 | |
7827 | if (parseToken(T: lltok::kw_within, ErrMsg: "expected 'within' after catchpad" )) |
7828 | return true; |
7829 | |
7830 | if (Lex.getKind() != lltok::LocalVar && Lex.getKind() != lltok::LocalVarID) |
7831 | return tokError(Msg: "expected scope value for catchpad" ); |
7832 | |
7833 | if (parseValue(Ty: Type::getTokenTy(C&: Context), V&: CatchSwitch, PFS)) |
7834 | return true; |
7835 | |
7836 | SmallVector<Value *, 8> Args; |
7837 | if (parseExceptionArgs(Args, PFS)) |
7838 | return true; |
7839 | |
7840 | Inst = CatchPadInst::Create(CatchSwitch, Args); |
7841 | return false; |
7842 | } |
7843 | |
7844 | /// parseCleanupPad |
7845 | /// ::= 'cleanuppad' within Parent ParamList |
7846 | bool LLParser::parseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { |
7847 | Value *ParentPad = nullptr; |
7848 | |
7849 | if (parseToken(T: lltok::kw_within, ErrMsg: "expected 'within' after cleanuppad" )) |
7850 | return true; |
7851 | |
7852 | if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && |
7853 | Lex.getKind() != lltok::LocalVarID) |
7854 | return tokError(Msg: "expected scope value for cleanuppad" ); |
7855 | |
7856 | if (parseValue(Ty: Type::getTokenTy(C&: Context), V&: ParentPad, PFS)) |
7857 | return true; |
7858 | |
7859 | SmallVector<Value *, 8> Args; |
7860 | if (parseExceptionArgs(Args, PFS)) |
7861 | return true; |
7862 | |
7863 | Inst = CleanupPadInst::Create(ParentPad, Args); |
7864 | return false; |
7865 | } |
7866 | |
7867 | //===----------------------------------------------------------------------===// |
7868 | // Unary Operators. |
7869 | //===----------------------------------------------------------------------===// |
7870 | |
7871 | /// parseUnaryOp |
7872 | /// ::= UnaryOp TypeAndValue ',' Value |
7873 | /// |
7874 | /// If IsFP is false, then any integer operand is allowed, if it is true, any fp |
7875 | /// operand is allowed. |
7876 | bool LLParser::parseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, |
7877 | unsigned Opc, bool IsFP) { |
7878 | LocTy Loc; Value *LHS; |
7879 | if (parseTypeAndValue(V&: LHS, Loc, PFS)) |
7880 | return true; |
7881 | |
7882 | bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy() |
7883 | : LHS->getType()->isIntOrIntVectorTy(); |
7884 | |
7885 | if (!Valid) |
7886 | return error(L: Loc, Msg: "invalid operand type for instruction" ); |
7887 | |
7888 | Inst = UnaryOperator::Create(Op: (Instruction::UnaryOps)Opc, S: LHS); |
7889 | return false; |
7890 | } |
7891 | |
7892 | /// parseCallBr |
7893 | /// ::= 'callbr' OptionalCallingConv OptionalAttrs Type Value ParamList |
7894 | /// OptionalAttrs OptionalOperandBundles 'to' TypeAndValue |
7895 | /// '[' LabelList ']' |
7896 | bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) { |
7897 | LocTy CallLoc = Lex.getLoc(); |
7898 | AttrBuilder RetAttrs(M->getContext()), FnAttrs(M->getContext()); |
7899 | std::vector<unsigned> FwdRefAttrGrps; |
7900 | LocTy NoBuiltinLoc; |
7901 | unsigned CC; |
7902 | Type *RetType = nullptr; |
7903 | LocTy RetTypeLoc; |
7904 | ValID CalleeID; |
7905 | SmallVector<ParamInfo, 16> ArgList; |
7906 | SmallVector<OperandBundleDef, 2> BundleList; |
7907 | |
7908 | BasicBlock *DefaultDest; |
7909 | if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(B&: RetAttrs) || |
7910 | parseType(Result&: RetType, Loc&: RetTypeLoc, AllowVoid: true /*void allowed*/) || |
7911 | parseValID(ID&: CalleeID, PFS: &PFS) || parseParameterList(ArgList, PFS) || |
7912 | parseFnAttributeValuePairs(B&: FnAttrs, FwdRefAttrGrps, InAttrGrp: false, |
7913 | BuiltinLoc&: NoBuiltinLoc) || |
7914 | parseOptionalOperandBundles(BundleList, PFS) || |
7915 | parseToken(T: lltok::kw_to, ErrMsg: "expected 'to' in callbr" ) || |
7916 | parseTypeAndBasicBlock(BB&: DefaultDest, PFS) || |
7917 | parseToken(T: lltok::lsquare, ErrMsg: "expected '[' in callbr" )) |
7918 | return true; |
7919 | |
7920 | // parse the destination list. |
7921 | SmallVector<BasicBlock *, 16> IndirectDests; |
7922 | |
7923 | if (Lex.getKind() != lltok::rsquare) { |
7924 | BasicBlock *DestBB; |
7925 | if (parseTypeAndBasicBlock(BB&: DestBB, PFS)) |
7926 | return true; |
7927 | IndirectDests.push_back(Elt: DestBB); |
7928 | |
7929 | while (EatIfPresent(T: lltok::comma)) { |
7930 | if (parseTypeAndBasicBlock(BB&: DestBB, PFS)) |
7931 | return true; |
7932 | IndirectDests.push_back(Elt: DestBB); |
7933 | } |
7934 | } |
7935 | |
7936 | if (parseToken(T: lltok::rsquare, ErrMsg: "expected ']' at end of block list" )) |
7937 | return true; |
7938 | |
7939 | // If RetType is a non-function pointer type, then this is the short syntax |
7940 | // for the call, which means that RetType is just the return type. Infer the |
7941 | // rest of the function argument types from the arguments that are present. |
7942 | FunctionType *Ty; |
7943 | if (resolveFunctionType(RetType, ArgList, FuncTy&: Ty)) |
7944 | return error(L: RetTypeLoc, Msg: "Invalid result type for LLVM function" ); |
7945 | |
7946 | CalleeID.FTy = Ty; |
7947 | |
7948 | // Look up the callee. |
7949 | Value *Callee; |
7950 | if (convertValIDToValue(Ty: PointerType::getUnqual(C&: Context), ID&: CalleeID, V&: Callee, |
7951 | PFS: &PFS)) |
7952 | return true; |
7953 | |
7954 | // Set up the Attribute for the function. |
7955 | SmallVector<Value *, 8> Args; |
7956 | SmallVector<AttributeSet, 8> ArgAttrs; |
7957 | |
7958 | // Loop through FunctionType's arguments and ensure they are specified |
7959 | // correctly. Also, gather any parameter attributes. |
7960 | FunctionType::param_iterator I = Ty->param_begin(); |
7961 | FunctionType::param_iterator E = Ty->param_end(); |
7962 | for (const ParamInfo &Arg : ArgList) { |
7963 | Type *ExpectedTy = nullptr; |
7964 | if (I != E) { |
7965 | ExpectedTy = *I++; |
7966 | } else if (!Ty->isVarArg()) { |
7967 | return error(L: Arg.Loc, Msg: "too many arguments specified" ); |
7968 | } |
7969 | |
7970 | if (ExpectedTy && ExpectedTy != Arg.V->getType()) |
7971 | return error(L: Arg.Loc, Msg: "argument is not of expected type '" + |
7972 | getTypeString(T: ExpectedTy) + "'" ); |
7973 | Args.push_back(Elt: Arg.V); |
7974 | ArgAttrs.push_back(Elt: Arg.Attrs); |
7975 | } |
7976 | |
7977 | if (I != E) |
7978 | return error(L: CallLoc, Msg: "not enough parameters specified for call" ); |
7979 | |
7980 | // Finish off the Attribute and check them |
7981 | AttributeList PAL = |
7982 | AttributeList::get(C&: Context, FnAttrs: AttributeSet::get(C&: Context, B: FnAttrs), |
7983 | RetAttrs: AttributeSet::get(C&: Context, B: RetAttrs), ArgAttrs); |
7984 | |
7985 | CallBrInst *CBI = |
7986 | CallBrInst::Create(Ty, Func: Callee, DefaultDest, IndirectDests, Args, |
7987 | Bundles: BundleList); |
7988 | CBI->setCallingConv(CC); |
7989 | CBI->setAttributes(PAL); |
7990 | ForwardRefAttrGroups[CBI] = FwdRefAttrGrps; |
7991 | Inst = CBI; |
7992 | return false; |
7993 | } |
7994 | |
7995 | //===----------------------------------------------------------------------===// |
7996 | // Binary Operators. |
7997 | //===----------------------------------------------------------------------===// |
7998 | |
7999 | /// parseArithmetic |
8000 | /// ::= ArithmeticOps TypeAndValue ',' Value |
8001 | /// |
8002 | /// If IsFP is false, then any integer operand is allowed, if it is true, any fp |
8003 | /// operand is allowed. |
8004 | bool LLParser::parseArithmetic(Instruction *&Inst, PerFunctionState &PFS, |
8005 | unsigned Opc, bool IsFP) { |
8006 | LocTy Loc; Value *LHS, *RHS; |
8007 | if (parseTypeAndValue(V&: LHS, Loc, PFS) || |
8008 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in arithmetic operation" ) || |
8009 | parseValue(Ty: LHS->getType(), V&: RHS, PFS)) |
8010 | return true; |
8011 | |
8012 | bool Valid = IsFP ? LHS->getType()->isFPOrFPVectorTy() |
8013 | : LHS->getType()->isIntOrIntVectorTy(); |
8014 | |
8015 | if (!Valid) |
8016 | return error(L: Loc, Msg: "invalid operand type for instruction" ); |
8017 | |
8018 | Inst = BinaryOperator::Create(Op: (Instruction::BinaryOps)Opc, S1: LHS, S2: RHS); |
8019 | return false; |
8020 | } |
8021 | |
8022 | /// parseLogical |
8023 | /// ::= ArithmeticOps TypeAndValue ',' Value { |
8024 | bool LLParser::parseLogical(Instruction *&Inst, PerFunctionState &PFS, |
8025 | unsigned Opc) { |
8026 | LocTy Loc; Value *LHS, *RHS; |
8027 | if (parseTypeAndValue(V&: LHS, Loc, PFS) || |
8028 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in logical operation" ) || |
8029 | parseValue(Ty: LHS->getType(), V&: RHS, PFS)) |
8030 | return true; |
8031 | |
8032 | if (!LHS->getType()->isIntOrIntVectorTy()) |
8033 | return error(L: Loc, |
8034 | Msg: "instruction requires integer or integer vector operands" ); |
8035 | |
8036 | Inst = BinaryOperator::Create(Op: (Instruction::BinaryOps)Opc, S1: LHS, S2: RHS); |
8037 | return false; |
8038 | } |
8039 | |
8040 | /// parseCompare |
8041 | /// ::= 'icmp' IPredicates TypeAndValue ',' Value |
8042 | /// ::= 'fcmp' FPredicates TypeAndValue ',' Value |
8043 | bool LLParser::parseCompare(Instruction *&Inst, PerFunctionState &PFS, |
8044 | unsigned Opc) { |
8045 | // parse the integer/fp comparison predicate. |
8046 | LocTy Loc; |
8047 | unsigned Pred; |
8048 | Value *LHS, *RHS; |
8049 | if (parseCmpPredicate(P&: Pred, Opc) || parseTypeAndValue(V&: LHS, Loc, PFS) || |
8050 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after compare value" ) || |
8051 | parseValue(Ty: LHS->getType(), V&: RHS, PFS)) |
8052 | return true; |
8053 | |
8054 | if (Opc == Instruction::FCmp) { |
8055 | if (!LHS->getType()->isFPOrFPVectorTy()) |
8056 | return error(L: Loc, Msg: "fcmp requires floating point operands" ); |
8057 | Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS); |
8058 | } else { |
8059 | assert(Opc == Instruction::ICmp && "Unknown opcode for CmpInst!" ); |
8060 | if (!LHS->getType()->isIntOrIntVectorTy() && |
8061 | !LHS->getType()->isPtrOrPtrVectorTy()) |
8062 | return error(L: Loc, Msg: "icmp requires integer operands" ); |
8063 | Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS); |
8064 | } |
8065 | return false; |
8066 | } |
8067 | |
8068 | //===----------------------------------------------------------------------===// |
8069 | // Other Instructions. |
8070 | //===----------------------------------------------------------------------===// |
8071 | |
8072 | /// parseCast |
8073 | /// ::= CastOpc TypeAndValue 'to' Type |
8074 | bool LLParser::parseCast(Instruction *&Inst, PerFunctionState &PFS, |
8075 | unsigned Opc) { |
8076 | LocTy Loc; |
8077 | Value *Op; |
8078 | Type *DestTy = nullptr; |
8079 | if (parseTypeAndValue(V&: Op, Loc, PFS) || |
8080 | parseToken(T: lltok::kw_to, ErrMsg: "expected 'to' after cast value" ) || |
8081 | parseType(Result&: DestTy)) |
8082 | return true; |
8083 | |
8084 | if (!CastInst::castIsValid(op: (Instruction::CastOps)Opc, S: Op, DstTy: DestTy)) |
8085 | return error(L: Loc, Msg: "invalid cast opcode for cast from '" + |
8086 | getTypeString(T: Op->getType()) + "' to '" + |
8087 | getTypeString(T: DestTy) + "'" ); |
8088 | Inst = CastInst::Create((Instruction::CastOps)Opc, S: Op, Ty: DestTy); |
8089 | return false; |
8090 | } |
8091 | |
8092 | /// parseSelect |
8093 | /// ::= 'select' TypeAndValue ',' TypeAndValue ',' TypeAndValue |
8094 | bool LLParser::parseSelect(Instruction *&Inst, PerFunctionState &PFS) { |
8095 | LocTy Loc; |
8096 | Value *Op0, *Op1, *Op2; |
8097 | if (parseTypeAndValue(V&: Op0, Loc, PFS) || |
8098 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after select condition" ) || |
8099 | parseTypeAndValue(V&: Op1, PFS) || |
8100 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after select value" ) || |
8101 | parseTypeAndValue(V&: Op2, PFS)) |
8102 | return true; |
8103 | |
8104 | if (const char *Reason = SelectInst::areInvalidOperands(Cond: Op0, True: Op1, False: Op2)) |
8105 | return error(L: Loc, Msg: Reason); |
8106 | |
8107 | Inst = SelectInst::Create(C: Op0, S1: Op1, S2: Op2); |
8108 | return false; |
8109 | } |
8110 | |
8111 | /// parseVAArg |
8112 | /// ::= 'va_arg' TypeAndValue ',' Type |
8113 | bool LLParser::parseVAArg(Instruction *&Inst, PerFunctionState &PFS) { |
8114 | Value *Op; |
8115 | Type *EltTy = nullptr; |
8116 | LocTy TypeLoc; |
8117 | if (parseTypeAndValue(V&: Op, PFS) || |
8118 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after vaarg operand" ) || |
8119 | parseType(Result&: EltTy, Loc&: TypeLoc)) |
8120 | return true; |
8121 | |
8122 | if (!EltTy->isFirstClassType()) |
8123 | return error(L: TypeLoc, Msg: "va_arg requires operand with first class type" ); |
8124 | |
8125 | Inst = new VAArgInst(Op, EltTy); |
8126 | return false; |
8127 | } |
8128 | |
8129 | /// parseExtractElement |
8130 | /// ::= 'extractelement' TypeAndValue ',' TypeAndValue |
8131 | bool LLParser::(Instruction *&Inst, PerFunctionState &PFS) { |
8132 | LocTy Loc; |
8133 | Value *Op0, *Op1; |
8134 | if (parseTypeAndValue(V&: Op0, Loc, PFS) || |
8135 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after extract value" ) || |
8136 | parseTypeAndValue(V&: Op1, PFS)) |
8137 | return true; |
8138 | |
8139 | if (!ExtractElementInst::isValidOperands(Vec: Op0, Idx: Op1)) |
8140 | return error(L: Loc, Msg: "invalid extractelement operands" ); |
8141 | |
8142 | Inst = ExtractElementInst::Create(Vec: Op0, Idx: Op1); |
8143 | return false; |
8144 | } |
8145 | |
8146 | /// parseInsertElement |
8147 | /// ::= 'insertelement' TypeAndValue ',' TypeAndValue ',' TypeAndValue |
8148 | bool LLParser::parseInsertElement(Instruction *&Inst, PerFunctionState &PFS) { |
8149 | LocTy Loc; |
8150 | Value *Op0, *Op1, *Op2; |
8151 | if (parseTypeAndValue(V&: Op0, Loc, PFS) || |
8152 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after insertelement value" ) || |
8153 | parseTypeAndValue(V&: Op1, PFS) || |
8154 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after insertelement value" ) || |
8155 | parseTypeAndValue(V&: Op2, PFS)) |
8156 | return true; |
8157 | |
8158 | if (!InsertElementInst::isValidOperands(Vec: Op0, NewElt: Op1, Idx: Op2)) |
8159 | return error(L: Loc, Msg: "invalid insertelement operands" ); |
8160 | |
8161 | Inst = InsertElementInst::Create(Vec: Op0, NewElt: Op1, Idx: Op2); |
8162 | return false; |
8163 | } |
8164 | |
8165 | /// parseShuffleVector |
8166 | /// ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue |
8167 | bool LLParser::parseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { |
8168 | LocTy Loc; |
8169 | Value *Op0, *Op1, *Op2; |
8170 | if (parseTypeAndValue(V&: Op0, Loc, PFS) || |
8171 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after shuffle mask" ) || |
8172 | parseTypeAndValue(V&: Op1, PFS) || |
8173 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after shuffle value" ) || |
8174 | parseTypeAndValue(V&: Op2, PFS)) |
8175 | return true; |
8176 | |
8177 | if (!ShuffleVectorInst::isValidOperands(V1: Op0, V2: Op1, Mask: Op2)) |
8178 | return error(L: Loc, Msg: "invalid shufflevector operands" ); |
8179 | |
8180 | Inst = new ShuffleVectorInst(Op0, Op1, Op2); |
8181 | return false; |
8182 | } |
8183 | |
8184 | /// parsePHI |
8185 | /// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')* |
8186 | int LLParser::parsePHI(Instruction *&Inst, PerFunctionState &PFS) { |
8187 | Type *Ty = nullptr; LocTy TypeLoc; |
8188 | Value *Op0, *Op1; |
8189 | |
8190 | if (parseType(Result&: Ty, Loc&: TypeLoc)) |
8191 | return true; |
8192 | |
8193 | if (!Ty->isFirstClassType()) |
8194 | return error(L: TypeLoc, Msg: "phi node must have first class type" ); |
8195 | |
8196 | bool First = true; |
8197 | bool = false; |
8198 | SmallVector<std::pair<Value*, BasicBlock*>, 16> PHIVals; |
8199 | |
8200 | while (true) { |
8201 | if (First) { |
8202 | if (Lex.getKind() != lltok::lsquare) |
8203 | break; |
8204 | First = false; |
8205 | } else if (!EatIfPresent(T: lltok::comma)) |
8206 | break; |
8207 | |
8208 | if (Lex.getKind() == lltok::MetadataVar) { |
8209 | AteExtraComma = true; |
8210 | break; |
8211 | } |
8212 | |
8213 | if (parseToken(T: lltok::lsquare, ErrMsg: "expected '[' in phi value list" ) || |
8214 | parseValue(Ty, V&: Op0, PFS) || |
8215 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after insertelement value" ) || |
8216 | parseValue(Ty: Type::getLabelTy(C&: Context), V&: Op1, PFS) || |
8217 | parseToken(T: lltok::rsquare, ErrMsg: "expected ']' in phi value list" )) |
8218 | return true; |
8219 | |
8220 | PHIVals.push_back(Elt: std::make_pair(x&: Op0, y: cast<BasicBlock>(Val: Op1))); |
8221 | } |
8222 | |
8223 | PHINode *PN = PHINode::Create(Ty, NumReservedValues: PHIVals.size()); |
8224 | for (const auto &[Val, BB] : PHIVals) |
8225 | PN->addIncoming(V: Val, BB); |
8226 | Inst = PN; |
8227 | return AteExtraComma ? InstExtraComma : InstNormal; |
8228 | } |
8229 | |
8230 | /// parseLandingPad |
8231 | /// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+ |
8232 | /// Clause |
8233 | /// ::= 'catch' TypeAndValue |
8234 | /// ::= 'filter' |
8235 | /// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* |
8236 | bool LLParser::parseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { |
8237 | Type *Ty = nullptr; LocTy TyLoc; |
8238 | |
8239 | if (parseType(Result&: Ty, Loc&: TyLoc)) |
8240 | return true; |
8241 | |
8242 | std::unique_ptr<LandingPadInst> LP(LandingPadInst::Create(RetTy: Ty, NumReservedClauses: 0)); |
8243 | LP->setCleanup(EatIfPresent(T: lltok::kw_cleanup)); |
8244 | |
8245 | while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ |
8246 | LandingPadInst::ClauseType CT; |
8247 | if (EatIfPresent(T: lltok::kw_catch)) |
8248 | CT = LandingPadInst::Catch; |
8249 | else if (EatIfPresent(T: lltok::kw_filter)) |
8250 | CT = LandingPadInst::Filter; |
8251 | else |
8252 | return tokError(Msg: "expected 'catch' or 'filter' clause type" ); |
8253 | |
8254 | Value *V; |
8255 | LocTy VLoc; |
8256 | if (parseTypeAndValue(V, Loc&: VLoc, PFS)) |
8257 | return true; |
8258 | |
8259 | // A 'catch' type expects a non-array constant. A filter clause expects an |
8260 | // array constant. |
8261 | if (CT == LandingPadInst::Catch) { |
8262 | if (isa<ArrayType>(Val: V->getType())) |
8263 | return error(L: VLoc, Msg: "'catch' clause has an invalid type" ); |
8264 | } else { |
8265 | if (!isa<ArrayType>(Val: V->getType())) |
8266 | return error(L: VLoc, Msg: "'filter' clause has an invalid type" ); |
8267 | } |
8268 | |
8269 | Constant *CV = dyn_cast<Constant>(Val: V); |
8270 | if (!CV) |
8271 | return error(L: VLoc, Msg: "clause argument must be a constant" ); |
8272 | LP->addClause(ClauseVal: CV); |
8273 | } |
8274 | |
8275 | Inst = LP.release(); |
8276 | return false; |
8277 | } |
8278 | |
8279 | /// parseFreeze |
8280 | /// ::= 'freeze' Type Value |
8281 | bool LLParser::parseFreeze(Instruction *&Inst, PerFunctionState &PFS) { |
8282 | LocTy Loc; |
8283 | Value *Op; |
8284 | if (parseTypeAndValue(V&: Op, Loc, PFS)) |
8285 | return true; |
8286 | |
8287 | Inst = new FreezeInst(Op); |
8288 | return false; |
8289 | } |
8290 | |
8291 | /// parseCall |
8292 | /// ::= 'call' OptionalFastMathFlags OptionalCallingConv |
8293 | /// OptionalAttrs Type Value ParameterList OptionalAttrs |
8294 | /// ::= 'tail' 'call' OptionalFastMathFlags OptionalCallingConv |
8295 | /// OptionalAttrs Type Value ParameterList OptionalAttrs |
8296 | /// ::= 'musttail' 'call' OptionalFastMathFlags OptionalCallingConv |
8297 | /// OptionalAttrs Type Value ParameterList OptionalAttrs |
8298 | /// ::= 'notail' 'call' OptionalFastMathFlags OptionalCallingConv |
8299 | /// OptionalAttrs Type Value ParameterList OptionalAttrs |
8300 | bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS, |
8301 | CallInst::TailCallKind TCK) { |
8302 | AttrBuilder RetAttrs(M->getContext()), FnAttrs(M->getContext()); |
8303 | std::vector<unsigned> FwdRefAttrGrps; |
8304 | LocTy BuiltinLoc; |
8305 | unsigned CallAddrSpace; |
8306 | unsigned CC; |
8307 | Type *RetType = nullptr; |
8308 | LocTy RetTypeLoc; |
8309 | ValID CalleeID; |
8310 | SmallVector<ParamInfo, 16> ArgList; |
8311 | SmallVector<OperandBundleDef, 2> BundleList; |
8312 | LocTy CallLoc = Lex.getLoc(); |
8313 | |
8314 | if (TCK != CallInst::TCK_None && |
8315 | parseToken(T: lltok::kw_call, |
8316 | ErrMsg: "expected 'tail call', 'musttail call', or 'notail call'" )) |
8317 | return true; |
8318 | |
8319 | FastMathFlags FMF = EatFastMathFlagsIfPresent(); |
8320 | |
8321 | if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(B&: RetAttrs) || |
8322 | parseOptionalProgramAddrSpace(AddrSpace&: CallAddrSpace) || |
8323 | parseType(Result&: RetType, Loc&: RetTypeLoc, AllowVoid: true /*void allowed*/) || |
8324 | parseValID(ID&: CalleeID, PFS: &PFS) || |
8325 | parseParameterList(ArgList, PFS, IsMustTailCall: TCK == CallInst::TCK_MustTail, |
8326 | InVarArgsFunc: PFS.getFunction().isVarArg()) || |
8327 | parseFnAttributeValuePairs(B&: FnAttrs, FwdRefAttrGrps, InAttrGrp: false, BuiltinLoc) || |
8328 | parseOptionalOperandBundles(BundleList, PFS)) |
8329 | return true; |
8330 | |
8331 | // If RetType is a non-function pointer type, then this is the short syntax |
8332 | // for the call, which means that RetType is just the return type. Infer the |
8333 | // rest of the function argument types from the arguments that are present. |
8334 | FunctionType *Ty; |
8335 | if (resolveFunctionType(RetType, ArgList, FuncTy&: Ty)) |
8336 | return error(L: RetTypeLoc, Msg: "Invalid result type for LLVM function" ); |
8337 | |
8338 | CalleeID.FTy = Ty; |
8339 | |
8340 | // Look up the callee. |
8341 | Value *Callee; |
8342 | if (convertValIDToValue(Ty: PointerType::get(C&: Context, AddressSpace: CallAddrSpace), ID&: CalleeID, |
8343 | V&: Callee, PFS: &PFS)) |
8344 | return true; |
8345 | |
8346 | // Set up the Attribute for the function. |
8347 | SmallVector<AttributeSet, 8> Attrs; |
8348 | |
8349 | SmallVector<Value*, 8> Args; |
8350 | |
8351 | // Loop through FunctionType's arguments and ensure they are specified |
8352 | // correctly. Also, gather any parameter attributes. |
8353 | FunctionType::param_iterator I = Ty->param_begin(); |
8354 | FunctionType::param_iterator E = Ty->param_end(); |
8355 | for (const ParamInfo &Arg : ArgList) { |
8356 | Type *ExpectedTy = nullptr; |
8357 | if (I != E) { |
8358 | ExpectedTy = *I++; |
8359 | } else if (!Ty->isVarArg()) { |
8360 | return error(L: Arg.Loc, Msg: "too many arguments specified" ); |
8361 | } |
8362 | |
8363 | if (ExpectedTy && ExpectedTy != Arg.V->getType()) |
8364 | return error(L: Arg.Loc, Msg: "argument is not of expected type '" + |
8365 | getTypeString(T: ExpectedTy) + "'" ); |
8366 | Args.push_back(Elt: Arg.V); |
8367 | Attrs.push_back(Elt: Arg.Attrs); |
8368 | } |
8369 | |
8370 | if (I != E) |
8371 | return error(L: CallLoc, Msg: "not enough parameters specified for call" ); |
8372 | |
8373 | // Finish off the Attribute and check them |
8374 | AttributeList PAL = |
8375 | AttributeList::get(C&: Context, FnAttrs: AttributeSet::get(C&: Context, B: FnAttrs), |
8376 | RetAttrs: AttributeSet::get(C&: Context, B: RetAttrs), ArgAttrs: Attrs); |
8377 | |
8378 | CallInst *CI = CallInst::Create(Ty, Func: Callee, Args, Bundles: BundleList); |
8379 | CI->setTailCallKind(TCK); |
8380 | CI->setCallingConv(CC); |
8381 | if (FMF.any()) { |
8382 | if (!isa<FPMathOperator>(Val: CI)) { |
8383 | CI->deleteValue(); |
8384 | return error(L: CallLoc, Msg: "fast-math-flags specified for call without " |
8385 | "floating-point scalar or vector return type" ); |
8386 | } |
8387 | CI->setFastMathFlags(FMF); |
8388 | } |
8389 | |
8390 | if (CalleeID.Kind == ValID::t_GlobalName && |
8391 | isOldDbgFormatIntrinsic(Name: CalleeID.StrVal)) { |
8392 | if (SeenNewDbgInfoFormat) { |
8393 | CI->deleteValue(); |
8394 | return error(L: CallLoc, Msg: "llvm.dbg intrinsic should not appear in a module " |
8395 | "using non-intrinsic debug info" ); |
8396 | } |
8397 | SeenOldDbgInfoFormat = true; |
8398 | } |
8399 | CI->setAttributes(PAL); |
8400 | ForwardRefAttrGroups[CI] = FwdRefAttrGrps; |
8401 | Inst = CI; |
8402 | return false; |
8403 | } |
8404 | |
8405 | //===----------------------------------------------------------------------===// |
8406 | // Memory Instructions. |
8407 | //===----------------------------------------------------------------------===// |
8408 | |
8409 | /// parseAlloc |
8410 | /// ::= 'alloca' 'inalloca'? 'swifterror'? Type (',' TypeAndValue)? |
8411 | /// (',' 'align' i32)? (',', 'addrspace(n))? |
8412 | int LLParser::parseAlloc(Instruction *&Inst, PerFunctionState &PFS) { |
8413 | Value *Size = nullptr; |
8414 | LocTy SizeLoc, TyLoc, ASLoc; |
8415 | MaybeAlign Alignment; |
8416 | unsigned AddrSpace = 0; |
8417 | Type *Ty = nullptr; |
8418 | |
8419 | bool IsInAlloca = EatIfPresent(T: lltok::kw_inalloca); |
8420 | bool IsSwiftError = EatIfPresent(T: lltok::kw_swifterror); |
8421 | |
8422 | if (parseType(Result&: Ty, Loc&: TyLoc)) |
8423 | return true; |
8424 | |
8425 | if (Ty->isFunctionTy() || !PointerType::isValidElementType(ElemTy: Ty)) |
8426 | return error(L: TyLoc, Msg: "invalid type for alloca" ); |
8427 | |
8428 | bool = false; |
8429 | if (EatIfPresent(T: lltok::comma)) { |
8430 | if (Lex.getKind() == lltok::kw_align) { |
8431 | if (parseOptionalAlignment(Alignment)) |
8432 | return true; |
8433 | if (parseOptionalCommaAddrSpace(AddrSpace, Loc&: ASLoc, AteExtraComma)) |
8434 | return true; |
8435 | } else if (Lex.getKind() == lltok::kw_addrspace) { |
8436 | ASLoc = Lex.getLoc(); |
8437 | if (parseOptionalAddrSpace(AddrSpace)) |
8438 | return true; |
8439 | } else if (Lex.getKind() == lltok::MetadataVar) { |
8440 | AteExtraComma = true; |
8441 | } else { |
8442 | if (parseTypeAndValue(V&: Size, Loc&: SizeLoc, PFS)) |
8443 | return true; |
8444 | if (EatIfPresent(T: lltok::comma)) { |
8445 | if (Lex.getKind() == lltok::kw_align) { |
8446 | if (parseOptionalAlignment(Alignment)) |
8447 | return true; |
8448 | if (parseOptionalCommaAddrSpace(AddrSpace, Loc&: ASLoc, AteExtraComma)) |
8449 | return true; |
8450 | } else if (Lex.getKind() == lltok::kw_addrspace) { |
8451 | ASLoc = Lex.getLoc(); |
8452 | if (parseOptionalAddrSpace(AddrSpace)) |
8453 | return true; |
8454 | } else if (Lex.getKind() == lltok::MetadataVar) { |
8455 | AteExtraComma = true; |
8456 | } |
8457 | } |
8458 | } |
8459 | } |
8460 | |
8461 | if (Size && !Size->getType()->isIntegerTy()) |
8462 | return error(L: SizeLoc, Msg: "element count must have integer type" ); |
8463 | |
8464 | SmallPtrSet<Type *, 4> Visited; |
8465 | if (!Alignment && !Ty->isSized(Visited: &Visited)) |
8466 | return error(L: TyLoc, Msg: "Cannot allocate unsized type" ); |
8467 | if (!Alignment) |
8468 | Alignment = M->getDataLayout().getPrefTypeAlign(Ty); |
8469 | AllocaInst *AI = new AllocaInst(Ty, AddrSpace, Size, *Alignment); |
8470 | AI->setUsedWithInAlloca(IsInAlloca); |
8471 | AI->setSwiftError(IsSwiftError); |
8472 | Inst = AI; |
8473 | return AteExtraComma ? InstExtraComma : InstNormal; |
8474 | } |
8475 | |
8476 | /// parseLoad |
8477 | /// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? |
8478 | /// ::= 'load' 'atomic' 'volatile'? TypeAndValue |
8479 | /// 'singlethread'? AtomicOrdering (',' 'align' i32)? |
8480 | int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) { |
8481 | Value *Val; LocTy Loc; |
8482 | MaybeAlign Alignment; |
8483 | bool = false; |
8484 | bool isAtomic = false; |
8485 | AtomicOrdering Ordering = AtomicOrdering::NotAtomic; |
8486 | SyncScope::ID SSID = SyncScope::System; |
8487 | |
8488 | if (Lex.getKind() == lltok::kw_atomic) { |
8489 | isAtomic = true; |
8490 | Lex.Lex(); |
8491 | } |
8492 | |
8493 | bool isVolatile = false; |
8494 | if (Lex.getKind() == lltok::kw_volatile) { |
8495 | isVolatile = true; |
8496 | Lex.Lex(); |
8497 | } |
8498 | |
8499 | Type *Ty; |
8500 | LocTy ExplicitTypeLoc = Lex.getLoc(); |
8501 | if (parseType(Result&: Ty) || |
8502 | parseToken(T: lltok::comma, ErrMsg: "expected comma after load's type" ) || |
8503 | parseTypeAndValue(V&: Val, Loc, PFS) || |
8504 | parseScopeAndOrdering(IsAtomic: isAtomic, SSID, Ordering) || |
8505 | parseOptionalCommaAlign(Alignment, AteExtraComma)) |
8506 | return true; |
8507 | |
8508 | if (!Val->getType()->isPointerTy() || !Ty->isFirstClassType()) |
8509 | return error(L: Loc, Msg: "load operand must be a pointer to a first class type" ); |
8510 | if (isAtomic && !Alignment) |
8511 | return error(L: Loc, Msg: "atomic load must have explicit non-zero alignment" ); |
8512 | if (Ordering == AtomicOrdering::Release || |
8513 | Ordering == AtomicOrdering::AcquireRelease) |
8514 | return error(L: Loc, Msg: "atomic load cannot use Release ordering" ); |
8515 | |
8516 | SmallPtrSet<Type *, 4> Visited; |
8517 | if (!Alignment && !Ty->isSized(Visited: &Visited)) |
8518 | return error(L: ExplicitTypeLoc, Msg: "loading unsized types is not allowed" ); |
8519 | if (!Alignment) |
8520 | Alignment = M->getDataLayout().getABITypeAlign(Ty); |
8521 | Inst = new LoadInst(Ty, Val, "" , isVolatile, *Alignment, Ordering, SSID); |
8522 | return AteExtraComma ? InstExtraComma : InstNormal; |
8523 | } |
8524 | |
8525 | /// parseStore |
8526 | |
8527 | /// ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)? |
8528 | /// ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue |
8529 | /// 'singlethread'? AtomicOrdering (',' 'align' i32)? |
8530 | int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) { |
8531 | Value *Val, *Ptr; LocTy Loc, PtrLoc; |
8532 | MaybeAlign Alignment; |
8533 | bool = false; |
8534 | bool isAtomic = false; |
8535 | AtomicOrdering Ordering = AtomicOrdering::NotAtomic; |
8536 | SyncScope::ID SSID = SyncScope::System; |
8537 | |
8538 | if (Lex.getKind() == lltok::kw_atomic) { |
8539 | isAtomic = true; |
8540 | Lex.Lex(); |
8541 | } |
8542 | |
8543 | bool isVolatile = false; |
8544 | if (Lex.getKind() == lltok::kw_volatile) { |
8545 | isVolatile = true; |
8546 | Lex.Lex(); |
8547 | } |
8548 | |
8549 | if (parseTypeAndValue(V&: Val, Loc, PFS) || |
8550 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after store operand" ) || |
8551 | parseTypeAndValue(V&: Ptr, Loc&: PtrLoc, PFS) || |
8552 | parseScopeAndOrdering(IsAtomic: isAtomic, SSID, Ordering) || |
8553 | parseOptionalCommaAlign(Alignment, AteExtraComma)) |
8554 | return true; |
8555 | |
8556 | if (!Ptr->getType()->isPointerTy()) |
8557 | return error(L: PtrLoc, Msg: "store operand must be a pointer" ); |
8558 | if (!Val->getType()->isFirstClassType()) |
8559 | return error(L: Loc, Msg: "store operand must be a first class value" ); |
8560 | if (isAtomic && !Alignment) |
8561 | return error(L: Loc, Msg: "atomic store must have explicit non-zero alignment" ); |
8562 | if (Ordering == AtomicOrdering::Acquire || |
8563 | Ordering == AtomicOrdering::AcquireRelease) |
8564 | return error(L: Loc, Msg: "atomic store cannot use Acquire ordering" ); |
8565 | SmallPtrSet<Type *, 4> Visited; |
8566 | if (!Alignment && !Val->getType()->isSized(Visited: &Visited)) |
8567 | return error(L: Loc, Msg: "storing unsized types is not allowed" ); |
8568 | if (!Alignment) |
8569 | Alignment = M->getDataLayout().getABITypeAlign(Ty: Val->getType()); |
8570 | |
8571 | Inst = new StoreInst(Val, Ptr, isVolatile, *Alignment, Ordering, SSID); |
8572 | return AteExtraComma ? InstExtraComma : InstNormal; |
8573 | } |
8574 | |
8575 | /// parseCmpXchg |
8576 | /// ::= 'cmpxchg' 'weak'? 'volatile'? TypeAndValue ',' TypeAndValue ',' |
8577 | /// TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering ',' |
8578 | /// 'Align'? |
8579 | int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { |
8580 | Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc; |
8581 | bool = false; |
8582 | AtomicOrdering SuccessOrdering = AtomicOrdering::NotAtomic; |
8583 | AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic; |
8584 | SyncScope::ID SSID = SyncScope::System; |
8585 | bool isVolatile = false; |
8586 | bool isWeak = false; |
8587 | MaybeAlign Alignment; |
8588 | |
8589 | if (EatIfPresent(T: lltok::kw_weak)) |
8590 | isWeak = true; |
8591 | |
8592 | if (EatIfPresent(T: lltok::kw_volatile)) |
8593 | isVolatile = true; |
8594 | |
8595 | if (parseTypeAndValue(V&: Ptr, Loc&: PtrLoc, PFS) || |
8596 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after cmpxchg address" ) || |
8597 | parseTypeAndValue(V&: Cmp, Loc&: CmpLoc, PFS) || |
8598 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after cmpxchg cmp operand" ) || |
8599 | parseTypeAndValue(V&: New, Loc&: NewLoc, PFS) || |
8600 | parseScopeAndOrdering(IsAtomic: true /*Always atomic*/, SSID, Ordering&: SuccessOrdering) || |
8601 | parseOrdering(Ordering&: FailureOrdering) || |
8602 | parseOptionalCommaAlign(Alignment, AteExtraComma)) |
8603 | return true; |
8604 | |
8605 | if (!AtomicCmpXchgInst::isValidSuccessOrdering(Ordering: SuccessOrdering)) |
8606 | return tokError(Msg: "invalid cmpxchg success ordering" ); |
8607 | if (!AtomicCmpXchgInst::isValidFailureOrdering(Ordering: FailureOrdering)) |
8608 | return tokError(Msg: "invalid cmpxchg failure ordering" ); |
8609 | if (!Ptr->getType()->isPointerTy()) |
8610 | return error(L: PtrLoc, Msg: "cmpxchg operand must be a pointer" ); |
8611 | if (Cmp->getType() != New->getType()) |
8612 | return error(L: NewLoc, Msg: "compare value and new value type do not match" ); |
8613 | if (!New->getType()->isFirstClassType()) |
8614 | return error(L: NewLoc, Msg: "cmpxchg operand must be a first class value" ); |
8615 | |
8616 | const Align DefaultAlignment( |
8617 | PFS.getFunction().getDataLayout().getTypeStoreSize( |
8618 | Ty: Cmp->getType())); |
8619 | |
8620 | AtomicCmpXchgInst *CXI = |
8621 | new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment.value_or(u: DefaultAlignment), |
8622 | SuccessOrdering, FailureOrdering, SSID); |
8623 | CXI->setVolatile(isVolatile); |
8624 | CXI->setWeak(isWeak); |
8625 | |
8626 | Inst = CXI; |
8627 | return AteExtraComma ? InstExtraComma : InstNormal; |
8628 | } |
8629 | |
8630 | /// parseAtomicRMW |
8631 | /// ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue |
8632 | /// 'singlethread'? AtomicOrdering |
8633 | int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { |
8634 | Value *Ptr, *Val; LocTy PtrLoc, ValLoc; |
8635 | bool = false; |
8636 | AtomicOrdering Ordering = AtomicOrdering::NotAtomic; |
8637 | SyncScope::ID SSID = SyncScope::System; |
8638 | bool isVolatile = false; |
8639 | bool IsFP = false; |
8640 | AtomicRMWInst::BinOp Operation; |
8641 | MaybeAlign Alignment; |
8642 | |
8643 | if (EatIfPresent(T: lltok::kw_volatile)) |
8644 | isVolatile = true; |
8645 | |
8646 | switch (Lex.getKind()) { |
8647 | default: |
8648 | return tokError(Msg: "expected binary operation in atomicrmw" ); |
8649 | case lltok::kw_xchg: Operation = AtomicRMWInst::Xchg; break; |
8650 | case lltok::kw_add: Operation = AtomicRMWInst::Add; break; |
8651 | case lltok::kw_sub: Operation = AtomicRMWInst::Sub; break; |
8652 | case lltok::kw_and: Operation = AtomicRMWInst::And; break; |
8653 | case lltok::kw_nand: Operation = AtomicRMWInst::Nand; break; |
8654 | case lltok::kw_or: Operation = AtomicRMWInst::Or; break; |
8655 | case lltok::kw_xor: Operation = AtomicRMWInst::Xor; break; |
8656 | case lltok::kw_max: Operation = AtomicRMWInst::Max; break; |
8657 | case lltok::kw_min: Operation = AtomicRMWInst::Min; break; |
8658 | case lltok::kw_umax: Operation = AtomicRMWInst::UMax; break; |
8659 | case lltok::kw_umin: Operation = AtomicRMWInst::UMin; break; |
8660 | case lltok::kw_uinc_wrap: |
8661 | Operation = AtomicRMWInst::UIncWrap; |
8662 | break; |
8663 | case lltok::kw_udec_wrap: |
8664 | Operation = AtomicRMWInst::UDecWrap; |
8665 | break; |
8666 | case lltok::kw_usub_cond: |
8667 | Operation = AtomicRMWInst::USubCond; |
8668 | break; |
8669 | case lltok::kw_usub_sat: |
8670 | Operation = AtomicRMWInst::USubSat; |
8671 | break; |
8672 | case lltok::kw_fadd: |
8673 | Operation = AtomicRMWInst::FAdd; |
8674 | IsFP = true; |
8675 | break; |
8676 | case lltok::kw_fsub: |
8677 | Operation = AtomicRMWInst::FSub; |
8678 | IsFP = true; |
8679 | break; |
8680 | case lltok::kw_fmax: |
8681 | Operation = AtomicRMWInst::FMax; |
8682 | IsFP = true; |
8683 | break; |
8684 | case lltok::kw_fmin: |
8685 | Operation = AtomicRMWInst::FMin; |
8686 | IsFP = true; |
8687 | break; |
8688 | case lltok::kw_fmaximum: |
8689 | Operation = AtomicRMWInst::FMaximum; |
8690 | IsFP = true; |
8691 | break; |
8692 | case lltok::kw_fminimum: |
8693 | Operation = AtomicRMWInst::FMinimum; |
8694 | IsFP = true; |
8695 | break; |
8696 | } |
8697 | Lex.Lex(); // Eat the operation. |
8698 | |
8699 | if (parseTypeAndValue(V&: Ptr, Loc&: PtrLoc, PFS) || |
8700 | parseToken(T: lltok::comma, ErrMsg: "expected ',' after atomicrmw address" ) || |
8701 | parseTypeAndValue(V&: Val, Loc&: ValLoc, PFS) || |
8702 | parseScopeAndOrdering(IsAtomic: true /*Always atomic*/, SSID, Ordering) || |
8703 | parseOptionalCommaAlign(Alignment, AteExtraComma)) |
8704 | return true; |
8705 | |
8706 | if (Ordering == AtomicOrdering::Unordered) |
8707 | return tokError(Msg: "atomicrmw cannot be unordered" ); |
8708 | if (!Ptr->getType()->isPointerTy()) |
8709 | return error(L: PtrLoc, Msg: "atomicrmw operand must be a pointer" ); |
8710 | if (Val->getType()->isScalableTy()) |
8711 | return error(L: ValLoc, Msg: "atomicrmw operand may not be scalable" ); |
8712 | |
8713 | if (Operation == AtomicRMWInst::Xchg) { |
8714 | if (!Val->getType()->isIntegerTy() && |
8715 | !Val->getType()->isFloatingPointTy() && |
8716 | !Val->getType()->isPointerTy()) { |
8717 | return error( |
8718 | L: ValLoc, |
8719 | Msg: "atomicrmw " + AtomicRMWInst::getOperationName(Op: Operation) + |
8720 | " operand must be an integer, floating point, or pointer type" ); |
8721 | } |
8722 | } else if (IsFP) { |
8723 | if (!Val->getType()->isFPOrFPVectorTy()) { |
8724 | return error(L: ValLoc, Msg: "atomicrmw " + |
8725 | AtomicRMWInst::getOperationName(Op: Operation) + |
8726 | " operand must be a floating point type" ); |
8727 | } |
8728 | } else { |
8729 | if (!Val->getType()->isIntegerTy()) { |
8730 | return error(L: ValLoc, Msg: "atomicrmw " + |
8731 | AtomicRMWInst::getOperationName(Op: Operation) + |
8732 | " operand must be an integer" ); |
8733 | } |
8734 | } |
8735 | |
8736 | unsigned Size = |
8737 | PFS.getFunction().getDataLayout().getTypeStoreSizeInBits( |
8738 | Ty: Val->getType()); |
8739 | if (Size < 8 || (Size & (Size - 1))) |
8740 | return error(L: ValLoc, Msg: "atomicrmw operand must be power-of-two byte-sized" |
8741 | " integer" ); |
8742 | const Align DefaultAlignment( |
8743 | PFS.getFunction().getDataLayout().getTypeStoreSize( |
8744 | Ty: Val->getType())); |
8745 | AtomicRMWInst *RMWI = |
8746 | new AtomicRMWInst(Operation, Ptr, Val, |
8747 | Alignment.value_or(u: DefaultAlignment), Ordering, SSID); |
8748 | RMWI->setVolatile(isVolatile); |
8749 | Inst = RMWI; |
8750 | return AteExtraComma ? InstExtraComma : InstNormal; |
8751 | } |
8752 | |
8753 | /// parseFence |
8754 | /// ::= 'fence' 'singlethread'? AtomicOrdering |
8755 | int LLParser::parseFence(Instruction *&Inst, PerFunctionState &PFS) { |
8756 | AtomicOrdering Ordering = AtomicOrdering::NotAtomic; |
8757 | SyncScope::ID SSID = SyncScope::System; |
8758 | if (parseScopeAndOrdering(IsAtomic: true /*Always atomic*/, SSID, Ordering)) |
8759 | return true; |
8760 | |
8761 | if (Ordering == AtomicOrdering::Unordered) |
8762 | return tokError(Msg: "fence cannot be unordered" ); |
8763 | if (Ordering == AtomicOrdering::Monotonic) |
8764 | return tokError(Msg: "fence cannot be monotonic" ); |
8765 | |
8766 | Inst = new FenceInst(Context, Ordering, SSID); |
8767 | return InstNormal; |
8768 | } |
8769 | |
8770 | /// parseGetElementPtr |
8771 | /// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* |
8772 | int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { |
8773 | Value *Ptr = nullptr; |
8774 | Value *Val = nullptr; |
8775 | LocTy Loc, EltLoc; |
8776 | GEPNoWrapFlags NW; |
8777 | |
8778 | while (true) { |
8779 | if (EatIfPresent(T: lltok::kw_inbounds)) |
8780 | NW |= GEPNoWrapFlags::inBounds(); |
8781 | else if (EatIfPresent(T: lltok::kw_nusw)) |
8782 | NW |= GEPNoWrapFlags::noUnsignedSignedWrap(); |
8783 | else if (EatIfPresent(T: lltok::kw_nuw)) |
8784 | NW |= GEPNoWrapFlags::noUnsignedWrap(); |
8785 | else |
8786 | break; |
8787 | } |
8788 | |
8789 | Type *Ty = nullptr; |
8790 | if (parseType(Result&: Ty) || |
8791 | parseToken(T: lltok::comma, ErrMsg: "expected comma after getelementptr's type" ) || |
8792 | parseTypeAndValue(V&: Ptr, Loc, PFS)) |
8793 | return true; |
8794 | |
8795 | Type *BaseType = Ptr->getType(); |
8796 | PointerType *BasePointerType = dyn_cast<PointerType>(Val: BaseType->getScalarType()); |
8797 | if (!BasePointerType) |
8798 | return error(L: Loc, Msg: "base of getelementptr must be a pointer" ); |
8799 | |
8800 | SmallVector<Value*, 16> Indices; |
8801 | bool = false; |
8802 | // GEP returns a vector of pointers if at least one of parameters is a vector. |
8803 | // All vector parameters should have the same vector width. |
8804 | ElementCount GEPWidth = BaseType->isVectorTy() |
8805 | ? cast<VectorType>(Val: BaseType)->getElementCount() |
8806 | : ElementCount::getFixed(MinVal: 0); |
8807 | |
8808 | while (EatIfPresent(T: lltok::comma)) { |
8809 | if (Lex.getKind() == lltok::MetadataVar) { |
8810 | AteExtraComma = true; |
8811 | break; |
8812 | } |
8813 | if (parseTypeAndValue(V&: Val, Loc&: EltLoc, PFS)) |
8814 | return true; |
8815 | if (!Val->getType()->isIntOrIntVectorTy()) |
8816 | return error(L: EltLoc, Msg: "getelementptr index must be an integer" ); |
8817 | |
8818 | if (auto *ValVTy = dyn_cast<VectorType>(Val: Val->getType())) { |
8819 | ElementCount ValNumEl = ValVTy->getElementCount(); |
8820 | if (GEPWidth != ElementCount::getFixed(MinVal: 0) && GEPWidth != ValNumEl) |
8821 | return error( |
8822 | L: EltLoc, |
8823 | Msg: "getelementptr vector index has a wrong number of elements" ); |
8824 | GEPWidth = ValNumEl; |
8825 | } |
8826 | Indices.push_back(Elt: Val); |
8827 | } |
8828 | |
8829 | SmallPtrSet<Type*, 4> Visited; |
8830 | if (!Indices.empty() && !Ty->isSized(Visited: &Visited)) |
8831 | return error(L: Loc, Msg: "base element of getelementptr must be sized" ); |
8832 | |
8833 | auto *STy = dyn_cast<StructType>(Val: Ty); |
8834 | if (STy && STy->isScalableTy()) |
8835 | return error(L: Loc, Msg: "getelementptr cannot target structure that contains " |
8836 | "scalable vector type" ); |
8837 | |
8838 | if (!GetElementPtrInst::getIndexedType(Ty, IdxList: Indices)) |
8839 | return error(L: Loc, Msg: "invalid getelementptr indices" ); |
8840 | GetElementPtrInst *GEP = GetElementPtrInst::Create(PointeeType: Ty, Ptr, IdxList: Indices); |
8841 | Inst = GEP; |
8842 | GEP->setNoWrapFlags(NW); |
8843 | return AteExtraComma ? InstExtraComma : InstNormal; |
8844 | } |
8845 | |
8846 | /// parseExtractValue |
8847 | /// ::= 'extractvalue' TypeAndValue (',' uint32)+ |
8848 | int LLParser::(Instruction *&Inst, PerFunctionState &PFS) { |
8849 | Value *Val; LocTy Loc; |
8850 | SmallVector<unsigned, 4> Indices; |
8851 | bool ; |
8852 | if (parseTypeAndValue(V&: Val, Loc, PFS) || |
8853 | parseIndexList(Indices, AteExtraComma)) |
8854 | return true; |
8855 | |
8856 | if (!Val->getType()->isAggregateType()) |
8857 | return error(L: Loc, Msg: "extractvalue operand must be aggregate type" ); |
8858 | |
8859 | if (!ExtractValueInst::getIndexedType(Agg: Val->getType(), Idxs: Indices)) |
8860 | return error(L: Loc, Msg: "invalid indices for extractvalue" ); |
8861 | Inst = ExtractValueInst::Create(Agg: Val, Idxs: Indices); |
8862 | return AteExtraComma ? InstExtraComma : InstNormal; |
8863 | } |
8864 | |
8865 | /// parseInsertValue |
8866 | /// ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+ |
8867 | int LLParser::parseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { |
8868 | Value *Val0, *Val1; LocTy Loc0, Loc1; |
8869 | SmallVector<unsigned, 4> Indices; |
8870 | bool ; |
8871 | if (parseTypeAndValue(V&: Val0, Loc&: Loc0, PFS) || |
8872 | parseToken(T: lltok::comma, ErrMsg: "expected comma after insertvalue operand" ) || |
8873 | parseTypeAndValue(V&: Val1, Loc&: Loc1, PFS) || |
8874 | parseIndexList(Indices, AteExtraComma)) |
8875 | return true; |
8876 | |
8877 | if (!Val0->getType()->isAggregateType()) |
8878 | return error(L: Loc0, Msg: "insertvalue operand must be aggregate type" ); |
8879 | |
8880 | Type *IndexedType = ExtractValueInst::getIndexedType(Agg: Val0->getType(), Idxs: Indices); |
8881 | if (!IndexedType) |
8882 | return error(L: Loc0, Msg: "invalid indices for insertvalue" ); |
8883 | if (IndexedType != Val1->getType()) |
8884 | return error(L: Loc1, Msg: "insertvalue operand and field disagree in type: '" + |
8885 | getTypeString(T: Val1->getType()) + "' instead of '" + |
8886 | getTypeString(T: IndexedType) + "'" ); |
8887 | Inst = InsertValueInst::Create(Agg: Val0, Val: Val1, Idxs: Indices); |
8888 | return AteExtraComma ? InstExtraComma : InstNormal; |
8889 | } |
8890 | |
8891 | //===----------------------------------------------------------------------===// |
8892 | // Embedded metadata. |
8893 | //===----------------------------------------------------------------------===// |
8894 | |
8895 | /// parseMDNodeVector |
8896 | /// ::= { Element (',' Element)* } |
8897 | /// Element |
8898 | /// ::= 'null' | Metadata |
8899 | bool LLParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) { |
8900 | if (parseToken(T: lltok::lbrace, ErrMsg: "expected '{' here" )) |
8901 | return true; |
8902 | |
8903 | // Check for an empty list. |
8904 | if (EatIfPresent(T: lltok::rbrace)) |
8905 | return false; |
8906 | |
8907 | do { |
8908 | if (EatIfPresent(T: lltok::kw_null)) { |
8909 | Elts.push_back(Elt: nullptr); |
8910 | continue; |
8911 | } |
8912 | |
8913 | Metadata *MD; |
8914 | if (parseMetadata(MD, PFS: nullptr)) |
8915 | return true; |
8916 | Elts.push_back(Elt: MD); |
8917 | } while (EatIfPresent(T: lltok::comma)); |
8918 | |
8919 | return parseToken(T: lltok::rbrace, ErrMsg: "expected end of metadata node" ); |
8920 | } |
8921 | |
8922 | //===----------------------------------------------------------------------===// |
8923 | // Use-list order directives. |
8924 | //===----------------------------------------------------------------------===// |
8925 | bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes, |
8926 | SMLoc Loc) { |
8927 | if (!V->hasUseList()) |
8928 | return false; |
8929 | if (V->use_empty()) |
8930 | return error(L: Loc, Msg: "value has no uses" ); |
8931 | |
8932 | unsigned NumUses = 0; |
8933 | SmallDenseMap<const Use *, unsigned, 16> Order; |
8934 | for (const Use &U : V->uses()) { |
8935 | if (++NumUses > Indexes.size()) |
8936 | break; |
8937 | Order[&U] = Indexes[NumUses - 1]; |
8938 | } |
8939 | if (NumUses < 2) |
8940 | return error(L: Loc, Msg: "value only has one use" ); |
8941 | if (Order.size() != Indexes.size() || NumUses > Indexes.size()) |
8942 | return error(L: Loc, |
8943 | Msg: "wrong number of indexes, expected " + Twine(V->getNumUses())); |
8944 | |
8945 | V->sortUseList(Cmp: [&](const Use &L, const Use &R) { |
8946 | return Order.lookup(Val: &L) < Order.lookup(Val: &R); |
8947 | }); |
8948 | return false; |
8949 | } |
8950 | |
8951 | /// parseUseListOrderIndexes |
8952 | /// ::= '{' uint32 (',' uint32)+ '}' |
8953 | bool LLParser::parseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) { |
8954 | SMLoc Loc = Lex.getLoc(); |
8955 | if (parseToken(T: lltok::lbrace, ErrMsg: "expected '{' here" )) |
8956 | return true; |
8957 | if (Lex.getKind() == lltok::rbrace) |
8958 | return tokError(Msg: "expected non-empty list of uselistorder indexes" ); |
8959 | |
8960 | // Use Offset, Max, and IsOrdered to check consistency of indexes. The |
8961 | // indexes should be distinct numbers in the range [0, size-1], and should |
8962 | // not be in order. |
8963 | unsigned Offset = 0; |
8964 | unsigned Max = 0; |
8965 | bool IsOrdered = true; |
8966 | assert(Indexes.empty() && "Expected empty order vector" ); |
8967 | do { |
8968 | unsigned Index; |
8969 | if (parseUInt32(Val&: Index)) |
8970 | return true; |
8971 | |
8972 | // Update consistency checks. |
8973 | Offset += Index - Indexes.size(); |
8974 | Max = std::max(a: Max, b: Index); |
8975 | IsOrdered &= Index == Indexes.size(); |
8976 | |
8977 | Indexes.push_back(Elt: Index); |
8978 | } while (EatIfPresent(T: lltok::comma)); |
8979 | |
8980 | if (parseToken(T: lltok::rbrace, ErrMsg: "expected '}' here" )) |
8981 | return true; |
8982 | |
8983 | if (Indexes.size() < 2) |
8984 | return error(L: Loc, Msg: "expected >= 2 uselistorder indexes" ); |
8985 | if (Offset != 0 || Max >= Indexes.size()) |
8986 | return error(L: Loc, |
8987 | Msg: "expected distinct uselistorder indexes in range [0, size)" ); |
8988 | if (IsOrdered) |
8989 | return error(L: Loc, Msg: "expected uselistorder indexes to change the order" ); |
8990 | |
8991 | return false; |
8992 | } |
8993 | |
8994 | /// parseUseListOrder |
8995 | /// ::= 'uselistorder' Type Value ',' UseListOrderIndexes |
8996 | bool LLParser::parseUseListOrder(PerFunctionState *PFS) { |
8997 | SMLoc Loc = Lex.getLoc(); |
8998 | if (parseToken(T: lltok::kw_uselistorder, ErrMsg: "expected uselistorder directive" )) |
8999 | return true; |
9000 | |
9001 | Value *V; |
9002 | SmallVector<unsigned, 16> Indexes; |
9003 | if (parseTypeAndValue(V, PFS) || |
9004 | parseToken(T: lltok::comma, ErrMsg: "expected comma in uselistorder directive" ) || |
9005 | parseUseListOrderIndexes(Indexes)) |
9006 | return true; |
9007 | |
9008 | return sortUseListOrder(V, Indexes, Loc); |
9009 | } |
9010 | |
9011 | /// parseUseListOrderBB |
9012 | /// ::= 'uselistorder_bb' @foo ',' %bar ',' UseListOrderIndexes |
9013 | bool LLParser::parseUseListOrderBB() { |
9014 | assert(Lex.getKind() == lltok::kw_uselistorder_bb); |
9015 | SMLoc Loc = Lex.getLoc(); |
9016 | Lex.Lex(); |
9017 | |
9018 | ValID Fn, Label; |
9019 | SmallVector<unsigned, 16> Indexes; |
9020 | if (parseValID(ID&: Fn, /*PFS=*/nullptr) || |
9021 | parseToken(T: lltok::comma, ErrMsg: "expected comma in uselistorder_bb directive" ) || |
9022 | parseValID(ID&: Label, /*PFS=*/nullptr) || |
9023 | parseToken(T: lltok::comma, ErrMsg: "expected comma in uselistorder_bb directive" ) || |
9024 | parseUseListOrderIndexes(Indexes)) |
9025 | return true; |
9026 | |
9027 | // Check the function. |
9028 | GlobalValue *GV; |
9029 | if (Fn.Kind == ValID::t_GlobalName) |
9030 | GV = M->getNamedValue(Name: Fn.StrVal); |
9031 | else if (Fn.Kind == ValID::t_GlobalID) |
9032 | GV = NumberedVals.get(ID: Fn.UIntVal); |
9033 | else |
9034 | return error(L: Fn.Loc, Msg: "expected function name in uselistorder_bb" ); |
9035 | if (!GV) |
9036 | return error(L: Fn.Loc, |
9037 | Msg: "invalid function forward reference in uselistorder_bb" ); |
9038 | auto *F = dyn_cast<Function>(Val: GV); |
9039 | if (!F) |
9040 | return error(L: Fn.Loc, Msg: "expected function name in uselistorder_bb" ); |
9041 | if (F->isDeclaration()) |
9042 | return error(L: Fn.Loc, Msg: "invalid declaration in uselistorder_bb" ); |
9043 | |
9044 | // Check the basic block. |
9045 | if (Label.Kind == ValID::t_LocalID) |
9046 | return error(L: Label.Loc, Msg: "invalid numeric label in uselistorder_bb" ); |
9047 | if (Label.Kind != ValID::t_LocalName) |
9048 | return error(L: Label.Loc, Msg: "expected basic block name in uselistorder_bb" ); |
9049 | Value *V = F->getValueSymbolTable()->lookup(Name: Label.StrVal); |
9050 | if (!V) |
9051 | return error(L: Label.Loc, Msg: "invalid basic block in uselistorder_bb" ); |
9052 | if (!isa<BasicBlock>(Val: V)) |
9053 | return error(L: Label.Loc, Msg: "expected basic block in uselistorder_bb" ); |
9054 | |
9055 | return sortUseListOrder(V, Indexes, Loc); |
9056 | } |
9057 | |
9058 | /// ModuleEntry |
9059 | /// ::= 'module' ':' '(' 'path' ':' STRINGCONSTANT ',' 'hash' ':' Hash ')' |
9060 | /// Hash ::= '(' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ',' UInt32 ')' |
9061 | bool LLParser::parseModuleEntry(unsigned ID) { |
9062 | assert(Lex.getKind() == lltok::kw_module); |
9063 | Lex.Lex(); |
9064 | |
9065 | std::string Path; |
9066 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9067 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9068 | parseToken(T: lltok::kw_path, ErrMsg: "expected 'path' here" ) || |
9069 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9070 | parseStringConstant(Result&: Path) || |
9071 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9072 | parseToken(T: lltok::kw_hash, ErrMsg: "expected 'hash' here" ) || |
9073 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9074 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9075 | return true; |
9076 | |
9077 | ModuleHash Hash; |
9078 | if (parseUInt32(Val&: Hash[0]) || parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9079 | parseUInt32(Val&: Hash[1]) || parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9080 | parseUInt32(Val&: Hash[2]) || parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9081 | parseUInt32(Val&: Hash[3]) || parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9082 | parseUInt32(Val&: Hash[4])) |
9083 | return true; |
9084 | |
9085 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" ) || |
9086 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9087 | return true; |
9088 | |
9089 | auto ModuleEntry = Index->addModule(ModPath: Path, Hash); |
9090 | ModuleIdMap[ID] = ModuleEntry->first(); |
9091 | |
9092 | return false; |
9093 | } |
9094 | |
9095 | /// TypeIdEntry |
9096 | /// ::= 'typeid' ':' '(' 'name' ':' STRINGCONSTANT ',' TypeIdSummary ')' |
9097 | bool LLParser::parseTypeIdEntry(unsigned ID) { |
9098 | assert(Lex.getKind() == lltok::kw_typeid); |
9099 | Lex.Lex(); |
9100 | |
9101 | std::string Name; |
9102 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9103 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9104 | parseToken(T: lltok::kw_name, ErrMsg: "expected 'name' here" ) || |
9105 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9106 | parseStringConstant(Result&: Name)) |
9107 | return true; |
9108 | |
9109 | TypeIdSummary &TIS = Index->getOrInsertTypeIdSummary(TypeId: Name); |
9110 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9111 | parseTypeIdSummary(TIS) || parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9112 | return true; |
9113 | |
9114 | // Check if this ID was forward referenced, and if so, update the |
9115 | // corresponding GUIDs. |
9116 | auto FwdRefTIDs = ForwardRefTypeIds.find(x: ID); |
9117 | if (FwdRefTIDs != ForwardRefTypeIds.end()) { |
9118 | for (auto TIDRef : FwdRefTIDs->second) { |
9119 | assert(!*TIDRef.first && |
9120 | "Forward referenced type id GUID expected to be 0" ); |
9121 | *TIDRef.first = GlobalValue::getGUIDAssumingExternalLinkage(GlobalName: Name); |
9122 | } |
9123 | ForwardRefTypeIds.erase(position: FwdRefTIDs); |
9124 | } |
9125 | |
9126 | return false; |
9127 | } |
9128 | |
9129 | /// TypeIdSummary |
9130 | /// ::= 'summary' ':' '(' TypeTestResolution [',' OptionalWpdResolutions]? ')' |
9131 | bool LLParser::parseTypeIdSummary(TypeIdSummary &TIS) { |
9132 | if (parseToken(T: lltok::kw_summary, ErrMsg: "expected 'summary' here" ) || |
9133 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9134 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9135 | parseTypeTestResolution(TTRes&: TIS.TTRes)) |
9136 | return true; |
9137 | |
9138 | if (EatIfPresent(T: lltok::comma)) { |
9139 | // Expect optional wpdResolutions field |
9140 | if (parseOptionalWpdResolutions(WPDResMap&: TIS.WPDRes)) |
9141 | return true; |
9142 | } |
9143 | |
9144 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9145 | return true; |
9146 | |
9147 | return false; |
9148 | } |
9149 | |
9150 | static ValueInfo EmptyVI = |
9151 | ValueInfo(false, (GlobalValueSummaryMapTy::value_type *)-8); |
9152 | |
9153 | /// TypeIdCompatibleVtableEntry |
9154 | /// ::= 'typeidCompatibleVTable' ':' '(' 'name' ':' STRINGCONSTANT ',' |
9155 | /// TypeIdCompatibleVtableInfo |
9156 | /// ')' |
9157 | bool LLParser::parseTypeIdCompatibleVtableEntry(unsigned ID) { |
9158 | assert(Lex.getKind() == lltok::kw_typeidCompatibleVTable); |
9159 | Lex.Lex(); |
9160 | |
9161 | std::string Name; |
9162 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9163 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9164 | parseToken(T: lltok::kw_name, ErrMsg: "expected 'name' here" ) || |
9165 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9166 | parseStringConstant(Result&: Name)) |
9167 | return true; |
9168 | |
9169 | TypeIdCompatibleVtableInfo &TI = |
9170 | Index->getOrInsertTypeIdCompatibleVtableSummary(TypeId: Name); |
9171 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9172 | parseToken(T: lltok::kw_summary, ErrMsg: "expected 'summary' here" ) || |
9173 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9174 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9175 | return true; |
9176 | |
9177 | IdToIndexMapType IdToIndexMap; |
9178 | // parse each call edge |
9179 | do { |
9180 | uint64_t Offset; |
9181 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9182 | parseToken(T: lltok::kw_offset, ErrMsg: "expected 'offset' here" ) || |
9183 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || parseUInt64(Val&: Offset) || |
9184 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" )) |
9185 | return true; |
9186 | |
9187 | LocTy Loc = Lex.getLoc(); |
9188 | unsigned GVId; |
9189 | ValueInfo VI; |
9190 | if (parseGVReference(VI, GVId)) |
9191 | return true; |
9192 | |
9193 | // Keep track of the TypeIdCompatibleVtableInfo array index needing a |
9194 | // forward reference. We will save the location of the ValueInfo needing an |
9195 | // update, but can only do so once the std::vector is finalized. |
9196 | if (VI == EmptyVI) |
9197 | IdToIndexMap[GVId].push_back(x: std::make_pair(x: TI.size(), y&: Loc)); |
9198 | TI.push_back(x: {Offset, VI}); |
9199 | |
9200 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in call" )) |
9201 | return true; |
9202 | } while (EatIfPresent(T: lltok::comma)); |
9203 | |
9204 | // Now that the TI vector is finalized, it is safe to save the locations |
9205 | // of any forward GV references that need updating later. |
9206 | for (auto I : IdToIndexMap) { |
9207 | auto &Infos = ForwardRefValueInfos[I.first]; |
9208 | for (auto P : I.second) { |
9209 | assert(TI[P.first].VTableVI == EmptyVI && |
9210 | "Forward referenced ValueInfo expected to be empty" ); |
9211 | Infos.emplace_back(args: &TI[P.first].VTableVI, args&: P.second); |
9212 | } |
9213 | } |
9214 | |
9215 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" ) || |
9216 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9217 | return true; |
9218 | |
9219 | // Check if this ID was forward referenced, and if so, update the |
9220 | // corresponding GUIDs. |
9221 | auto FwdRefTIDs = ForwardRefTypeIds.find(x: ID); |
9222 | if (FwdRefTIDs != ForwardRefTypeIds.end()) { |
9223 | for (auto TIDRef : FwdRefTIDs->second) { |
9224 | assert(!*TIDRef.first && |
9225 | "Forward referenced type id GUID expected to be 0" ); |
9226 | *TIDRef.first = GlobalValue::getGUIDAssumingExternalLinkage(GlobalName: Name); |
9227 | } |
9228 | ForwardRefTypeIds.erase(position: FwdRefTIDs); |
9229 | } |
9230 | |
9231 | return false; |
9232 | } |
9233 | |
9234 | /// TypeTestResolution |
9235 | /// ::= 'typeTestRes' ':' '(' 'kind' ':' |
9236 | /// ( 'unsat' | 'byteArray' | 'inline' | 'single' | 'allOnes' ) ',' |
9237 | /// 'sizeM1BitWidth' ':' SizeM1BitWidth [',' 'alignLog2' ':' UInt64]? |
9238 | /// [',' 'sizeM1' ':' UInt64]? [',' 'bitMask' ':' UInt8]? |
9239 | /// [',' 'inlinesBits' ':' UInt64]? ')' |
9240 | bool LLParser::parseTypeTestResolution(TypeTestResolution &TTRes) { |
9241 | if (parseToken(T: lltok::kw_typeTestRes, ErrMsg: "expected 'typeTestRes' here" ) || |
9242 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9243 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9244 | parseToken(T: lltok::kw_kind, ErrMsg: "expected 'kind' here" ) || |
9245 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
9246 | return true; |
9247 | |
9248 | switch (Lex.getKind()) { |
9249 | case lltok::kw_unknown: |
9250 | TTRes.TheKind = TypeTestResolution::Unknown; |
9251 | break; |
9252 | case lltok::kw_unsat: |
9253 | TTRes.TheKind = TypeTestResolution::Unsat; |
9254 | break; |
9255 | case lltok::kw_byteArray: |
9256 | TTRes.TheKind = TypeTestResolution::ByteArray; |
9257 | break; |
9258 | case lltok::kw_inline: |
9259 | TTRes.TheKind = TypeTestResolution::Inline; |
9260 | break; |
9261 | case lltok::kw_single: |
9262 | TTRes.TheKind = TypeTestResolution::Single; |
9263 | break; |
9264 | case lltok::kw_allOnes: |
9265 | TTRes.TheKind = TypeTestResolution::AllOnes; |
9266 | break; |
9267 | default: |
9268 | return error(L: Lex.getLoc(), Msg: "unexpected TypeTestResolution kind" ); |
9269 | } |
9270 | Lex.Lex(); |
9271 | |
9272 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9273 | parseToken(T: lltok::kw_sizeM1BitWidth, ErrMsg: "expected 'sizeM1BitWidth' here" ) || |
9274 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9275 | parseUInt32(Val&: TTRes.SizeM1BitWidth)) |
9276 | return true; |
9277 | |
9278 | // parse optional fields |
9279 | while (EatIfPresent(T: lltok::comma)) { |
9280 | switch (Lex.getKind()) { |
9281 | case lltok::kw_alignLog2: |
9282 | Lex.Lex(); |
9283 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || |
9284 | parseUInt64(Val&: TTRes.AlignLog2)) |
9285 | return true; |
9286 | break; |
9287 | case lltok::kw_sizeM1: |
9288 | Lex.Lex(); |
9289 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseUInt64(Val&: TTRes.SizeM1)) |
9290 | return true; |
9291 | break; |
9292 | case lltok::kw_bitMask: { |
9293 | unsigned Val; |
9294 | Lex.Lex(); |
9295 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseUInt32(Val)) |
9296 | return true; |
9297 | assert(Val <= 0xff); |
9298 | TTRes.BitMask = (uint8_t)Val; |
9299 | break; |
9300 | } |
9301 | case lltok::kw_inlineBits: |
9302 | Lex.Lex(); |
9303 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || |
9304 | parseUInt64(Val&: TTRes.InlineBits)) |
9305 | return true; |
9306 | break; |
9307 | default: |
9308 | return error(L: Lex.getLoc(), Msg: "expected optional TypeTestResolution field" ); |
9309 | } |
9310 | } |
9311 | |
9312 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9313 | return true; |
9314 | |
9315 | return false; |
9316 | } |
9317 | |
9318 | /// OptionalWpdResolutions |
9319 | /// ::= 'wpsResolutions' ':' '(' WpdResolution [',' WpdResolution]* ')' |
9320 | /// WpdResolution ::= '(' 'offset' ':' UInt64 ',' WpdRes ')' |
9321 | bool LLParser::parseOptionalWpdResolutions( |
9322 | std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap) { |
9323 | if (parseToken(T: lltok::kw_wpdResolutions, ErrMsg: "expected 'wpdResolutions' here" ) || |
9324 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9325 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9326 | return true; |
9327 | |
9328 | do { |
9329 | uint64_t Offset; |
9330 | WholeProgramDevirtResolution WPDRes; |
9331 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9332 | parseToken(T: lltok::kw_offset, ErrMsg: "expected 'offset' here" ) || |
9333 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || parseUInt64(Val&: Offset) || |
9334 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || parseWpdRes(WPDRes) || |
9335 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9336 | return true; |
9337 | WPDResMap[Offset] = WPDRes; |
9338 | } while (EatIfPresent(T: lltok::comma)); |
9339 | |
9340 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9341 | return true; |
9342 | |
9343 | return false; |
9344 | } |
9345 | |
9346 | /// WpdRes |
9347 | /// ::= 'wpdRes' ':' '(' 'kind' ':' 'indir' |
9348 | /// [',' OptionalResByArg]? ')' |
9349 | /// ::= 'wpdRes' ':' '(' 'kind' ':' 'singleImpl' |
9350 | /// ',' 'singleImplName' ':' STRINGCONSTANT ',' |
9351 | /// [',' OptionalResByArg]? ')' |
9352 | /// ::= 'wpdRes' ':' '(' 'kind' ':' 'branchFunnel' |
9353 | /// [',' OptionalResByArg]? ')' |
9354 | bool LLParser::parseWpdRes(WholeProgramDevirtResolution &WPDRes) { |
9355 | if (parseToken(T: lltok::kw_wpdRes, ErrMsg: "expected 'wpdRes' here" ) || |
9356 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9357 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9358 | parseToken(T: lltok::kw_kind, ErrMsg: "expected 'kind' here" ) || |
9359 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
9360 | return true; |
9361 | |
9362 | switch (Lex.getKind()) { |
9363 | case lltok::kw_indir: |
9364 | WPDRes.TheKind = WholeProgramDevirtResolution::Indir; |
9365 | break; |
9366 | case lltok::kw_singleImpl: |
9367 | WPDRes.TheKind = WholeProgramDevirtResolution::SingleImpl; |
9368 | break; |
9369 | case lltok::kw_branchFunnel: |
9370 | WPDRes.TheKind = WholeProgramDevirtResolution::BranchFunnel; |
9371 | break; |
9372 | default: |
9373 | return error(L: Lex.getLoc(), Msg: "unexpected WholeProgramDevirtResolution kind" ); |
9374 | } |
9375 | Lex.Lex(); |
9376 | |
9377 | // parse optional fields |
9378 | while (EatIfPresent(T: lltok::comma)) { |
9379 | switch (Lex.getKind()) { |
9380 | case lltok::kw_singleImplName: |
9381 | Lex.Lex(); |
9382 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9383 | parseStringConstant(Result&: WPDRes.SingleImplName)) |
9384 | return true; |
9385 | break; |
9386 | case lltok::kw_resByArg: |
9387 | if (parseOptionalResByArg(ResByArg&: WPDRes.ResByArg)) |
9388 | return true; |
9389 | break; |
9390 | default: |
9391 | return error(L: Lex.getLoc(), |
9392 | Msg: "expected optional WholeProgramDevirtResolution field" ); |
9393 | } |
9394 | } |
9395 | |
9396 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9397 | return true; |
9398 | |
9399 | return false; |
9400 | } |
9401 | |
9402 | /// OptionalResByArg |
9403 | /// ::= 'wpdRes' ':' '(' ResByArg[, ResByArg]* ')' |
9404 | /// ResByArg ::= Args ',' 'byArg' ':' '(' 'kind' ':' |
9405 | /// ( 'indir' | 'uniformRetVal' | 'UniqueRetVal' | |
9406 | /// 'virtualConstProp' ) |
9407 | /// [',' 'info' ':' UInt64]? [',' 'byte' ':' UInt32]? |
9408 | /// [',' 'bit' ':' UInt32]? ')' |
9409 | bool LLParser::parseOptionalResByArg( |
9410 | std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> |
9411 | &ResByArg) { |
9412 | if (parseToken(T: lltok::kw_resByArg, ErrMsg: "expected 'resByArg' here" ) || |
9413 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9414 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9415 | return true; |
9416 | |
9417 | do { |
9418 | std::vector<uint64_t> Args; |
9419 | if (parseArgs(Args) || parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9420 | parseToken(T: lltok::kw_byArg, ErrMsg: "expected 'byArg here" ) || |
9421 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9422 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9423 | parseToken(T: lltok::kw_kind, ErrMsg: "expected 'kind' here" ) || |
9424 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
9425 | return true; |
9426 | |
9427 | WholeProgramDevirtResolution::ByArg ByArg; |
9428 | switch (Lex.getKind()) { |
9429 | case lltok::kw_indir: |
9430 | ByArg.TheKind = WholeProgramDevirtResolution::ByArg::Indir; |
9431 | break; |
9432 | case lltok::kw_uniformRetVal: |
9433 | ByArg.TheKind = WholeProgramDevirtResolution::ByArg::UniformRetVal; |
9434 | break; |
9435 | case lltok::kw_uniqueRetVal: |
9436 | ByArg.TheKind = WholeProgramDevirtResolution::ByArg::UniqueRetVal; |
9437 | break; |
9438 | case lltok::kw_virtualConstProp: |
9439 | ByArg.TheKind = WholeProgramDevirtResolution::ByArg::VirtualConstProp; |
9440 | break; |
9441 | default: |
9442 | return error(L: Lex.getLoc(), |
9443 | Msg: "unexpected WholeProgramDevirtResolution::ByArg kind" ); |
9444 | } |
9445 | Lex.Lex(); |
9446 | |
9447 | // parse optional fields |
9448 | while (EatIfPresent(T: lltok::comma)) { |
9449 | switch (Lex.getKind()) { |
9450 | case lltok::kw_info: |
9451 | Lex.Lex(); |
9452 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9453 | parseUInt64(Val&: ByArg.Info)) |
9454 | return true; |
9455 | break; |
9456 | case lltok::kw_byte: |
9457 | Lex.Lex(); |
9458 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9459 | parseUInt32(Val&: ByArg.Byte)) |
9460 | return true; |
9461 | break; |
9462 | case lltok::kw_bit: |
9463 | Lex.Lex(); |
9464 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9465 | parseUInt32(Val&: ByArg.Bit)) |
9466 | return true; |
9467 | break; |
9468 | default: |
9469 | return error(L: Lex.getLoc(), |
9470 | Msg: "expected optional whole program devirt field" ); |
9471 | } |
9472 | } |
9473 | |
9474 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9475 | return true; |
9476 | |
9477 | ResByArg[Args] = ByArg; |
9478 | } while (EatIfPresent(T: lltok::comma)); |
9479 | |
9480 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9481 | return true; |
9482 | |
9483 | return false; |
9484 | } |
9485 | |
9486 | /// OptionalResByArg |
9487 | /// ::= 'args' ':' '(' UInt64[, UInt64]* ')' |
9488 | bool LLParser::parseArgs(std::vector<uint64_t> &Args) { |
9489 | if (parseToken(T: lltok::kw_args, ErrMsg: "expected 'args' here" ) || |
9490 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9491 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9492 | return true; |
9493 | |
9494 | do { |
9495 | uint64_t Val; |
9496 | if (parseUInt64(Val)) |
9497 | return true; |
9498 | Args.push_back(x: Val); |
9499 | } while (EatIfPresent(T: lltok::comma)); |
9500 | |
9501 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9502 | return true; |
9503 | |
9504 | return false; |
9505 | } |
9506 | |
9507 | static const auto FwdVIRef = (GlobalValueSummaryMapTy::value_type *)-8; |
9508 | |
9509 | static void resolveFwdRef(ValueInfo *Fwd, ValueInfo &Resolved) { |
9510 | bool ReadOnly = Fwd->isReadOnly(); |
9511 | bool WriteOnly = Fwd->isWriteOnly(); |
9512 | assert(!(ReadOnly && WriteOnly)); |
9513 | *Fwd = Resolved; |
9514 | if (ReadOnly) |
9515 | Fwd->setReadOnly(); |
9516 | if (WriteOnly) |
9517 | Fwd->setWriteOnly(); |
9518 | } |
9519 | |
9520 | /// Stores the given Name/GUID and associated summary into the Index. |
9521 | /// Also updates any forward references to the associated entry ID. |
9522 | bool LLParser::addGlobalValueToIndex( |
9523 | std::string Name, GlobalValue::GUID GUID, GlobalValue::LinkageTypes Linkage, |
9524 | unsigned ID, std::unique_ptr<GlobalValueSummary> Summary, LocTy Loc) { |
9525 | // First create the ValueInfo utilizing the Name or GUID. |
9526 | ValueInfo VI; |
9527 | if (GUID != 0) { |
9528 | assert(Name.empty()); |
9529 | VI = Index->getOrInsertValueInfo(GUID); |
9530 | } else { |
9531 | assert(!Name.empty()); |
9532 | if (M) { |
9533 | auto *GV = M->getNamedValue(Name); |
9534 | if (!GV) |
9535 | return error(L: Loc, Msg: "Reference to undefined global \"" + Name + "\"" ); |
9536 | |
9537 | VI = Index->getOrInsertValueInfo(GV); |
9538 | } else { |
9539 | assert( |
9540 | (!GlobalValue::isLocalLinkage(Linkage) || !SourceFileName.empty()) && |
9541 | "Need a source_filename to compute GUID for local" ); |
9542 | GUID = GlobalValue::getGUIDAssumingExternalLinkage( |
9543 | GlobalName: GlobalValue::getGlobalIdentifier(Name, Linkage, FileName: SourceFileName)); |
9544 | VI = Index->getOrInsertValueInfo(GUID, Name: Index->saveString(String: Name)); |
9545 | } |
9546 | } |
9547 | |
9548 | // Resolve forward references from calls/refs |
9549 | auto FwdRefVIs = ForwardRefValueInfos.find(x: ID); |
9550 | if (FwdRefVIs != ForwardRefValueInfos.end()) { |
9551 | for (auto VIRef : FwdRefVIs->second) { |
9552 | assert(VIRef.first->getRef() == FwdVIRef && |
9553 | "Forward referenced ValueInfo expected to be empty" ); |
9554 | resolveFwdRef(Fwd: VIRef.first, Resolved&: VI); |
9555 | } |
9556 | ForwardRefValueInfos.erase(position: FwdRefVIs); |
9557 | } |
9558 | |
9559 | // Resolve forward references from aliases |
9560 | auto FwdRefAliasees = ForwardRefAliasees.find(x: ID); |
9561 | if (FwdRefAliasees != ForwardRefAliasees.end()) { |
9562 | for (auto AliaseeRef : FwdRefAliasees->second) { |
9563 | assert(!AliaseeRef.first->hasAliasee() && |
9564 | "Forward referencing alias already has aliasee" ); |
9565 | assert(Summary && "Aliasee must be a definition" ); |
9566 | AliaseeRef.first->setAliasee(AliaseeVI&: VI, Aliasee: Summary.get()); |
9567 | } |
9568 | ForwardRefAliasees.erase(position: FwdRefAliasees); |
9569 | } |
9570 | |
9571 | // Add the summary if one was provided. |
9572 | if (Summary) |
9573 | Index->addGlobalValueSummary(VI, Summary: std::move(Summary)); |
9574 | |
9575 | // Save the associated ValueInfo for use in later references by ID. |
9576 | if (ID == NumberedValueInfos.size()) |
9577 | NumberedValueInfos.push_back(x: VI); |
9578 | else { |
9579 | // Handle non-continuous numbers (to make test simplification easier). |
9580 | if (ID > NumberedValueInfos.size()) |
9581 | NumberedValueInfos.resize(new_size: ID + 1); |
9582 | NumberedValueInfos[ID] = VI; |
9583 | } |
9584 | |
9585 | return false; |
9586 | } |
9587 | |
9588 | /// parseSummaryIndexFlags |
9589 | /// ::= 'flags' ':' UInt64 |
9590 | bool LLParser::parseSummaryIndexFlags() { |
9591 | assert(Lex.getKind() == lltok::kw_flags); |
9592 | Lex.Lex(); |
9593 | |
9594 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
9595 | return true; |
9596 | uint64_t Flags; |
9597 | if (parseUInt64(Val&: Flags)) |
9598 | return true; |
9599 | if (Index) |
9600 | Index->setFlags(Flags); |
9601 | return false; |
9602 | } |
9603 | |
9604 | /// parseBlockCount |
9605 | /// ::= 'blockcount' ':' UInt64 |
9606 | bool LLParser::parseBlockCount() { |
9607 | assert(Lex.getKind() == lltok::kw_blockcount); |
9608 | Lex.Lex(); |
9609 | |
9610 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
9611 | return true; |
9612 | uint64_t BlockCount; |
9613 | if (parseUInt64(Val&: BlockCount)) |
9614 | return true; |
9615 | if (Index) |
9616 | Index->setBlockCount(BlockCount); |
9617 | return false; |
9618 | } |
9619 | |
9620 | /// parseGVEntry |
9621 | /// ::= 'gv' ':' '(' ('name' ':' STRINGCONSTANT | 'guid' ':' UInt64) |
9622 | /// [',' 'summaries' ':' Summary[',' Summary]* ]? ')' |
9623 | /// Summary ::= '(' (FunctionSummary | VariableSummary | AliasSummary) ')' |
9624 | bool LLParser::parseGVEntry(unsigned ID) { |
9625 | assert(Lex.getKind() == lltok::kw_gv); |
9626 | Lex.Lex(); |
9627 | |
9628 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9629 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9630 | return true; |
9631 | |
9632 | LocTy Loc = Lex.getLoc(); |
9633 | std::string Name; |
9634 | GlobalValue::GUID GUID = 0; |
9635 | switch (Lex.getKind()) { |
9636 | case lltok::kw_name: |
9637 | Lex.Lex(); |
9638 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9639 | parseStringConstant(Result&: Name)) |
9640 | return true; |
9641 | // Can't create GUID/ValueInfo until we have the linkage. |
9642 | break; |
9643 | case lltok::kw_guid: |
9644 | Lex.Lex(); |
9645 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || parseUInt64(Val&: GUID)) |
9646 | return true; |
9647 | break; |
9648 | default: |
9649 | return error(L: Lex.getLoc(), Msg: "expected name or guid tag" ); |
9650 | } |
9651 | |
9652 | if (!EatIfPresent(T: lltok::comma)) { |
9653 | // No summaries. Wrap up. |
9654 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9655 | return true; |
9656 | // This was created for a call to an external or indirect target. |
9657 | // A GUID with no summary came from a VALUE_GUID record, dummy GUID |
9658 | // created for indirect calls with VP. A Name with no GUID came from |
9659 | // an external definition. We pass ExternalLinkage since that is only |
9660 | // used when the GUID must be computed from Name, and in that case |
9661 | // the symbol must have external linkage. |
9662 | return addGlobalValueToIndex(Name, GUID, Linkage: GlobalValue::ExternalLinkage, ID, |
9663 | Summary: nullptr, Loc); |
9664 | } |
9665 | |
9666 | // Have a list of summaries |
9667 | if (parseToken(T: lltok::kw_summaries, ErrMsg: "expected 'summaries' here" ) || |
9668 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9669 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
9670 | return true; |
9671 | do { |
9672 | switch (Lex.getKind()) { |
9673 | case lltok::kw_function: |
9674 | if (parseFunctionSummary(Name, GUID, ID)) |
9675 | return true; |
9676 | break; |
9677 | case lltok::kw_variable: |
9678 | if (parseVariableSummary(Name, GUID, ID)) |
9679 | return true; |
9680 | break; |
9681 | case lltok::kw_alias: |
9682 | if (parseAliasSummary(Name, GUID, ID)) |
9683 | return true; |
9684 | break; |
9685 | default: |
9686 | return error(L: Lex.getLoc(), Msg: "expected summary type" ); |
9687 | } |
9688 | } while (EatIfPresent(T: lltok::comma)); |
9689 | |
9690 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" ) || |
9691 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9692 | return true; |
9693 | |
9694 | return false; |
9695 | } |
9696 | |
9697 | /// FunctionSummary |
9698 | /// ::= 'function' ':' '(' 'module' ':' ModuleReference ',' GVFlags |
9699 | /// ',' 'insts' ':' UInt32 [',' OptionalFFlags]? [',' OptionalCalls]? |
9700 | /// [',' OptionalTypeIdInfo]? [',' OptionalParamAccesses]? |
9701 | /// [',' OptionalRefs]? ')' |
9702 | bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID, |
9703 | unsigned ID) { |
9704 | LocTy Loc = Lex.getLoc(); |
9705 | assert(Lex.getKind() == lltok::kw_function); |
9706 | Lex.Lex(); |
9707 | |
9708 | StringRef ModulePath; |
9709 | GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( |
9710 | GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility, |
9711 | /*NotEligibleToImport=*/false, |
9712 | /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false, |
9713 | GlobalValueSummary::Definition); |
9714 | unsigned InstCount; |
9715 | SmallVector<FunctionSummary::EdgeTy, 0> Calls; |
9716 | FunctionSummary::TypeIdInfo TypeIdInfo; |
9717 | std::vector<FunctionSummary::ParamAccess> ParamAccesses; |
9718 | SmallVector<ValueInfo, 0> Refs; |
9719 | std::vector<CallsiteInfo> Callsites; |
9720 | std::vector<AllocInfo> Allocs; |
9721 | // Default is all-zeros (conservative values). |
9722 | FunctionSummary::FFlags FFlags = {}; |
9723 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9724 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9725 | parseModuleReference(ModulePath) || |
9726 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || parseGVFlags(GVFlags) || |
9727 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9728 | parseToken(T: lltok::kw_insts, ErrMsg: "expected 'insts' here" ) || |
9729 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || parseUInt32(Val&: InstCount)) |
9730 | return true; |
9731 | |
9732 | // parse optional fields |
9733 | while (EatIfPresent(T: lltok::comma)) { |
9734 | switch (Lex.getKind()) { |
9735 | case lltok::kw_funcFlags: |
9736 | if (parseOptionalFFlags(FFlags)) |
9737 | return true; |
9738 | break; |
9739 | case lltok::kw_calls: |
9740 | if (parseOptionalCalls(Calls)) |
9741 | return true; |
9742 | break; |
9743 | case lltok::kw_typeIdInfo: |
9744 | if (parseOptionalTypeIdInfo(TypeIdInfo)) |
9745 | return true; |
9746 | break; |
9747 | case lltok::kw_refs: |
9748 | if (parseOptionalRefs(Refs)) |
9749 | return true; |
9750 | break; |
9751 | case lltok::kw_params: |
9752 | if (parseOptionalParamAccesses(Params&: ParamAccesses)) |
9753 | return true; |
9754 | break; |
9755 | case lltok::kw_allocs: |
9756 | if (parseOptionalAllocs(Allocs)) |
9757 | return true; |
9758 | break; |
9759 | case lltok::kw_callsites: |
9760 | if (parseOptionalCallsites(Callsites)) |
9761 | return true; |
9762 | break; |
9763 | default: |
9764 | return error(L: Lex.getLoc(), Msg: "expected optional function summary field" ); |
9765 | } |
9766 | } |
9767 | |
9768 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9769 | return true; |
9770 | |
9771 | auto FS = std::make_unique<FunctionSummary>( |
9772 | args&: GVFlags, args&: InstCount, args&: FFlags, args: std::move(Refs), args: std::move(Calls), |
9773 | args: std::move(TypeIdInfo.TypeTests), |
9774 | args: std::move(TypeIdInfo.TypeTestAssumeVCalls), |
9775 | args: std::move(TypeIdInfo.TypeCheckedLoadVCalls), |
9776 | args: std::move(TypeIdInfo.TypeTestAssumeConstVCalls), |
9777 | args: std::move(TypeIdInfo.TypeCheckedLoadConstVCalls), |
9778 | args: std::move(ParamAccesses), args: std::move(Callsites), args: std::move(Allocs)); |
9779 | |
9780 | FS->setModulePath(ModulePath); |
9781 | |
9782 | return addGlobalValueToIndex(Name, GUID, |
9783 | Linkage: (GlobalValue::LinkageTypes)GVFlags.Linkage, ID, |
9784 | Summary: std::move(FS), Loc); |
9785 | } |
9786 | |
9787 | /// VariableSummary |
9788 | /// ::= 'variable' ':' '(' 'module' ':' ModuleReference ',' GVFlags |
9789 | /// [',' OptionalRefs]? ')' |
9790 | bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID, |
9791 | unsigned ID) { |
9792 | LocTy Loc = Lex.getLoc(); |
9793 | assert(Lex.getKind() == lltok::kw_variable); |
9794 | Lex.Lex(); |
9795 | |
9796 | StringRef ModulePath; |
9797 | GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( |
9798 | GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility, |
9799 | /*NotEligibleToImport=*/false, |
9800 | /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false, |
9801 | GlobalValueSummary::Definition); |
9802 | GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false, |
9803 | /* WriteOnly */ false, |
9804 | /* Constant */ false, |
9805 | GlobalObject::VCallVisibilityPublic); |
9806 | SmallVector<ValueInfo, 0> Refs; |
9807 | VTableFuncList VTableFuncs; |
9808 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9809 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9810 | parseModuleReference(ModulePath) || |
9811 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || parseGVFlags(GVFlags) || |
9812 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9813 | parseGVarFlags(GVarFlags)) |
9814 | return true; |
9815 | |
9816 | // parse optional fields |
9817 | while (EatIfPresent(T: lltok::comma)) { |
9818 | switch (Lex.getKind()) { |
9819 | case lltok::kw_vTableFuncs: |
9820 | if (parseOptionalVTableFuncs(VTableFuncs)) |
9821 | return true; |
9822 | break; |
9823 | case lltok::kw_refs: |
9824 | if (parseOptionalRefs(Refs)) |
9825 | return true; |
9826 | break; |
9827 | default: |
9828 | return error(L: Lex.getLoc(), Msg: "expected optional variable summary field" ); |
9829 | } |
9830 | } |
9831 | |
9832 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9833 | return true; |
9834 | |
9835 | auto GS = |
9836 | std::make_unique<GlobalVarSummary>(args&: GVFlags, args&: GVarFlags, args: std::move(Refs)); |
9837 | |
9838 | GS->setModulePath(ModulePath); |
9839 | GS->setVTableFuncs(std::move(VTableFuncs)); |
9840 | |
9841 | return addGlobalValueToIndex(Name, GUID, |
9842 | Linkage: (GlobalValue::LinkageTypes)GVFlags.Linkage, ID, |
9843 | Summary: std::move(GS), Loc); |
9844 | } |
9845 | |
9846 | /// AliasSummary |
9847 | /// ::= 'alias' ':' '(' 'module' ':' ModuleReference ',' GVFlags ',' |
9848 | /// 'aliasee' ':' GVReference ')' |
9849 | bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID, |
9850 | unsigned ID) { |
9851 | assert(Lex.getKind() == lltok::kw_alias); |
9852 | LocTy Loc = Lex.getLoc(); |
9853 | Lex.Lex(); |
9854 | |
9855 | StringRef ModulePath; |
9856 | GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags( |
9857 | GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility, |
9858 | /*NotEligibleToImport=*/false, |
9859 | /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false, |
9860 | GlobalValueSummary::Definition); |
9861 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
9862 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
9863 | parseModuleReference(ModulePath) || |
9864 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || parseGVFlags(GVFlags) || |
9865 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
9866 | parseToken(T: lltok::kw_aliasee, ErrMsg: "expected 'aliasee' here" ) || |
9867 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
9868 | return true; |
9869 | |
9870 | ValueInfo AliaseeVI; |
9871 | unsigned GVId; |
9872 | if (parseGVReference(VI&: AliaseeVI, GVId)) |
9873 | return true; |
9874 | |
9875 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
9876 | return true; |
9877 | |
9878 | auto AS = std::make_unique<AliasSummary>(args&: GVFlags); |
9879 | |
9880 | AS->setModulePath(ModulePath); |
9881 | |
9882 | // Record forward reference if the aliasee is not parsed yet. |
9883 | if (AliaseeVI.getRef() == FwdVIRef) { |
9884 | ForwardRefAliasees[GVId].emplace_back(args: AS.get(), args&: Loc); |
9885 | } else { |
9886 | auto Summary = Index->findSummaryInModule(VI: AliaseeVI, ModuleId: ModulePath); |
9887 | assert(Summary && "Aliasee must be a definition" ); |
9888 | AS->setAliasee(AliaseeVI, Aliasee: Summary); |
9889 | } |
9890 | |
9891 | return addGlobalValueToIndex(Name, GUID, |
9892 | Linkage: (GlobalValue::LinkageTypes)GVFlags.Linkage, ID, |
9893 | Summary: std::move(AS), Loc); |
9894 | } |
9895 | |
9896 | /// Flag |
9897 | /// ::= [0|1] |
9898 | bool LLParser::parseFlag(unsigned &Val) { |
9899 | if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) |
9900 | return tokError(Msg: "expected integer" ); |
9901 | Val = (unsigned)Lex.getAPSIntVal().getBoolValue(); |
9902 | Lex.Lex(); |
9903 | return false; |
9904 | } |
9905 | |
9906 | /// OptionalFFlags |
9907 | /// := 'funcFlags' ':' '(' ['readNone' ':' Flag]? |
9908 | /// [',' 'readOnly' ':' Flag]? [',' 'noRecurse' ':' Flag]? |
9909 | /// [',' 'returnDoesNotAlias' ':' Flag]? ')' |
9910 | /// [',' 'noInline' ':' Flag]? ')' |
9911 | /// [',' 'alwaysInline' ':' Flag]? ')' |
9912 | /// [',' 'noUnwind' ':' Flag]? ')' |
9913 | /// [',' 'mayThrow' ':' Flag]? ')' |
9914 | /// [',' 'hasUnknownCall' ':' Flag]? ')' |
9915 | /// [',' 'mustBeUnreachable' ':' Flag]? ')' |
9916 | |
9917 | bool LLParser::parseOptionalFFlags(FunctionSummary::FFlags &FFlags) { |
9918 | assert(Lex.getKind() == lltok::kw_funcFlags); |
9919 | Lex.Lex(); |
9920 | |
9921 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in funcFlags" ) || |
9922 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in funcFlags" )) |
9923 | return true; |
9924 | |
9925 | do { |
9926 | unsigned Val = 0; |
9927 | switch (Lex.getKind()) { |
9928 | case lltok::kw_readNone: |
9929 | Lex.Lex(); |
9930 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9931 | return true; |
9932 | FFlags.ReadNone = Val; |
9933 | break; |
9934 | case lltok::kw_readOnly: |
9935 | Lex.Lex(); |
9936 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9937 | return true; |
9938 | FFlags.ReadOnly = Val; |
9939 | break; |
9940 | case lltok::kw_noRecurse: |
9941 | Lex.Lex(); |
9942 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9943 | return true; |
9944 | FFlags.NoRecurse = Val; |
9945 | break; |
9946 | case lltok::kw_returnDoesNotAlias: |
9947 | Lex.Lex(); |
9948 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9949 | return true; |
9950 | FFlags.ReturnDoesNotAlias = Val; |
9951 | break; |
9952 | case lltok::kw_noInline: |
9953 | Lex.Lex(); |
9954 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9955 | return true; |
9956 | FFlags.NoInline = Val; |
9957 | break; |
9958 | case lltok::kw_alwaysInline: |
9959 | Lex.Lex(); |
9960 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9961 | return true; |
9962 | FFlags.AlwaysInline = Val; |
9963 | break; |
9964 | case lltok::kw_noUnwind: |
9965 | Lex.Lex(); |
9966 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9967 | return true; |
9968 | FFlags.NoUnwind = Val; |
9969 | break; |
9970 | case lltok::kw_mayThrow: |
9971 | Lex.Lex(); |
9972 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9973 | return true; |
9974 | FFlags.MayThrow = Val; |
9975 | break; |
9976 | case lltok::kw_hasUnknownCall: |
9977 | Lex.Lex(); |
9978 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9979 | return true; |
9980 | FFlags.HasUnknownCall = Val; |
9981 | break; |
9982 | case lltok::kw_mustBeUnreachable: |
9983 | Lex.Lex(); |
9984 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val)) |
9985 | return true; |
9986 | FFlags.MustBeUnreachable = Val; |
9987 | break; |
9988 | default: |
9989 | return error(L: Lex.getLoc(), Msg: "expected function flag type" ); |
9990 | } |
9991 | } while (EatIfPresent(T: lltok::comma)); |
9992 | |
9993 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in funcFlags" )) |
9994 | return true; |
9995 | |
9996 | return false; |
9997 | } |
9998 | |
9999 | /// OptionalCalls |
10000 | /// := 'calls' ':' '(' Call [',' Call]* ')' |
10001 | /// Call ::= '(' 'callee' ':' GVReference |
10002 | /// [( ',' 'hotness' ':' Hotness | ',' 'relbf' ':' UInt32 )]? |
10003 | /// [ ',' 'tail' ]? ')' |
10004 | bool LLParser::parseOptionalCalls( |
10005 | SmallVectorImpl<FunctionSummary::EdgeTy> &Calls) { |
10006 | assert(Lex.getKind() == lltok::kw_calls); |
10007 | Lex.Lex(); |
10008 | |
10009 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in calls" ) || |
10010 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in calls" )) |
10011 | return true; |
10012 | |
10013 | IdToIndexMapType IdToIndexMap; |
10014 | // parse each call edge |
10015 | do { |
10016 | ValueInfo VI; |
10017 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in call" ) || |
10018 | parseToken(T: lltok::kw_callee, ErrMsg: "expected 'callee' in call" ) || |
10019 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10020 | return true; |
10021 | |
10022 | LocTy Loc = Lex.getLoc(); |
10023 | unsigned GVId; |
10024 | if (parseGVReference(VI, GVId)) |
10025 | return true; |
10026 | |
10027 | CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; |
10028 | unsigned RelBF = 0; |
10029 | unsigned HasTailCall = false; |
10030 | |
10031 | // parse optional fields |
10032 | while (EatIfPresent(T: lltok::comma)) { |
10033 | switch (Lex.getKind()) { |
10034 | case lltok::kw_hotness: |
10035 | Lex.Lex(); |
10036 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseHotness(Hotness)) |
10037 | return true; |
10038 | break; |
10039 | case lltok::kw_relbf: |
10040 | Lex.Lex(); |
10041 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseUInt32(Val&: RelBF)) |
10042 | return true; |
10043 | break; |
10044 | case lltok::kw_tail: |
10045 | Lex.Lex(); |
10046 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val&: HasTailCall)) |
10047 | return true; |
10048 | break; |
10049 | default: |
10050 | return error(L: Lex.getLoc(), Msg: "expected hotness, relbf, or tail" ); |
10051 | } |
10052 | } |
10053 | if (Hotness != CalleeInfo::HotnessType::Unknown && RelBF > 0) |
10054 | return tokError(Msg: "Expected only one of hotness or relbf" ); |
10055 | // Keep track of the Call array index needing a forward reference. |
10056 | // We will save the location of the ValueInfo needing an update, but |
10057 | // can only do so once the std::vector is finalized. |
10058 | if (VI.getRef() == FwdVIRef) |
10059 | IdToIndexMap[GVId].push_back(x: std::make_pair(x: Calls.size(), y&: Loc)); |
10060 | Calls.push_back( |
10061 | Elt: FunctionSummary::EdgeTy{VI, CalleeInfo(Hotness, HasTailCall, RelBF)}); |
10062 | |
10063 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in call" )) |
10064 | return true; |
10065 | } while (EatIfPresent(T: lltok::comma)); |
10066 | |
10067 | // Now that the Calls vector is finalized, it is safe to save the locations |
10068 | // of any forward GV references that need updating later. |
10069 | for (auto I : IdToIndexMap) { |
10070 | auto &Infos = ForwardRefValueInfos[I.first]; |
10071 | for (auto P : I.second) { |
10072 | assert(Calls[P.first].first.getRef() == FwdVIRef && |
10073 | "Forward referenced ValueInfo expected to be empty" ); |
10074 | Infos.emplace_back(args: &Calls[P.first].first, args&: P.second); |
10075 | } |
10076 | } |
10077 | |
10078 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in calls" )) |
10079 | return true; |
10080 | |
10081 | return false; |
10082 | } |
10083 | |
10084 | /// Hotness |
10085 | /// := ('unknown'|'cold'|'none'|'hot'|'critical') |
10086 | bool LLParser::parseHotness(CalleeInfo::HotnessType &Hotness) { |
10087 | switch (Lex.getKind()) { |
10088 | case lltok::kw_unknown: |
10089 | Hotness = CalleeInfo::HotnessType::Unknown; |
10090 | break; |
10091 | case lltok::kw_cold: |
10092 | Hotness = CalleeInfo::HotnessType::Cold; |
10093 | break; |
10094 | case lltok::kw_none: |
10095 | Hotness = CalleeInfo::HotnessType::None; |
10096 | break; |
10097 | case lltok::kw_hot: |
10098 | Hotness = CalleeInfo::HotnessType::Hot; |
10099 | break; |
10100 | case lltok::kw_critical: |
10101 | Hotness = CalleeInfo::HotnessType::Critical; |
10102 | break; |
10103 | default: |
10104 | return error(L: Lex.getLoc(), Msg: "invalid call edge hotness" ); |
10105 | } |
10106 | Lex.Lex(); |
10107 | return false; |
10108 | } |
10109 | |
10110 | /// OptionalVTableFuncs |
10111 | /// := 'vTableFuncs' ':' '(' VTableFunc [',' VTableFunc]* ')' |
10112 | /// VTableFunc ::= '(' 'virtFunc' ':' GVReference ',' 'offset' ':' UInt64 ')' |
10113 | bool LLParser::parseOptionalVTableFuncs(VTableFuncList &VTableFuncs) { |
10114 | assert(Lex.getKind() == lltok::kw_vTableFuncs); |
10115 | Lex.Lex(); |
10116 | |
10117 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in vTableFuncs" ) || |
10118 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in vTableFuncs" )) |
10119 | return true; |
10120 | |
10121 | IdToIndexMapType IdToIndexMap; |
10122 | // parse each virtual function pair |
10123 | do { |
10124 | ValueInfo VI; |
10125 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in vTableFunc" ) || |
10126 | parseToken(T: lltok::kw_virtFunc, ErrMsg: "expected 'callee' in vTableFunc" ) || |
10127 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10128 | return true; |
10129 | |
10130 | LocTy Loc = Lex.getLoc(); |
10131 | unsigned GVId; |
10132 | if (parseGVReference(VI, GVId)) |
10133 | return true; |
10134 | |
10135 | uint64_t Offset; |
10136 | if (parseToken(T: lltok::comma, ErrMsg: "expected comma" ) || |
10137 | parseToken(T: lltok::kw_offset, ErrMsg: "expected offset" ) || |
10138 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseUInt64(Val&: Offset)) |
10139 | return true; |
10140 | |
10141 | // Keep track of the VTableFuncs array index needing a forward reference. |
10142 | // We will save the location of the ValueInfo needing an update, but |
10143 | // can only do so once the std::vector is finalized. |
10144 | if (VI == EmptyVI) |
10145 | IdToIndexMap[GVId].push_back(x: std::make_pair(x: VTableFuncs.size(), y&: Loc)); |
10146 | VTableFuncs.push_back(x: {VI, Offset}); |
10147 | |
10148 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in vTableFunc" )) |
10149 | return true; |
10150 | } while (EatIfPresent(T: lltok::comma)); |
10151 | |
10152 | // Now that the VTableFuncs vector is finalized, it is safe to save the |
10153 | // locations of any forward GV references that need updating later. |
10154 | for (auto I : IdToIndexMap) { |
10155 | auto &Infos = ForwardRefValueInfos[I.first]; |
10156 | for (auto P : I.second) { |
10157 | assert(VTableFuncs[P.first].FuncVI == EmptyVI && |
10158 | "Forward referenced ValueInfo expected to be empty" ); |
10159 | Infos.emplace_back(args: &VTableFuncs[P.first].FuncVI, args&: P.second); |
10160 | } |
10161 | } |
10162 | |
10163 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in vTableFuncs" )) |
10164 | return true; |
10165 | |
10166 | return false; |
10167 | } |
10168 | |
10169 | /// ParamNo := 'param' ':' UInt64 |
10170 | bool LLParser::parseParamNo(uint64_t &ParamNo) { |
10171 | if (parseToken(T: lltok::kw_param, ErrMsg: "expected 'param' here" ) || |
10172 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || parseUInt64(Val&: ParamNo)) |
10173 | return true; |
10174 | return false; |
10175 | } |
10176 | |
10177 | /// ParamAccessOffset := 'offset' ':' '[' APSINTVAL ',' APSINTVAL ']' |
10178 | bool LLParser::parseParamAccessOffset(ConstantRange &Range) { |
10179 | APSInt Lower; |
10180 | APSInt Upper; |
10181 | auto ParseAPSInt = [&](APSInt &Val) { |
10182 | if (Lex.getKind() != lltok::APSInt) |
10183 | return tokError(Msg: "expected integer" ); |
10184 | Val = Lex.getAPSIntVal(); |
10185 | Val = Val.extOrTrunc(width: FunctionSummary::ParamAccess::RangeWidth); |
10186 | Val.setIsSigned(true); |
10187 | Lex.Lex(); |
10188 | return false; |
10189 | }; |
10190 | if (parseToken(T: lltok::kw_offset, ErrMsg: "expected 'offset' here" ) || |
10191 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10192 | parseToken(T: lltok::lsquare, ErrMsg: "expected '[' here" ) || ParseAPSInt(Lower) || |
10193 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || ParseAPSInt(Upper) || |
10194 | parseToken(T: lltok::rsquare, ErrMsg: "expected ']' here" )) |
10195 | return true; |
10196 | |
10197 | ++Upper; |
10198 | Range = |
10199 | (Lower == Upper && !Lower.isMaxValue()) |
10200 | ? ConstantRange::getEmpty(BitWidth: FunctionSummary::ParamAccess::RangeWidth) |
10201 | : ConstantRange(Lower, Upper); |
10202 | |
10203 | return false; |
10204 | } |
10205 | |
10206 | /// ParamAccessCall |
10207 | /// := '(' 'callee' ':' GVReference ',' ParamNo ',' ParamAccessOffset ')' |
10208 | bool LLParser::parseParamAccessCall(FunctionSummary::ParamAccess::Call &Call, |
10209 | IdLocListType &IdLocList) { |
10210 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
10211 | parseToken(T: lltok::kw_callee, ErrMsg: "expected 'callee' here" ) || |
10212 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" )) |
10213 | return true; |
10214 | |
10215 | unsigned GVId; |
10216 | ValueInfo VI; |
10217 | LocTy Loc = Lex.getLoc(); |
10218 | if (parseGVReference(VI, GVId)) |
10219 | return true; |
10220 | |
10221 | Call.Callee = VI; |
10222 | IdLocList.emplace_back(args&: GVId, args&: Loc); |
10223 | |
10224 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
10225 | parseParamNo(ParamNo&: Call.ParamNo) || |
10226 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
10227 | parseParamAccessOffset(Range&: Call.Offsets)) |
10228 | return true; |
10229 | |
10230 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10231 | return true; |
10232 | |
10233 | return false; |
10234 | } |
10235 | |
10236 | /// ParamAccess |
10237 | /// := '(' ParamNo ',' ParamAccessOffset [',' OptionalParamAccessCalls]? ')' |
10238 | /// OptionalParamAccessCalls := '(' Call [',' Call]* ')' |
10239 | bool LLParser::parseParamAccess(FunctionSummary::ParamAccess &Param, |
10240 | IdLocListType &IdLocList) { |
10241 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
10242 | parseParamNo(ParamNo&: Param.ParamNo) || |
10243 | parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
10244 | parseParamAccessOffset(Range&: Param.Use)) |
10245 | return true; |
10246 | |
10247 | if (EatIfPresent(T: lltok::comma)) { |
10248 | if (parseToken(T: lltok::kw_calls, ErrMsg: "expected 'calls' here" ) || |
10249 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10250 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10251 | return true; |
10252 | do { |
10253 | FunctionSummary::ParamAccess::Call Call; |
10254 | if (parseParamAccessCall(Call, IdLocList)) |
10255 | return true; |
10256 | Param.Calls.push_back(x: Call); |
10257 | } while (EatIfPresent(T: lltok::comma)); |
10258 | |
10259 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10260 | return true; |
10261 | } |
10262 | |
10263 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10264 | return true; |
10265 | |
10266 | return false; |
10267 | } |
10268 | |
10269 | /// OptionalParamAccesses |
10270 | /// := 'params' ':' '(' ParamAccess [',' ParamAccess]* ')' |
10271 | bool LLParser::parseOptionalParamAccesses( |
10272 | std::vector<FunctionSummary::ParamAccess> &Params) { |
10273 | assert(Lex.getKind() == lltok::kw_params); |
10274 | Lex.Lex(); |
10275 | |
10276 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10277 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10278 | return true; |
10279 | |
10280 | IdLocListType VContexts; |
10281 | size_t CallsNum = 0; |
10282 | do { |
10283 | FunctionSummary::ParamAccess ParamAccess; |
10284 | if (parseParamAccess(Param&: ParamAccess, IdLocList&: VContexts)) |
10285 | return true; |
10286 | CallsNum += ParamAccess.Calls.size(); |
10287 | assert(VContexts.size() == CallsNum); |
10288 | (void)CallsNum; |
10289 | Params.emplace_back(args: std::move(ParamAccess)); |
10290 | } while (EatIfPresent(T: lltok::comma)); |
10291 | |
10292 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10293 | return true; |
10294 | |
10295 | // Now that the Params is finalized, it is safe to save the locations |
10296 | // of any forward GV references that need updating later. |
10297 | IdLocListType::const_iterator ItContext = VContexts.begin(); |
10298 | for (auto &PA : Params) { |
10299 | for (auto &C : PA.Calls) { |
10300 | if (C.Callee.getRef() == FwdVIRef) |
10301 | ForwardRefValueInfos[ItContext->first].emplace_back(args: &C.Callee, |
10302 | args: ItContext->second); |
10303 | ++ItContext; |
10304 | } |
10305 | } |
10306 | assert(ItContext == VContexts.end()); |
10307 | |
10308 | return false; |
10309 | } |
10310 | |
10311 | /// OptionalRefs |
10312 | /// := 'refs' ':' '(' GVReference [',' GVReference]* ')' |
10313 | bool LLParser::parseOptionalRefs(SmallVectorImpl<ValueInfo> &Refs) { |
10314 | assert(Lex.getKind() == lltok::kw_refs); |
10315 | Lex.Lex(); |
10316 | |
10317 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in refs" ) || |
10318 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in refs" )) |
10319 | return true; |
10320 | |
10321 | struct ValueContext { |
10322 | ValueInfo VI; |
10323 | unsigned GVId; |
10324 | LocTy Loc; |
10325 | }; |
10326 | std::vector<ValueContext> VContexts; |
10327 | // parse each ref edge |
10328 | do { |
10329 | ValueContext VC; |
10330 | VC.Loc = Lex.getLoc(); |
10331 | if (parseGVReference(VI&: VC.VI, GVId&: VC.GVId)) |
10332 | return true; |
10333 | VContexts.push_back(x: VC); |
10334 | } while (EatIfPresent(T: lltok::comma)); |
10335 | |
10336 | // Sort value contexts so that ones with writeonly |
10337 | // and readonly ValueInfo are at the end of VContexts vector. |
10338 | // See FunctionSummary::specialRefCounts() |
10339 | llvm::sort(C&: VContexts, Comp: [](const ValueContext &VC1, const ValueContext &VC2) { |
10340 | return VC1.VI.getAccessSpecifier() < VC2.VI.getAccessSpecifier(); |
10341 | }); |
10342 | |
10343 | IdToIndexMapType IdToIndexMap; |
10344 | for (auto &VC : VContexts) { |
10345 | // Keep track of the Refs array index needing a forward reference. |
10346 | // We will save the location of the ValueInfo needing an update, but |
10347 | // can only do so once the std::vector is finalized. |
10348 | if (VC.VI.getRef() == FwdVIRef) |
10349 | IdToIndexMap[VC.GVId].push_back(x: std::make_pair(x: Refs.size(), y&: VC.Loc)); |
10350 | Refs.push_back(Elt: VC.VI); |
10351 | } |
10352 | |
10353 | // Now that the Refs vector is finalized, it is safe to save the locations |
10354 | // of any forward GV references that need updating later. |
10355 | for (auto I : IdToIndexMap) { |
10356 | auto &Infos = ForwardRefValueInfos[I.first]; |
10357 | for (auto P : I.second) { |
10358 | assert(Refs[P.first].getRef() == FwdVIRef && |
10359 | "Forward referenced ValueInfo expected to be empty" ); |
10360 | Infos.emplace_back(args: &Refs[P.first], args&: P.second); |
10361 | } |
10362 | } |
10363 | |
10364 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in refs" )) |
10365 | return true; |
10366 | |
10367 | return false; |
10368 | } |
10369 | |
10370 | /// OptionalTypeIdInfo |
10371 | /// := 'typeidinfo' ':' '(' [',' TypeTests]? [',' TypeTestAssumeVCalls]? |
10372 | /// [',' TypeCheckedLoadVCalls]? [',' TypeTestAssumeConstVCalls]? |
10373 | /// [',' TypeCheckedLoadConstVCalls]? ')' |
10374 | bool LLParser::parseOptionalTypeIdInfo( |
10375 | FunctionSummary::TypeIdInfo &TypeIdInfo) { |
10376 | assert(Lex.getKind() == lltok::kw_typeIdInfo); |
10377 | Lex.Lex(); |
10378 | |
10379 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10380 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in typeIdInfo" )) |
10381 | return true; |
10382 | |
10383 | do { |
10384 | switch (Lex.getKind()) { |
10385 | case lltok::kw_typeTests: |
10386 | if (parseTypeTests(TypeTests&: TypeIdInfo.TypeTests)) |
10387 | return true; |
10388 | break; |
10389 | case lltok::kw_typeTestAssumeVCalls: |
10390 | if (parseVFuncIdList(Kind: lltok::kw_typeTestAssumeVCalls, |
10391 | VFuncIdList&: TypeIdInfo.TypeTestAssumeVCalls)) |
10392 | return true; |
10393 | break; |
10394 | case lltok::kw_typeCheckedLoadVCalls: |
10395 | if (parseVFuncIdList(Kind: lltok::kw_typeCheckedLoadVCalls, |
10396 | VFuncIdList&: TypeIdInfo.TypeCheckedLoadVCalls)) |
10397 | return true; |
10398 | break; |
10399 | case lltok::kw_typeTestAssumeConstVCalls: |
10400 | if (parseConstVCallList(Kind: lltok::kw_typeTestAssumeConstVCalls, |
10401 | ConstVCallList&: TypeIdInfo.TypeTestAssumeConstVCalls)) |
10402 | return true; |
10403 | break; |
10404 | case lltok::kw_typeCheckedLoadConstVCalls: |
10405 | if (parseConstVCallList(Kind: lltok::kw_typeCheckedLoadConstVCalls, |
10406 | ConstVCallList&: TypeIdInfo.TypeCheckedLoadConstVCalls)) |
10407 | return true; |
10408 | break; |
10409 | default: |
10410 | return error(L: Lex.getLoc(), Msg: "invalid typeIdInfo list type" ); |
10411 | } |
10412 | } while (EatIfPresent(T: lltok::comma)); |
10413 | |
10414 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in typeIdInfo" )) |
10415 | return true; |
10416 | |
10417 | return false; |
10418 | } |
10419 | |
10420 | /// TypeTests |
10421 | /// ::= 'typeTests' ':' '(' (SummaryID | UInt64) |
10422 | /// [',' (SummaryID | UInt64)]* ')' |
10423 | bool LLParser::parseTypeTests(std::vector<GlobalValue::GUID> &TypeTests) { |
10424 | assert(Lex.getKind() == lltok::kw_typeTests); |
10425 | Lex.Lex(); |
10426 | |
10427 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10428 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in typeIdInfo" )) |
10429 | return true; |
10430 | |
10431 | IdToIndexMapType IdToIndexMap; |
10432 | do { |
10433 | GlobalValue::GUID GUID = 0; |
10434 | if (Lex.getKind() == lltok::SummaryID) { |
10435 | unsigned ID = Lex.getUIntVal(); |
10436 | LocTy Loc = Lex.getLoc(); |
10437 | // Keep track of the TypeTests array index needing a forward reference. |
10438 | // We will save the location of the GUID needing an update, but |
10439 | // can only do so once the std::vector is finalized. |
10440 | IdToIndexMap[ID].push_back(x: std::make_pair(x: TypeTests.size(), y&: Loc)); |
10441 | Lex.Lex(); |
10442 | } else if (parseUInt64(Val&: GUID)) |
10443 | return true; |
10444 | TypeTests.push_back(x: GUID); |
10445 | } while (EatIfPresent(T: lltok::comma)); |
10446 | |
10447 | // Now that the TypeTests vector is finalized, it is safe to save the |
10448 | // locations of any forward GV references that need updating later. |
10449 | for (auto I : IdToIndexMap) { |
10450 | auto &Ids = ForwardRefTypeIds[I.first]; |
10451 | for (auto P : I.second) { |
10452 | assert(TypeTests[P.first] == 0 && |
10453 | "Forward referenced type id GUID expected to be 0" ); |
10454 | Ids.emplace_back(args: &TypeTests[P.first], args&: P.second); |
10455 | } |
10456 | } |
10457 | |
10458 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in typeIdInfo" )) |
10459 | return true; |
10460 | |
10461 | return false; |
10462 | } |
10463 | |
10464 | /// VFuncIdList |
10465 | /// ::= Kind ':' '(' VFuncId [',' VFuncId]* ')' |
10466 | bool LLParser::parseVFuncIdList( |
10467 | lltok::Kind Kind, std::vector<FunctionSummary::VFuncId> &VFuncIdList) { |
10468 | assert(Lex.getKind() == Kind); |
10469 | Lex.Lex(); |
10470 | |
10471 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10472 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10473 | return true; |
10474 | |
10475 | IdToIndexMapType IdToIndexMap; |
10476 | do { |
10477 | FunctionSummary::VFuncId VFuncId; |
10478 | if (parseVFuncId(VFuncId, IdToIndexMap, Index: VFuncIdList.size())) |
10479 | return true; |
10480 | VFuncIdList.push_back(x: VFuncId); |
10481 | } while (EatIfPresent(T: lltok::comma)); |
10482 | |
10483 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10484 | return true; |
10485 | |
10486 | // Now that the VFuncIdList vector is finalized, it is safe to save the |
10487 | // locations of any forward GV references that need updating later. |
10488 | for (auto I : IdToIndexMap) { |
10489 | auto &Ids = ForwardRefTypeIds[I.first]; |
10490 | for (auto P : I.second) { |
10491 | assert(VFuncIdList[P.first].GUID == 0 && |
10492 | "Forward referenced type id GUID expected to be 0" ); |
10493 | Ids.emplace_back(args: &VFuncIdList[P.first].GUID, args&: P.second); |
10494 | } |
10495 | } |
10496 | |
10497 | return false; |
10498 | } |
10499 | |
10500 | /// ConstVCallList |
10501 | /// ::= Kind ':' '(' ConstVCall [',' ConstVCall]* ')' |
10502 | bool LLParser::parseConstVCallList( |
10503 | lltok::Kind Kind, |
10504 | std::vector<FunctionSummary::ConstVCall> &ConstVCallList) { |
10505 | assert(Lex.getKind() == Kind); |
10506 | Lex.Lex(); |
10507 | |
10508 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10509 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10510 | return true; |
10511 | |
10512 | IdToIndexMapType IdToIndexMap; |
10513 | do { |
10514 | FunctionSummary::ConstVCall ConstVCall; |
10515 | if (parseConstVCall(ConstVCall, IdToIndexMap, Index: ConstVCallList.size())) |
10516 | return true; |
10517 | ConstVCallList.push_back(x: ConstVCall); |
10518 | } while (EatIfPresent(T: lltok::comma)); |
10519 | |
10520 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10521 | return true; |
10522 | |
10523 | // Now that the ConstVCallList vector is finalized, it is safe to save the |
10524 | // locations of any forward GV references that need updating later. |
10525 | for (auto I : IdToIndexMap) { |
10526 | auto &Ids = ForwardRefTypeIds[I.first]; |
10527 | for (auto P : I.second) { |
10528 | assert(ConstVCallList[P.first].VFunc.GUID == 0 && |
10529 | "Forward referenced type id GUID expected to be 0" ); |
10530 | Ids.emplace_back(args: &ConstVCallList[P.first].VFunc.GUID, args&: P.second); |
10531 | } |
10532 | } |
10533 | |
10534 | return false; |
10535 | } |
10536 | |
10537 | /// ConstVCall |
10538 | /// ::= '(' VFuncId ',' Args ')' |
10539 | bool LLParser::parseConstVCall(FunctionSummary::ConstVCall &ConstVCall, |
10540 | IdToIndexMapType &IdToIndexMap, unsigned Index) { |
10541 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" ) || |
10542 | parseVFuncId(VFuncId&: ConstVCall.VFunc, IdToIndexMap, Index)) |
10543 | return true; |
10544 | |
10545 | if (EatIfPresent(T: lltok::comma)) |
10546 | if (parseArgs(Args&: ConstVCall.Args)) |
10547 | return true; |
10548 | |
10549 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10550 | return true; |
10551 | |
10552 | return false; |
10553 | } |
10554 | |
10555 | /// VFuncId |
10556 | /// ::= 'vFuncId' ':' '(' (SummaryID | 'guid' ':' UInt64) ',' |
10557 | /// 'offset' ':' UInt64 ')' |
10558 | bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId, |
10559 | IdToIndexMapType &IdToIndexMap, unsigned Index) { |
10560 | assert(Lex.getKind() == lltok::kw_vFuncId); |
10561 | Lex.Lex(); |
10562 | |
10563 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10564 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10565 | return true; |
10566 | |
10567 | if (Lex.getKind() == lltok::SummaryID) { |
10568 | VFuncId.GUID = 0; |
10569 | unsigned ID = Lex.getUIntVal(); |
10570 | LocTy Loc = Lex.getLoc(); |
10571 | // Keep track of the array index needing a forward reference. |
10572 | // We will save the location of the GUID needing an update, but |
10573 | // can only do so once the caller's std::vector is finalized. |
10574 | IdToIndexMap[ID].push_back(x: std::make_pair(x&: Index, y&: Loc)); |
10575 | Lex.Lex(); |
10576 | } else if (parseToken(T: lltok::kw_guid, ErrMsg: "expected 'guid' here" ) || |
10577 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10578 | parseUInt64(Val&: VFuncId.GUID)) |
10579 | return true; |
10580 | |
10581 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' here" ) || |
10582 | parseToken(T: lltok::kw_offset, ErrMsg: "expected 'offset' here" ) || |
10583 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10584 | parseUInt64(Val&: VFuncId.Offset) || |
10585 | parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10586 | return true; |
10587 | |
10588 | return false; |
10589 | } |
10590 | |
10591 | /// GVFlags |
10592 | /// ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ',' |
10593 | /// 'visibility' ':' Flag 'notEligibleToImport' ':' Flag ',' |
10594 | /// 'live' ':' Flag ',' 'dsoLocal' ':' Flag ',' |
10595 | /// 'canAutoHide' ':' Flag ',' ')' |
10596 | bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) { |
10597 | assert(Lex.getKind() == lltok::kw_flags); |
10598 | Lex.Lex(); |
10599 | |
10600 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10601 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10602 | return true; |
10603 | |
10604 | do { |
10605 | unsigned Flag = 0; |
10606 | switch (Lex.getKind()) { |
10607 | case lltok::kw_linkage: |
10608 | Lex.Lex(); |
10609 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10610 | return true; |
10611 | bool HasLinkage; |
10612 | GVFlags.Linkage = parseOptionalLinkageAux(Kind: Lex.getKind(), HasLinkage); |
10613 | assert(HasLinkage && "Linkage not optional in summary entry" ); |
10614 | Lex.Lex(); |
10615 | break; |
10616 | case lltok::kw_visibility: |
10617 | Lex.Lex(); |
10618 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10619 | return true; |
10620 | parseOptionalVisibility(Res&: Flag); |
10621 | GVFlags.Visibility = Flag; |
10622 | break; |
10623 | case lltok::kw_notEligibleToImport: |
10624 | Lex.Lex(); |
10625 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val&: Flag)) |
10626 | return true; |
10627 | GVFlags.NotEligibleToImport = Flag; |
10628 | break; |
10629 | case lltok::kw_live: |
10630 | Lex.Lex(); |
10631 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val&: Flag)) |
10632 | return true; |
10633 | GVFlags.Live = Flag; |
10634 | break; |
10635 | case lltok::kw_dsoLocal: |
10636 | Lex.Lex(); |
10637 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val&: Flag)) |
10638 | return true; |
10639 | GVFlags.DSOLocal = Flag; |
10640 | break; |
10641 | case lltok::kw_canAutoHide: |
10642 | Lex.Lex(); |
10643 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || parseFlag(Val&: Flag)) |
10644 | return true; |
10645 | GVFlags.CanAutoHide = Flag; |
10646 | break; |
10647 | case lltok::kw_importType: |
10648 | Lex.Lex(); |
10649 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10650 | return true; |
10651 | GlobalValueSummary::ImportKind IK; |
10652 | if (parseOptionalImportType(Kind: Lex.getKind(), Res&: IK)) |
10653 | return true; |
10654 | GVFlags.ImportType = static_cast<unsigned>(IK); |
10655 | Lex.Lex(); |
10656 | break; |
10657 | default: |
10658 | return error(L: Lex.getLoc(), Msg: "expected gv flag type" ); |
10659 | } |
10660 | } while (EatIfPresent(T: lltok::comma)); |
10661 | |
10662 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" )) |
10663 | return true; |
10664 | |
10665 | return false; |
10666 | } |
10667 | |
10668 | /// GVarFlags |
10669 | /// ::= 'varFlags' ':' '(' 'readonly' ':' Flag |
10670 | /// ',' 'writeonly' ':' Flag |
10671 | /// ',' 'constant' ':' Flag ')' |
10672 | bool LLParser::parseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { |
10673 | assert(Lex.getKind() == lltok::kw_varFlags); |
10674 | Lex.Lex(); |
10675 | |
10676 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10677 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' here" )) |
10678 | return true; |
10679 | |
10680 | auto ParseRest = [this](unsigned int &Val) { |
10681 | Lex.Lex(); |
10682 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10683 | return true; |
10684 | return parseFlag(Val); |
10685 | }; |
10686 | |
10687 | do { |
10688 | unsigned Flag = 0; |
10689 | switch (Lex.getKind()) { |
10690 | case lltok::kw_readonly: |
10691 | if (ParseRest(Flag)) |
10692 | return true; |
10693 | GVarFlags.MaybeReadOnly = Flag; |
10694 | break; |
10695 | case lltok::kw_writeonly: |
10696 | if (ParseRest(Flag)) |
10697 | return true; |
10698 | GVarFlags.MaybeWriteOnly = Flag; |
10699 | break; |
10700 | case lltok::kw_constant: |
10701 | if (ParseRest(Flag)) |
10702 | return true; |
10703 | GVarFlags.Constant = Flag; |
10704 | break; |
10705 | case lltok::kw_vcall_visibility: |
10706 | if (ParseRest(Flag)) |
10707 | return true; |
10708 | GVarFlags.VCallVisibility = Flag; |
10709 | break; |
10710 | default: |
10711 | return error(L: Lex.getLoc(), Msg: "expected gvar flag type" ); |
10712 | } |
10713 | } while (EatIfPresent(T: lltok::comma)); |
10714 | return parseToken(T: lltok::rparen, ErrMsg: "expected ')' here" ); |
10715 | } |
10716 | |
10717 | /// ModuleReference |
10718 | /// ::= 'module' ':' UInt |
10719 | bool LLParser::parseModuleReference(StringRef &ModulePath) { |
10720 | // parse module id. |
10721 | if (parseToken(T: lltok::kw_module, ErrMsg: "expected 'module' here" ) || |
10722 | parseToken(T: lltok::colon, ErrMsg: "expected ':' here" ) || |
10723 | parseToken(T: lltok::SummaryID, ErrMsg: "expected module ID" )) |
10724 | return true; |
10725 | |
10726 | unsigned ModuleID = Lex.getUIntVal(); |
10727 | auto I = ModuleIdMap.find(x: ModuleID); |
10728 | // We should have already parsed all module IDs |
10729 | assert(I != ModuleIdMap.end()); |
10730 | ModulePath = I->second; |
10731 | return false; |
10732 | } |
10733 | |
10734 | /// GVReference |
10735 | /// ::= SummaryID |
10736 | bool LLParser::parseGVReference(ValueInfo &VI, unsigned &GVId) { |
10737 | bool WriteOnly = false, ReadOnly = EatIfPresent(T: lltok::kw_readonly); |
10738 | if (!ReadOnly) |
10739 | WriteOnly = EatIfPresent(T: lltok::kw_writeonly); |
10740 | if (parseToken(T: lltok::SummaryID, ErrMsg: "expected GV ID" )) |
10741 | return true; |
10742 | |
10743 | GVId = Lex.getUIntVal(); |
10744 | // Check if we already have a VI for this GV |
10745 | if (GVId < NumberedValueInfos.size() && NumberedValueInfos[GVId]) { |
10746 | assert(NumberedValueInfos[GVId].getRef() != FwdVIRef); |
10747 | VI = NumberedValueInfos[GVId]; |
10748 | } else |
10749 | // We will create a forward reference to the stored location. |
10750 | VI = ValueInfo(false, FwdVIRef); |
10751 | |
10752 | if (ReadOnly) |
10753 | VI.setReadOnly(); |
10754 | if (WriteOnly) |
10755 | VI.setWriteOnly(); |
10756 | return false; |
10757 | } |
10758 | |
10759 | /// OptionalAllocs |
10760 | /// := 'allocs' ':' '(' Alloc [',' Alloc]* ')' |
10761 | /// Alloc ::= '(' 'versions' ':' '(' Version [',' Version]* ')' |
10762 | /// ',' MemProfs ')' |
10763 | /// Version ::= UInt32 |
10764 | bool LLParser::parseOptionalAllocs(std::vector<AllocInfo> &Allocs) { |
10765 | assert(Lex.getKind() == lltok::kw_allocs); |
10766 | Lex.Lex(); |
10767 | |
10768 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in allocs" ) || |
10769 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in allocs" )) |
10770 | return true; |
10771 | |
10772 | // parse each alloc |
10773 | do { |
10774 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in alloc" ) || |
10775 | parseToken(T: lltok::kw_versions, ErrMsg: "expected 'versions' in alloc" ) || |
10776 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || |
10777 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in versions" )) |
10778 | return true; |
10779 | |
10780 | SmallVector<uint8_t> Versions; |
10781 | do { |
10782 | uint8_t V = 0; |
10783 | if (parseAllocType(AllocType&: V)) |
10784 | return true; |
10785 | Versions.push_back(Elt: V); |
10786 | } while (EatIfPresent(T: lltok::comma)); |
10787 | |
10788 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in versions" ) || |
10789 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in alloc" )) |
10790 | return true; |
10791 | |
10792 | std::vector<MIBInfo> MIBs; |
10793 | if (parseMemProfs(MIBs)) |
10794 | return true; |
10795 | |
10796 | Allocs.push_back(x: {Versions, MIBs}); |
10797 | |
10798 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in alloc" )) |
10799 | return true; |
10800 | } while (EatIfPresent(T: lltok::comma)); |
10801 | |
10802 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in allocs" )) |
10803 | return true; |
10804 | |
10805 | return false; |
10806 | } |
10807 | |
10808 | /// MemProfs |
10809 | /// := 'memProf' ':' '(' MemProf [',' MemProf]* ')' |
10810 | /// MemProf ::= '(' 'type' ':' AllocType |
10811 | /// ',' 'stackIds' ':' '(' StackId [',' StackId]* ')' ')' |
10812 | /// StackId ::= UInt64 |
10813 | bool LLParser::parseMemProfs(std::vector<MIBInfo> &MIBs) { |
10814 | assert(Lex.getKind() == lltok::kw_memProf); |
10815 | Lex.Lex(); |
10816 | |
10817 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in memprof" ) || |
10818 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in memprof" )) |
10819 | return true; |
10820 | |
10821 | // parse each MIB |
10822 | do { |
10823 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in memprof" ) || |
10824 | parseToken(T: lltok::kw_type, ErrMsg: "expected 'type' in memprof" ) || |
10825 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10826 | return true; |
10827 | |
10828 | uint8_t AllocType; |
10829 | if (parseAllocType(AllocType)) |
10830 | return true; |
10831 | |
10832 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' in memprof" ) || |
10833 | parseToken(T: lltok::kw_stackIds, ErrMsg: "expected 'stackIds' in memprof" ) || |
10834 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || |
10835 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in stackIds" )) |
10836 | return true; |
10837 | |
10838 | SmallVector<unsigned> StackIdIndices; |
10839 | // Combined index alloc records may not have a stack id list. |
10840 | if (Lex.getKind() != lltok::rparen) { |
10841 | do { |
10842 | uint64_t StackId = 0; |
10843 | if (parseUInt64(Val&: StackId)) |
10844 | return true; |
10845 | StackIdIndices.push_back(Elt: Index->addOrGetStackIdIndex(StackId)); |
10846 | } while (EatIfPresent(T: lltok::comma)); |
10847 | } |
10848 | |
10849 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in stackIds" )) |
10850 | return true; |
10851 | |
10852 | MIBs.push_back(x: {(AllocationType)AllocType, StackIdIndices}); |
10853 | |
10854 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in memprof" )) |
10855 | return true; |
10856 | } while (EatIfPresent(T: lltok::comma)); |
10857 | |
10858 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in memprof" )) |
10859 | return true; |
10860 | |
10861 | return false; |
10862 | } |
10863 | |
10864 | /// AllocType |
10865 | /// := ('none'|'notcold'|'cold'|'hot') |
10866 | bool LLParser::parseAllocType(uint8_t &AllocType) { |
10867 | switch (Lex.getKind()) { |
10868 | case lltok::kw_none: |
10869 | AllocType = (uint8_t)AllocationType::None; |
10870 | break; |
10871 | case lltok::kw_notcold: |
10872 | AllocType = (uint8_t)AllocationType::NotCold; |
10873 | break; |
10874 | case lltok::kw_cold: |
10875 | AllocType = (uint8_t)AllocationType::Cold; |
10876 | break; |
10877 | case lltok::kw_hot: |
10878 | AllocType = (uint8_t)AllocationType::Hot; |
10879 | break; |
10880 | default: |
10881 | return error(L: Lex.getLoc(), Msg: "invalid alloc type" ); |
10882 | } |
10883 | Lex.Lex(); |
10884 | return false; |
10885 | } |
10886 | |
10887 | /// OptionalCallsites |
10888 | /// := 'callsites' ':' '(' Callsite [',' Callsite]* ')' |
10889 | /// Callsite ::= '(' 'callee' ':' GVReference |
10890 | /// ',' 'clones' ':' '(' Version [',' Version]* ')' |
10891 | /// ',' 'stackIds' ':' '(' StackId [',' StackId]* ')' ')' |
10892 | /// Version ::= UInt32 |
10893 | /// StackId ::= UInt64 |
10894 | bool LLParser::parseOptionalCallsites(std::vector<CallsiteInfo> &Callsites) { |
10895 | assert(Lex.getKind() == lltok::kw_callsites); |
10896 | Lex.Lex(); |
10897 | |
10898 | if (parseToken(T: lltok::colon, ErrMsg: "expected ':' in callsites" ) || |
10899 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in callsites" )) |
10900 | return true; |
10901 | |
10902 | IdToIndexMapType IdToIndexMap; |
10903 | // parse each callsite |
10904 | do { |
10905 | if (parseToken(T: lltok::lparen, ErrMsg: "expected '(' in callsite" ) || |
10906 | parseToken(T: lltok::kw_callee, ErrMsg: "expected 'callee' in callsite" ) || |
10907 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" )) |
10908 | return true; |
10909 | |
10910 | ValueInfo VI; |
10911 | unsigned GVId = 0; |
10912 | LocTy Loc = Lex.getLoc(); |
10913 | if (!EatIfPresent(T: lltok::kw_null)) { |
10914 | if (parseGVReference(VI, GVId)) |
10915 | return true; |
10916 | } |
10917 | |
10918 | if (parseToken(T: lltok::comma, ErrMsg: "expected ',' in callsite" ) || |
10919 | parseToken(T: lltok::kw_clones, ErrMsg: "expected 'clones' in callsite" ) || |
10920 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || |
10921 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in clones" )) |
10922 | return true; |
10923 | |
10924 | SmallVector<unsigned> Clones; |
10925 | do { |
10926 | unsigned V = 0; |
10927 | if (parseUInt32(Val&: V)) |
10928 | return true; |
10929 | Clones.push_back(Elt: V); |
10930 | } while (EatIfPresent(T: lltok::comma)); |
10931 | |
10932 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in clones" ) || |
10933 | parseToken(T: lltok::comma, ErrMsg: "expected ',' in callsite" ) || |
10934 | parseToken(T: lltok::kw_stackIds, ErrMsg: "expected 'stackIds' in callsite" ) || |
10935 | parseToken(T: lltok::colon, ErrMsg: "expected ':'" ) || |
10936 | parseToken(T: lltok::lparen, ErrMsg: "expected '(' in stackIds" )) |
10937 | return true; |
10938 | |
10939 | SmallVector<unsigned> StackIdIndices; |
10940 | // Synthesized callsite records will not have a stack id list. |
10941 | if (Lex.getKind() != lltok::rparen) { |
10942 | do { |
10943 | uint64_t StackId = 0; |
10944 | if (parseUInt64(Val&: StackId)) |
10945 | return true; |
10946 | StackIdIndices.push_back(Elt: Index->addOrGetStackIdIndex(StackId)); |
10947 | } while (EatIfPresent(T: lltok::comma)); |
10948 | } |
10949 | |
10950 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in stackIds" )) |
10951 | return true; |
10952 | |
10953 | // Keep track of the Callsites array index needing a forward reference. |
10954 | // We will save the location of the ValueInfo needing an update, but |
10955 | // can only do so once the SmallVector is finalized. |
10956 | if (VI.getRef() == FwdVIRef) |
10957 | IdToIndexMap[GVId].push_back(x: std::make_pair(x: Callsites.size(), y&: Loc)); |
10958 | Callsites.push_back(x: {VI, Clones, StackIdIndices}); |
10959 | |
10960 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in callsite" )) |
10961 | return true; |
10962 | } while (EatIfPresent(T: lltok::comma)); |
10963 | |
10964 | // Now that the Callsites vector is finalized, it is safe to save the |
10965 | // locations of any forward GV references that need updating later. |
10966 | for (auto I : IdToIndexMap) { |
10967 | auto &Infos = ForwardRefValueInfos[I.first]; |
10968 | for (auto P : I.second) { |
10969 | assert(Callsites[P.first].Callee.getRef() == FwdVIRef && |
10970 | "Forward referenced ValueInfo expected to be empty" ); |
10971 | Infos.emplace_back(args: &Callsites[P.first].Callee, args&: P.second); |
10972 | } |
10973 | } |
10974 | |
10975 | if (parseToken(T: lltok::rparen, ErrMsg: "expected ')' in callsites" )) |
10976 | return true; |
10977 | |
10978 | return false; |
10979 | } |
10980 | |