1e28b9357SCarlos Alberto Enciso //===-- LVScope.cpp -------------------------------------------------------===//
2e28b9357SCarlos Alberto Enciso //
3e28b9357SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e28b9357SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
5e28b9357SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e28b9357SCarlos Alberto Enciso //
7e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
8e28b9357SCarlos Alberto Enciso //
9e28b9357SCarlos Alberto Enciso // This implements the LVScope class.
10e28b9357SCarlos Alberto Enciso //
11e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
12e28b9357SCarlos Alberto Enciso
13e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
14e98a4c5aSCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
15e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
163c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
173c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVRange.h"
18e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
19e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
20e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
21e28b9357SCarlos Alberto Enciso
22e28b9357SCarlos Alberto Enciso using namespace llvm;
23e28b9357SCarlos Alberto Enciso using namespace llvm::logicalview;
24e28b9357SCarlos Alberto Enciso
25e28b9357SCarlos Alberto Enciso #define DEBUG_TYPE "Scope"
26e28b9357SCarlos Alberto Enciso
27e28b9357SCarlos Alberto Enciso namespace {
28e28b9357SCarlos Alberto Enciso const char *const KindArray = "Array";
29e28b9357SCarlos Alberto Enciso const char *const KindBlock = "Block";
30e28b9357SCarlos Alberto Enciso const char *const KindCallSite = "CallSite";
31e28b9357SCarlos Alberto Enciso const char *const KindClass = "Class";
32e28b9357SCarlos Alberto Enciso const char *const KindCompileUnit = "CompileUnit";
33e28b9357SCarlos Alberto Enciso const char *const KindEnumeration = "Enumeration";
34e28b9357SCarlos Alberto Enciso const char *const KindFile = "File";
35e28b9357SCarlos Alberto Enciso const char *const KindFunction = "Function";
36e28b9357SCarlos Alberto Enciso const char *const KindInlinedFunction = "InlinedFunction";
37e28b9357SCarlos Alberto Enciso const char *const KindNamespace = "Namespace";
38e28b9357SCarlos Alberto Enciso const char *const KindStruct = "Struct";
39e28b9357SCarlos Alberto Enciso const char *const KindTemplateAlias = "TemplateAlias";
40e28b9357SCarlos Alberto Enciso const char *const KindTemplatePack = "TemplatePack";
41e28b9357SCarlos Alberto Enciso const char *const KindUndefined = "Undefined";
42e28b9357SCarlos Alberto Enciso const char *const KindUnion = "Union";
43e28b9357SCarlos Alberto Enciso } // end anonymous namespace
44e28b9357SCarlos Alberto Enciso
45e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
46e28b9357SCarlos Alberto Enciso // DWARF lexical block, such as: namespace, function, compile unit, module, etc.
47e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
48e28b9357SCarlos Alberto Enciso // Return a string representation for the scope kind.
kind() const49e28b9357SCarlos Alberto Enciso const char *LVScope::kind() const {
50e28b9357SCarlos Alberto Enciso const char *Kind = KindUndefined;
51e28b9357SCarlos Alberto Enciso if (getIsArray())
52e28b9357SCarlos Alberto Enciso Kind = KindArray;
53e28b9357SCarlos Alberto Enciso else if (getIsBlock())
54e28b9357SCarlos Alberto Enciso Kind = KindBlock;
55e28b9357SCarlos Alberto Enciso else if (getIsCallSite())
56e28b9357SCarlos Alberto Enciso Kind = KindCallSite;
57e28b9357SCarlos Alberto Enciso else if (getIsCompileUnit())
58e28b9357SCarlos Alberto Enciso Kind = KindCompileUnit;
59e28b9357SCarlos Alberto Enciso else if (getIsEnumeration())
60e28b9357SCarlos Alberto Enciso Kind = KindEnumeration;
61e28b9357SCarlos Alberto Enciso else if (getIsInlinedFunction())
62e28b9357SCarlos Alberto Enciso Kind = KindInlinedFunction;
63e28b9357SCarlos Alberto Enciso else if (getIsNamespace())
64e28b9357SCarlos Alberto Enciso Kind = KindNamespace;
65e28b9357SCarlos Alberto Enciso else if (getIsTemplatePack())
66e28b9357SCarlos Alberto Enciso Kind = KindTemplatePack;
67e28b9357SCarlos Alberto Enciso else if (getIsRoot())
68e28b9357SCarlos Alberto Enciso Kind = KindFile;
69e28b9357SCarlos Alberto Enciso else if (getIsTemplateAlias())
70e28b9357SCarlos Alberto Enciso Kind = KindTemplateAlias;
71e28b9357SCarlos Alberto Enciso else if (getIsClass())
72e28b9357SCarlos Alberto Enciso Kind = KindClass;
73e28b9357SCarlos Alberto Enciso else if (getIsFunction())
74e28b9357SCarlos Alberto Enciso Kind = KindFunction;
75e28b9357SCarlos Alberto Enciso else if (getIsStructure())
76e28b9357SCarlos Alberto Enciso Kind = KindStruct;
77e28b9357SCarlos Alberto Enciso else if (getIsUnion())
78e28b9357SCarlos Alberto Enciso Kind = KindUnion;
79e28b9357SCarlos Alberto Enciso return Kind;
80e28b9357SCarlos Alberto Enciso }
81e28b9357SCarlos Alberto Enciso
820332a8e7SCarlos Alberto Enciso LVScopeDispatch LVScope::Dispatch = {
830332a8e7SCarlos Alberto Enciso {LVScopeKind::IsAggregate, &LVScope::getIsAggregate},
840332a8e7SCarlos Alberto Enciso {LVScopeKind::IsArray, &LVScope::getIsArray},
850332a8e7SCarlos Alberto Enciso {LVScopeKind::IsBlock, &LVScope::getIsBlock},
860332a8e7SCarlos Alberto Enciso {LVScopeKind::IsCallSite, &LVScope::getIsCallSite},
870332a8e7SCarlos Alberto Enciso {LVScopeKind::IsCatchBlock, &LVScope::getIsCatchBlock},
880332a8e7SCarlos Alberto Enciso {LVScopeKind::IsClass, &LVScope::getIsClass},
890332a8e7SCarlos Alberto Enciso {LVScopeKind::IsCompileUnit, &LVScope::getIsCompileUnit},
900332a8e7SCarlos Alberto Enciso {LVScopeKind::IsEntryPoint, &LVScope::getIsEntryPoint},
910332a8e7SCarlos Alberto Enciso {LVScopeKind::IsEnumeration, &LVScope::getIsEnumeration},
920332a8e7SCarlos Alberto Enciso {LVScopeKind::IsFunction, &LVScope::getIsFunction},
930332a8e7SCarlos Alberto Enciso {LVScopeKind::IsFunctionType, &LVScope::getIsFunctionType},
940332a8e7SCarlos Alberto Enciso {LVScopeKind::IsInlinedFunction, &LVScope::getIsInlinedFunction},
950332a8e7SCarlos Alberto Enciso {LVScopeKind::IsLabel, &LVScope::getIsLabel},
960332a8e7SCarlos Alberto Enciso {LVScopeKind::IsLexicalBlock, &LVScope::getIsLexicalBlock},
970332a8e7SCarlos Alberto Enciso {LVScopeKind::IsNamespace, &LVScope::getIsNamespace},
980332a8e7SCarlos Alberto Enciso {LVScopeKind::IsRoot, &LVScope::getIsRoot},
990332a8e7SCarlos Alberto Enciso {LVScopeKind::IsStructure, &LVScope::getIsStructure},
1000332a8e7SCarlos Alberto Enciso {LVScopeKind::IsTemplate, &LVScope::getIsTemplate},
1010332a8e7SCarlos Alberto Enciso {LVScopeKind::IsTemplateAlias, &LVScope::getIsTemplateAlias},
1020332a8e7SCarlos Alberto Enciso {LVScopeKind::IsTemplatePack, &LVScope::getIsTemplatePack},
1030332a8e7SCarlos Alberto Enciso {LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},
1040332a8e7SCarlos Alberto Enciso {LVScopeKind::IsUnion, &LVScope::getIsUnion}};
1050332a8e7SCarlos Alberto Enciso
addToChildren(LVElement * Element)106e28b9357SCarlos Alberto Enciso void LVScope::addToChildren(LVElement *Element) {
107e28b9357SCarlos Alberto Enciso if (!Children)
1087fbcc244SCarlos Alberto Enciso Children = std::make_unique<LVElements>();
109e28b9357SCarlos Alberto Enciso Children->push_back(Element);
110e28b9357SCarlos Alberto Enciso }
111e28b9357SCarlos Alberto Enciso
addElement(LVElement * Element)112e28b9357SCarlos Alberto Enciso void LVScope::addElement(LVElement *Element) {
113e28b9357SCarlos Alberto Enciso assert(Element && "Invalid element.");
114e28b9357SCarlos Alberto Enciso if (Element->getIsType())
115e28b9357SCarlos Alberto Enciso addElement(static_cast<LVType *>(Element));
116e28b9357SCarlos Alberto Enciso else if (Element->getIsScope())
117e28b9357SCarlos Alberto Enciso addElement(static_cast<LVScope *>(Element));
118e28b9357SCarlos Alberto Enciso else if (Element->getIsSymbol())
119e28b9357SCarlos Alberto Enciso addElement(static_cast<LVSymbol *>(Element));
120e28b9357SCarlos Alberto Enciso else if (Element->getIsLine())
121e28b9357SCarlos Alberto Enciso addElement(static_cast<LVLine *>(Element));
122e28b9357SCarlos Alberto Enciso else
123e28b9357SCarlos Alberto Enciso llvm_unreachable("Invalid Element.");
124e28b9357SCarlos Alberto Enciso }
125e28b9357SCarlos Alberto Enciso
126e28b9357SCarlos Alberto Enciso // Adds the line info item to the ones stored in the scope.
addElement(LVLine * Line)127e28b9357SCarlos Alberto Enciso void LVScope::addElement(LVLine *Line) {
128e28b9357SCarlos Alberto Enciso assert(Line && "Invalid line.");
129e28b9357SCarlos Alberto Enciso assert(!Line->getParent() && "Line already inserted");
130e28b9357SCarlos Alberto Enciso if (!Lines)
1317fbcc244SCarlos Alberto Enciso Lines = std::make_unique<LVLines>();
132e28b9357SCarlos Alberto Enciso
133e28b9357SCarlos Alberto Enciso // Add it to parent.
134e28b9357SCarlos Alberto Enciso Lines->push_back(Line);
135e28b9357SCarlos Alberto Enciso Line->setParent(this);
136e28b9357SCarlos Alberto Enciso
137e28b9357SCarlos Alberto Enciso // Notify the reader about the new element being added.
138e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->addedElement(Line);
139e28b9357SCarlos Alberto Enciso
140e28b9357SCarlos Alberto Enciso // All logical elements added to the children, are sorted by any of the
141e28b9357SCarlos Alberto Enciso // following criterias: offset, name, line number, kind.
142e28b9357SCarlos Alberto Enciso // Do not add the line records to the children, as they represent the
143e28b9357SCarlos Alberto Enciso // logical view for the text section and any sorting will not preserve
144e28b9357SCarlos Alberto Enciso // the original sequence.
145e28b9357SCarlos Alberto Enciso
146e28b9357SCarlos Alberto Enciso // Indicate that this tree branch has lines.
147e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasLines, &LVScope::setHasLines);
148e28b9357SCarlos Alberto Enciso }
149e28b9357SCarlos Alberto Enciso
1503c397c90SCarlos Alberto Enciso // Add a location.
addObject(LVLocation * Location)1513c397c90SCarlos Alberto Enciso void LVScope::addObject(LVLocation *Location) {
1523c397c90SCarlos Alberto Enciso assert(Location && "Invalid location.");
1533c397c90SCarlos Alberto Enciso assert(!Location->getParent() && "Location already inserted");
1543c397c90SCarlos Alberto Enciso if (!Ranges)
1557fbcc244SCarlos Alberto Enciso Ranges = std::make_unique<LVLocations>();
1563c397c90SCarlos Alberto Enciso
1573c397c90SCarlos Alberto Enciso // Add it to parent.
1583c397c90SCarlos Alberto Enciso Location->setParent(this);
1593c397c90SCarlos Alberto Enciso Location->setOffset(getOffset());
1603c397c90SCarlos Alberto Enciso
1613c397c90SCarlos Alberto Enciso Ranges->push_back(Location);
1623c397c90SCarlos Alberto Enciso setHasRanges();
1633c397c90SCarlos Alberto Enciso }
1643c397c90SCarlos Alberto Enciso
165e28b9357SCarlos Alberto Enciso // Adds the scope to the child scopes and sets the parent in the child.
addElement(LVScope * Scope)166e28b9357SCarlos Alberto Enciso void LVScope::addElement(LVScope *Scope) {
167e28b9357SCarlos Alberto Enciso assert(Scope && "Invalid scope.");
168e28b9357SCarlos Alberto Enciso assert(!Scope->getParent() && "Scope already inserted");
169e28b9357SCarlos Alberto Enciso if (!Scopes)
1707fbcc244SCarlos Alberto Enciso Scopes = std::make_unique<LVScopes>();
171e28b9357SCarlos Alberto Enciso
172e28b9357SCarlos Alberto Enciso // Add it to parent.
173e28b9357SCarlos Alberto Enciso Scopes->push_back(Scope);
174e28b9357SCarlos Alberto Enciso addToChildren(Scope);
175e28b9357SCarlos Alberto Enciso Scope->setParent(this);
176e28b9357SCarlos Alberto Enciso
177e28b9357SCarlos Alberto Enciso // Notify the reader about the new element being added.
178e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->addedElement(Scope);
179e28b9357SCarlos Alberto Enciso
180e28b9357SCarlos Alberto Enciso // If the element is a global reference, mark its parent as having global
181e28b9357SCarlos Alberto Enciso // references; that information is used, to print only those branches
182e28b9357SCarlos Alberto Enciso // with global references.
183e28b9357SCarlos Alberto Enciso if (Scope->getIsGlobalReference())
184e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);
185e28b9357SCarlos Alberto Enciso else
186e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);
187e28b9357SCarlos Alberto Enciso
188e28b9357SCarlos Alberto Enciso // Indicate that this tree branch has scopes.
189e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasScopes, &LVScope::setHasScopes);
190e28b9357SCarlos Alberto Enciso }
191e28b9357SCarlos Alberto Enciso
192e28b9357SCarlos Alberto Enciso // Adds a symbol to the ones stored in the scope.
addElement(LVSymbol * Symbol)193e28b9357SCarlos Alberto Enciso void LVScope::addElement(LVSymbol *Symbol) {
194e28b9357SCarlos Alberto Enciso assert(Symbol && "Invalid symbol.");
195e28b9357SCarlos Alberto Enciso assert(!Symbol->getParent() && "Symbol already inserted");
196e28b9357SCarlos Alberto Enciso if (!Symbols)
1977fbcc244SCarlos Alberto Enciso Symbols = std::make_unique<LVSymbols>();
198e28b9357SCarlos Alberto Enciso
199e28b9357SCarlos Alberto Enciso // Add it to parent.
200e28b9357SCarlos Alberto Enciso Symbols->push_back(Symbol);
201e28b9357SCarlos Alberto Enciso addToChildren(Symbol);
202e28b9357SCarlos Alberto Enciso Symbol->setParent(this);
203e28b9357SCarlos Alberto Enciso
204e28b9357SCarlos Alberto Enciso // Notify the reader about the new element being added.
205e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->addedElement(Symbol);
206e28b9357SCarlos Alberto Enciso
207e28b9357SCarlos Alberto Enciso // If the element is a global reference, mark its parent as having global
208e28b9357SCarlos Alberto Enciso // references; that information is used, to print only those branches
209e28b9357SCarlos Alberto Enciso // with global references.
210e28b9357SCarlos Alberto Enciso if (Symbol->getIsGlobalReference())
211e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);
212e28b9357SCarlos Alberto Enciso else
213e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);
214e28b9357SCarlos Alberto Enciso
215e28b9357SCarlos Alberto Enciso // Indicate that this tree branch has symbols.
216e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasSymbols, &LVScope::setHasSymbols);
217e28b9357SCarlos Alberto Enciso }
218e28b9357SCarlos Alberto Enciso
219e28b9357SCarlos Alberto Enciso // Adds a type to the ones stored in the scope.
addElement(LVType * Type)220e28b9357SCarlos Alberto Enciso void LVScope::addElement(LVType *Type) {
221e28b9357SCarlos Alberto Enciso assert(Type && "Invalid type.");
222e28b9357SCarlos Alberto Enciso assert(!Type->getParent() && "Type already inserted");
223e28b9357SCarlos Alberto Enciso if (!Types)
2247fbcc244SCarlos Alberto Enciso Types = std::make_unique<LVTypes>();
225e28b9357SCarlos Alberto Enciso
226e28b9357SCarlos Alberto Enciso // Add it to parent.
227e28b9357SCarlos Alberto Enciso Types->push_back(Type);
228e28b9357SCarlos Alberto Enciso addToChildren(Type);
229e28b9357SCarlos Alberto Enciso Type->setParent(this);
230e28b9357SCarlos Alberto Enciso
231e28b9357SCarlos Alberto Enciso // Notify the reader about the new element being added.
232e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->addedElement(Type);
233e28b9357SCarlos Alberto Enciso
234e28b9357SCarlos Alberto Enciso // If the element is a global reference, mark its parent as having global
235e28b9357SCarlos Alberto Enciso // references; that information is used, to print only those branches
236e28b9357SCarlos Alberto Enciso // with global references.
237e28b9357SCarlos Alberto Enciso if (Type->getIsGlobalReference())
238e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);
239e28b9357SCarlos Alberto Enciso else
240e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);
241e28b9357SCarlos Alberto Enciso
242e28b9357SCarlos Alberto Enciso // Indicate that this tree branch has types.
243e28b9357SCarlos Alberto Enciso traverseParents(&LVScope::getHasTypes, &LVScope::setHasTypes);
244e28b9357SCarlos Alberto Enciso }
245e28b9357SCarlos Alberto Enciso
2463c397c90SCarlos Alberto Enciso // Add a pair of ranges.
addObject(LVAddress LowerAddress,LVAddress UpperAddress)2473c397c90SCarlos Alberto Enciso void LVScope::addObject(LVAddress LowerAddress, LVAddress UpperAddress) {
2483c397c90SCarlos Alberto Enciso // Pack the ranges into a Location object.
2497fbcc244SCarlos Alberto Enciso LVLocation *Location = getReader().createLocation();
2503c397c90SCarlos Alberto Enciso Location->setLowerAddress(LowerAddress);
2513c397c90SCarlos Alberto Enciso Location->setUpperAddress(UpperAddress);
2523c397c90SCarlos Alberto Enciso Location->setIsAddressRange();
2533c397c90SCarlos Alberto Enciso
2543c397c90SCarlos Alberto Enciso addObject(Location);
2553c397c90SCarlos Alberto Enciso }
2563c397c90SCarlos Alberto Enciso
removeElement(LVElement * Element)257e28b9357SCarlos Alberto Enciso bool LVScope::removeElement(LVElement *Element) {
258e28b9357SCarlos Alberto Enciso auto Predicate = [Element](LVElement *Item) -> bool {
259e28b9357SCarlos Alberto Enciso return Item == Element;
260e28b9357SCarlos Alberto Enciso };
261e28b9357SCarlos Alberto Enciso auto RemoveElement = [Element, Predicate](auto &Container) -> bool {
262e28b9357SCarlos Alberto Enciso auto Iter = std::remove_if(Container->begin(), Container->end(), Predicate);
263e28b9357SCarlos Alberto Enciso if (Iter != Container->end()) {
264e28b9357SCarlos Alberto Enciso Container->erase(Iter, Container->end());
265e28b9357SCarlos Alberto Enciso Element->resetParent();
266e28b9357SCarlos Alberto Enciso return true;
267e28b9357SCarlos Alberto Enciso }
268e28b9357SCarlos Alberto Enciso return false;
269e28b9357SCarlos Alberto Enciso };
270e28b9357SCarlos Alberto Enciso
271e28b9357SCarlos Alberto Enciso // As 'children' contains only (scopes, symbols and types), check if the
272e28b9357SCarlos Alberto Enciso // element we are deleting is a line.
273e28b9357SCarlos Alberto Enciso if (Element->getIsLine())
274e28b9357SCarlos Alberto Enciso return RemoveElement(Lines);
275e28b9357SCarlos Alberto Enciso
276e28b9357SCarlos Alberto Enciso if (RemoveElement(Children)) {
277e28b9357SCarlos Alberto Enciso if (Element->getIsSymbol())
278e28b9357SCarlos Alberto Enciso return RemoveElement(Symbols);
279e28b9357SCarlos Alberto Enciso if (Element->getIsType())
280e28b9357SCarlos Alberto Enciso return RemoveElement(Types);
281e28b9357SCarlos Alberto Enciso if (Element->getIsScope())
282e28b9357SCarlos Alberto Enciso return RemoveElement(Scopes);
283e28b9357SCarlos Alberto Enciso llvm_unreachable("Invalid element.");
284e28b9357SCarlos Alberto Enciso }
285e28b9357SCarlos Alberto Enciso
286e28b9357SCarlos Alberto Enciso return false;
287e28b9357SCarlos Alberto Enciso }
288e28b9357SCarlos Alberto Enciso
addMissingElements(LVScope * Reference)289e28b9357SCarlos Alberto Enciso void LVScope::addMissingElements(LVScope *Reference) {
290e28b9357SCarlos Alberto Enciso setAddedMissing();
291e28b9357SCarlos Alberto Enciso if (!Reference)
292e28b9357SCarlos Alberto Enciso return;
293e28b9357SCarlos Alberto Enciso
294e28b9357SCarlos Alberto Enciso // Get abstract symbols for the given scope reference.
295e28b9357SCarlos Alberto Enciso const LVSymbols *ReferenceSymbols = Reference->getSymbols();
296e28b9357SCarlos Alberto Enciso if (!ReferenceSymbols)
297e28b9357SCarlos Alberto Enciso return;
298e28b9357SCarlos Alberto Enciso
299e28b9357SCarlos Alberto Enciso LVSymbols References;
300e28b9357SCarlos Alberto Enciso References.append(ReferenceSymbols->begin(), ReferenceSymbols->end());
301e28b9357SCarlos Alberto Enciso
302e28b9357SCarlos Alberto Enciso // Erase abstract symbols already in this scope from the collection of
303e28b9357SCarlos Alberto Enciso // symbols in the referenced scope.
304e28b9357SCarlos Alberto Enciso if (getSymbols())
305e28b9357SCarlos Alberto Enciso for (const LVSymbol *Symbol : *getSymbols())
306e28b9357SCarlos Alberto Enciso if (Symbol->getHasReferenceAbstract())
307*f9306f6dSKazu Hirata llvm::erase(References, Symbol->getReference());
308e28b9357SCarlos Alberto Enciso
309e28b9357SCarlos Alberto Enciso // If we have elements left in 'References', those are the elements that
310e28b9357SCarlos Alberto Enciso // need to be inserted in the current scope.
311e28b9357SCarlos Alberto Enciso if (References.size()) {
312e28b9357SCarlos Alberto Enciso LLVM_DEBUG({
313e28b9357SCarlos Alberto Enciso dbgs() << "Insert Missing Inlined Elements\n"
314e28b9357SCarlos Alberto Enciso << "Offset = " << hexSquareString(getOffset()) << " "
315e28b9357SCarlos Alberto Enciso << "Abstract = " << hexSquareString(Reference->getOffset())
316e28b9357SCarlos Alberto Enciso << "\n";
317e28b9357SCarlos Alberto Enciso });
318e28b9357SCarlos Alberto Enciso for (LVSymbol *Reference : References) {
319e28b9357SCarlos Alberto Enciso LLVM_DEBUG({
320e28b9357SCarlos Alberto Enciso dbgs() << "Missing Offset = " << hexSquareString(Reference->getOffset())
321e28b9357SCarlos Alberto Enciso << "\n";
322e28b9357SCarlos Alberto Enciso });
323e28b9357SCarlos Alberto Enciso // We can't clone the abstract origin reference, as it contain extra
324e28b9357SCarlos Alberto Enciso // information that is incorrect for the element to be inserted.
325e28b9357SCarlos Alberto Enciso // As the symbol being added does not exist in the debug section,
326e28b9357SCarlos Alberto Enciso // use its parent scope offset, to indicate its DIE location.
3277fbcc244SCarlos Alberto Enciso LVSymbol *Symbol = getReader().createSymbol();
328e28b9357SCarlos Alberto Enciso addElement(Symbol);
329e28b9357SCarlos Alberto Enciso Symbol->setOffset(getOffset());
330e28b9357SCarlos Alberto Enciso Symbol->setIsOptimized();
331e28b9357SCarlos Alberto Enciso Symbol->setReference(Reference);
332e28b9357SCarlos Alberto Enciso
333e28b9357SCarlos Alberto Enciso // The symbol can be a constant, parameter or variable.
334e28b9357SCarlos Alberto Enciso if (Reference->getIsConstant())
335e28b9357SCarlos Alberto Enciso Symbol->setIsConstant();
336e28b9357SCarlos Alberto Enciso else if (Reference->getIsParameter())
337e28b9357SCarlos Alberto Enciso Symbol->setIsParameter();
338e28b9357SCarlos Alberto Enciso else if (Reference->getIsVariable())
339e28b9357SCarlos Alberto Enciso Symbol->setIsVariable();
340e28b9357SCarlos Alberto Enciso else
341e28b9357SCarlos Alberto Enciso llvm_unreachable("Invalid symbol kind.");
342e28b9357SCarlos Alberto Enciso }
343e28b9357SCarlos Alberto Enciso }
344e28b9357SCarlos Alberto Enciso }
345e28b9357SCarlos Alberto Enciso
updateLevel(LVScope * Parent,bool Moved)346e28b9357SCarlos Alberto Enciso void LVScope::updateLevel(LVScope *Parent, bool Moved) {
347e28b9357SCarlos Alberto Enciso // Update the level for the element itself and all its children, using the
348e28b9357SCarlos Alberto Enciso // given scope parent as reference.
349e28b9357SCarlos Alberto Enciso setLevel(Parent->getLevel() + 1);
350e28b9357SCarlos Alberto Enciso
351e28b9357SCarlos Alberto Enciso // Update the children.
352e28b9357SCarlos Alberto Enciso if (Children)
353e28b9357SCarlos Alberto Enciso for (LVElement *Element : *Children)
354e28b9357SCarlos Alberto Enciso Element->updateLevel(this, Moved);
355e28b9357SCarlos Alberto Enciso
356e28b9357SCarlos Alberto Enciso // Update any lines.
357e28b9357SCarlos Alberto Enciso if (Lines)
358e28b9357SCarlos Alberto Enciso for (LVLine *Line : *Lines)
359e28b9357SCarlos Alberto Enciso Line->updateLevel(this, Moved);
360e28b9357SCarlos Alberto Enciso }
361e28b9357SCarlos Alberto Enciso
resolve()362e28b9357SCarlos Alberto Enciso void LVScope::resolve() {
363e28b9357SCarlos Alberto Enciso if (getIsResolved())
364e28b9357SCarlos Alberto Enciso return;
365e28b9357SCarlos Alberto Enciso
366e28b9357SCarlos Alberto Enciso // Resolve the element itself.
367e28b9357SCarlos Alberto Enciso LVElement::resolve();
368e28b9357SCarlos Alberto Enciso
369e28b9357SCarlos Alberto Enciso // Resolve the children.
370e28b9357SCarlos Alberto Enciso if (Children)
371e28b9357SCarlos Alberto Enciso for (LVElement *Element : *Children) {
372e28b9357SCarlos Alberto Enciso if (getIsGlobalReference())
373e28b9357SCarlos Alberto Enciso // If the scope is a global reference, mark all its children as well.
374e28b9357SCarlos Alberto Enciso Element->setIsGlobalReference();
375e28b9357SCarlos Alberto Enciso Element->resolve();
376e28b9357SCarlos Alberto Enciso }
377e28b9357SCarlos Alberto Enciso }
378e28b9357SCarlos Alberto Enciso
resolveName()379e28b9357SCarlos Alberto Enciso void LVScope::resolveName() {
380e28b9357SCarlos Alberto Enciso if (getIsResolvedName())
381e28b9357SCarlos Alberto Enciso return;
382e28b9357SCarlos Alberto Enciso setIsResolvedName();
383e28b9357SCarlos Alberto Enciso
384e28b9357SCarlos Alberto Enciso // If the scope is a template, resolve the template parameters and get
385e28b9357SCarlos Alberto Enciso // the name for the template with the encoded arguments.
386e28b9357SCarlos Alberto Enciso if (getIsTemplate())
387e28b9357SCarlos Alberto Enciso resolveTemplate();
388e28b9357SCarlos Alberto Enciso else {
389e28b9357SCarlos Alberto Enciso if (LVElement *BaseType = getType()) {
390e28b9357SCarlos Alberto Enciso BaseType->resolveName();
391e28b9357SCarlos Alberto Enciso resolveFullname(BaseType);
392e28b9357SCarlos Alberto Enciso }
393e28b9357SCarlos Alberto Enciso }
394e28b9357SCarlos Alberto Enciso
395e28b9357SCarlos Alberto Enciso // In the case of unnamed scopes, try to generate a name for it, using
396e28b9357SCarlos Alberto Enciso // the parents name and the line information. In the case of compiler
397e28b9357SCarlos Alberto Enciso // generated functions, use its linkage name if is available.
398e28b9357SCarlos Alberto Enciso if (!isNamed()) {
399e28b9357SCarlos Alberto Enciso if (getIsArtificial())
400e28b9357SCarlos Alberto Enciso setName(getLinkageName());
401e28b9357SCarlos Alberto Enciso else
402e28b9357SCarlos Alberto Enciso generateName();
403e28b9357SCarlos Alberto Enciso }
404e28b9357SCarlos Alberto Enciso
405e28b9357SCarlos Alberto Enciso LVElement::resolveName();
4060332a8e7SCarlos Alberto Enciso
4070332a8e7SCarlos Alberto Enciso // Resolve any given pattern.
4080332a8e7SCarlos Alberto Enciso patterns().resolvePatternMatch(this);
409e28b9357SCarlos Alberto Enciso }
410e28b9357SCarlos Alberto Enciso
resolveReferences()411e28b9357SCarlos Alberto Enciso void LVScope::resolveReferences() {
412e28b9357SCarlos Alberto Enciso // The scopes can have the following references to other elements:
413e28b9357SCarlos Alberto Enciso // A type:
414e28b9357SCarlos Alberto Enciso // DW_AT_type -> Type or Scope
415e28b9357SCarlos Alberto Enciso // DW_AT_import -> Type
416e28b9357SCarlos Alberto Enciso // A Reference:
417e28b9357SCarlos Alberto Enciso // DW_AT_specification -> Scope
418e28b9357SCarlos Alberto Enciso // DW_AT_abstract_origin -> Scope
419e28b9357SCarlos Alberto Enciso // DW_AT_extension -> Scope
420e28b9357SCarlos Alberto Enciso
421e28b9357SCarlos Alberto Enciso // Resolve any referenced scope.
422e28b9357SCarlos Alberto Enciso LVScope *Reference = getReference();
423e28b9357SCarlos Alberto Enciso if (Reference) {
424e28b9357SCarlos Alberto Enciso Reference->resolve();
425e28b9357SCarlos Alberto Enciso // Recursively resolve the scope names.
426e28b9357SCarlos Alberto Enciso resolveReferencesChain();
427e28b9357SCarlos Alberto Enciso }
428e28b9357SCarlos Alberto Enciso
429e28b9357SCarlos Alberto Enciso // Set the file/line information using the Debug Information entry.
430e28b9357SCarlos Alberto Enciso setFile(Reference);
431e28b9357SCarlos Alberto Enciso
432e28b9357SCarlos Alberto Enciso // Resolve any referenced type or scope.
433e28b9357SCarlos Alberto Enciso if (LVElement *Element = getType())
434e28b9357SCarlos Alberto Enciso Element->resolve();
435e28b9357SCarlos Alberto Enciso }
436e28b9357SCarlos Alberto Enciso
resolveElements()437e28b9357SCarlos Alberto Enciso void LVScope::resolveElements() {
438e28b9357SCarlos Alberto Enciso // The current element represents the Root. Traverse each Compile Unit.
439e28b9357SCarlos Alberto Enciso if (!Scopes)
440e28b9357SCarlos Alberto Enciso return;
441e28b9357SCarlos Alberto Enciso
442e28b9357SCarlos Alberto Enciso for (LVScope *Scope : *Scopes) {
443e28b9357SCarlos Alberto Enciso LVScopeCompileUnit *CompileUnit = static_cast<LVScopeCompileUnit *>(Scope);
444e28b9357SCarlos Alberto Enciso getReader().setCompileUnit(CompileUnit);
445e28b9357SCarlos Alberto Enciso CompileUnit->resolve();
4460332a8e7SCarlos Alberto Enciso // Propagate any matching information into the scopes tree.
4470332a8e7SCarlos Alberto Enciso CompileUnit->propagatePatternMatch();
448e28b9357SCarlos Alberto Enciso }
449e28b9357SCarlos Alberto Enciso }
450e28b9357SCarlos Alberto Enciso
resolveReferencesChain()451e28b9357SCarlos Alberto Enciso StringRef LVScope::resolveReferencesChain() {
452e28b9357SCarlos Alberto Enciso // If the scope has a DW_AT_specification or DW_AT_abstract_origin,
453e28b9357SCarlos Alberto Enciso // follow the chain to resolve the name from those references.
454e28b9357SCarlos Alberto Enciso if (getHasReference() && !isNamed())
455e28b9357SCarlos Alberto Enciso setName(getReference()->resolveReferencesChain());
456e28b9357SCarlos Alberto Enciso
457e28b9357SCarlos Alberto Enciso return getName();
458e28b9357SCarlos Alberto Enciso }
459e28b9357SCarlos Alberto Enciso
460e28b9357SCarlos Alberto Enciso // Get template parameter types.
getTemplateParameterTypes(LVTypes & Params)461e28b9357SCarlos Alberto Enciso bool LVScope::getTemplateParameterTypes(LVTypes &Params) {
462e28b9357SCarlos Alberto Enciso // Traverse the scope types and populate the given container with those
463e28b9357SCarlos Alberto Enciso // types that are template parameters; that container will be used by
464e28b9357SCarlos Alberto Enciso // 'encodeTemplateArguments' to resolve them.
465e28b9357SCarlos Alberto Enciso if (const LVTypes *Types = getTypes())
466e28b9357SCarlos Alberto Enciso for (LVType *Type : *Types)
467e28b9357SCarlos Alberto Enciso if (Type->getIsTemplateParam()) {
468e28b9357SCarlos Alberto Enciso Type->resolve();
469e28b9357SCarlos Alberto Enciso Params.push_back(Type);
470e28b9357SCarlos Alberto Enciso }
471e28b9357SCarlos Alberto Enciso
472e28b9357SCarlos Alberto Enciso return !Params.empty();
473e28b9357SCarlos Alberto Enciso }
474e28b9357SCarlos Alberto Enciso
475e28b9357SCarlos Alberto Enciso // Resolve the template parameters/arguments relationship.
resolveTemplate()476e28b9357SCarlos Alberto Enciso void LVScope::resolveTemplate() {
477e28b9357SCarlos Alberto Enciso if (getIsTemplateResolved())
478e28b9357SCarlos Alberto Enciso return;
479e28b9357SCarlos Alberto Enciso setIsTemplateResolved();
480e28b9357SCarlos Alberto Enciso
481e28b9357SCarlos Alberto Enciso // Check if we need to encode the template arguments.
482e28b9357SCarlos Alberto Enciso if (options().getAttributeEncoded()) {
483e28b9357SCarlos Alberto Enciso LVTypes Params;
484e28b9357SCarlos Alberto Enciso if (getTemplateParameterTypes(Params)) {
485e28b9357SCarlos Alberto Enciso std::string EncodedArgs;
486e28b9357SCarlos Alberto Enciso // Encode the arguments as part of the template name and update the
487e28b9357SCarlos Alberto Enciso // template name, to reflect the encoded parameters.
488e28b9357SCarlos Alberto Enciso encodeTemplateArguments(EncodedArgs, &Params);
489d22f050eSGregory Alfonso setEncodedArgs(EncodedArgs);
490e28b9357SCarlos Alberto Enciso }
491e28b9357SCarlos Alberto Enciso }
492e28b9357SCarlos Alberto Enciso }
493e28b9357SCarlos Alberto Enciso
494e28b9357SCarlos Alberto Enciso // Get the qualified name for the template.
getQualifiedName(std::string & QualifiedName) const495e28b9357SCarlos Alberto Enciso void LVScope::getQualifiedName(std::string &QualifiedName) const {
496e28b9357SCarlos Alberto Enciso if (getIsRoot() || getIsCompileUnit())
497e28b9357SCarlos Alberto Enciso return;
498e28b9357SCarlos Alberto Enciso
499e28b9357SCarlos Alberto Enciso if (LVScope *Parent = getParentScope())
500e28b9357SCarlos Alberto Enciso Parent->getQualifiedName(QualifiedName);
501e28b9357SCarlos Alberto Enciso if (!QualifiedName.empty())
502e28b9357SCarlos Alberto Enciso QualifiedName.append("::");
503e28b9357SCarlos Alberto Enciso QualifiedName.append(std::string(getName()));
504e28b9357SCarlos Alberto Enciso }
505e28b9357SCarlos Alberto Enciso
506e28b9357SCarlos Alberto Enciso // Encode the template arguments as part of the template name.
encodeTemplateArguments(std::string & Name) const507e28b9357SCarlos Alberto Enciso void LVScope::encodeTemplateArguments(std::string &Name) const {
508e28b9357SCarlos Alberto Enciso // Qualify only when we are expanding parameters that are template
509e28b9357SCarlos Alberto Enciso // instances; the debugger will assume the current scope symbol as
510e28b9357SCarlos Alberto Enciso // the qualifying tag for the symbol being generated, which gives:
511e28b9357SCarlos Alberto Enciso // namespace std {
512e28b9357SCarlos Alberto Enciso // ...
513e28b9357SCarlos Alberto Enciso // set<float,std::less<float>,std::allocator<float>>
514e28b9357SCarlos Alberto Enciso // ...
515e28b9357SCarlos Alberto Enciso // }
516e28b9357SCarlos Alberto Enciso // The 'set' symbol is assumed to have the qualified tag 'std'.
517e28b9357SCarlos Alberto Enciso
518e28b9357SCarlos Alberto Enciso // We are resolving a template parameter which is another template. If
519e28b9357SCarlos Alberto Enciso // it is already resolved, just get the qualified name and return.
520e28b9357SCarlos Alberto Enciso std::string BaseName;
521e28b9357SCarlos Alberto Enciso getQualifiedName(BaseName);
522e28b9357SCarlos Alberto Enciso if (getIsTemplateResolved())
523e28b9357SCarlos Alberto Enciso Name.append(BaseName);
524e28b9357SCarlos Alberto Enciso }
525e28b9357SCarlos Alberto Enciso
encodeTemplateArguments(std::string & Name,const LVTypes * Types) const526e28b9357SCarlos Alberto Enciso void LVScope::encodeTemplateArguments(std::string &Name,
527e28b9357SCarlos Alberto Enciso const LVTypes *Types) const {
528e28b9357SCarlos Alberto Enciso // The encoded string will start with the scope name.
529e28b9357SCarlos Alberto Enciso Name.append("<");
530e28b9357SCarlos Alberto Enciso
531e28b9357SCarlos Alberto Enciso // The list of types are the template parameters.
532e28b9357SCarlos Alberto Enciso if (Types) {
533e28b9357SCarlos Alberto Enciso bool AddComma = false;
534e28b9357SCarlos Alberto Enciso for (const LVType *Type : *Types) {
535e28b9357SCarlos Alberto Enciso if (AddComma)
536e28b9357SCarlos Alberto Enciso Name.append(", ");
537e28b9357SCarlos Alberto Enciso Type->encodeTemplateArgument(Name);
538e28b9357SCarlos Alberto Enciso AddComma = true;
539e28b9357SCarlos Alberto Enciso }
540e28b9357SCarlos Alberto Enciso }
541e28b9357SCarlos Alberto Enciso
542e28b9357SCarlos Alberto Enciso Name.append(">");
543e28b9357SCarlos Alberto Enciso }
544e28b9357SCarlos Alberto Enciso
resolvePrinting() const545e28b9357SCarlos Alberto Enciso bool LVScope::resolvePrinting() const {
5462c155d37SCarlos Alberto Enciso // The warnings collected during the scope creation as per compile unit.
5472c155d37SCarlos Alberto Enciso // If there is a request for printing warnings, always print its associate
5482c155d37SCarlos Alberto Enciso // Compile Unit.
5492c155d37SCarlos Alberto Enciso if (options().getPrintWarnings() && (getIsRoot() || getIsCompileUnit()))
5502c155d37SCarlos Alberto Enciso return true;
5512c155d37SCarlos Alberto Enciso
5520332a8e7SCarlos Alberto Enciso // In selection mode, always print the root scope regardless of the
5530332a8e7SCarlos Alberto Enciso // number of matched elements. If no matches, the root by itself will
5540332a8e7SCarlos Alberto Enciso // indicate no matches.
5550332a8e7SCarlos Alberto Enciso if (options().getSelectExecute()) {
5560332a8e7SCarlos Alberto Enciso return getIsRoot() || getIsCompileUnit() || getHasPattern();
5570332a8e7SCarlos Alberto Enciso }
5580332a8e7SCarlos Alberto Enciso
559e28b9357SCarlos Alberto Enciso bool Globals = options().getAttributeGlobal();
560e28b9357SCarlos Alberto Enciso bool Locals = options().getAttributeLocal();
561e28b9357SCarlos Alberto Enciso if ((Globals && Locals) || (!Globals && !Locals)) {
562e28b9357SCarlos Alberto Enciso // Print both Global and Local.
563e28b9357SCarlos Alberto Enciso } else {
564e28b9357SCarlos Alberto Enciso // Check for Global or Local Objects.
565e28b9357SCarlos Alberto Enciso if ((Globals && !(getHasGlobals() || getIsGlobalReference())) ||
566e28b9357SCarlos Alberto Enciso (Locals && !(getHasLocals() || !getIsGlobalReference())))
567e28b9357SCarlos Alberto Enciso return false;
568e28b9357SCarlos Alberto Enciso }
569e28b9357SCarlos Alberto Enciso
570e28b9357SCarlos Alberto Enciso // For the case of functions, skip it if is compiler generated.
571e28b9357SCarlos Alberto Enciso if (getIsFunction() && getIsArtificial() &&
572e28b9357SCarlos Alberto Enciso !options().getAttributeGenerated())
573e28b9357SCarlos Alberto Enciso return false;
574e28b9357SCarlos Alberto Enciso
575e28b9357SCarlos Alberto Enciso return true;
576e28b9357SCarlos Alberto Enciso }
577e28b9357SCarlos Alberto Enciso
doPrint(bool Split,bool Match,bool Print,raw_ostream & OS,bool Full) const578e28b9357SCarlos Alberto Enciso Error LVScope::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
579e28b9357SCarlos Alberto Enciso bool Full) const {
580e28b9357SCarlos Alberto Enciso // During a view output splitting, use the output stream created by the
581e28b9357SCarlos Alberto Enciso // split context, then switch to the reader output stream.
582e28b9357SCarlos Alberto Enciso raw_ostream *StreamSplit = &OS;
583e28b9357SCarlos Alberto Enciso
584e7950fceSCarlos Alberto Enciso // Ignore the CU generated by the VS toolchain, when compiling to PDB.
585e7950fceSCarlos Alberto Enciso if (getIsSystem() && !options().getAttributeSystem())
586e7950fceSCarlos Alberto Enciso return Error::success();
587e7950fceSCarlos Alberto Enciso
588e28b9357SCarlos Alberto Enciso // If 'Split', we use the scope name (CU name) as the ouput file; the
589e28b9357SCarlos Alberto Enciso // delimiters in the pathname, must be replaced by a normal character.
590e28b9357SCarlos Alberto Enciso if (getIsCompileUnit()) {
591e28b9357SCarlos Alberto Enciso getReader().setCompileUnit(const_cast<LVScope *>(this));
592e28b9357SCarlos Alberto Enciso if (Split) {
593e28b9357SCarlos Alberto Enciso std::string ScopeName(getName());
594e28b9357SCarlos Alberto Enciso if (std::error_code EC =
595e28b9357SCarlos Alberto Enciso getReaderSplitContext().open(ScopeName, ".txt", OS))
596e28b9357SCarlos Alberto Enciso return createStringError(EC, "Unable to create split output file %s",
597e28b9357SCarlos Alberto Enciso ScopeName.c_str());
598e28b9357SCarlos Alberto Enciso StreamSplit = static_cast<raw_ostream *>(&getReaderSplitContext().os());
599e28b9357SCarlos Alberto Enciso }
600e28b9357SCarlos Alberto Enciso }
601e28b9357SCarlos Alberto Enciso
602e28b9357SCarlos Alberto Enciso // Ignore discarded or stripped scopes (functions).
603e28b9357SCarlos Alberto Enciso bool DoPrint = (options().getAttributeDiscarded()) ? true : !getIsDiscarded();
604e28b9357SCarlos Alberto Enciso
605e28b9357SCarlos Alberto Enciso // If we are in compare mode, the only conditions are related to the
606e28b9357SCarlos Alberto Enciso // element being missing. In the case of elements comparison, we print the
607e28b9357SCarlos Alberto Enciso // augmented view, that includes added elements.
608e28b9357SCarlos Alberto Enciso // In print mode, we check other conditions, such as local, global, etc.
609e28b9357SCarlos Alberto Enciso if (DoPrint) {
610e28b9357SCarlos Alberto Enciso DoPrint =
611e28b9357SCarlos Alberto Enciso getIsInCompare() ? options().getReportExecute() : resolvePrinting();
612e28b9357SCarlos Alberto Enciso }
613e28b9357SCarlos Alberto Enciso
614e28b9357SCarlos Alberto Enciso // At this point we have checked for very specific options, to decide if the
615e28b9357SCarlos Alberto Enciso // element will be printed. Include the caller's test for element general
616e28b9357SCarlos Alberto Enciso // print.
617e28b9357SCarlos Alberto Enciso DoPrint = DoPrint && (Print || options().getOutputSplit());
618e28b9357SCarlos Alberto Enciso
619e28b9357SCarlos Alberto Enciso if (DoPrint) {
620e28b9357SCarlos Alberto Enciso // Print the element itself.
621e28b9357SCarlos Alberto Enciso print(*StreamSplit, Full);
622e28b9357SCarlos Alberto Enciso
623e28b9357SCarlos Alberto Enciso // Check if we have reached the requested lexical level specified in the
624e28b9357SCarlos Alberto Enciso // command line options. Input file is level zero and the CU is level 1.
625e28b9357SCarlos Alberto Enciso if ((getIsRoot() || options().getPrintAnyElement()) &&
626e28b9357SCarlos Alberto Enciso options().getPrintFormatting() &&
627e28b9357SCarlos Alberto Enciso getLevel() < options().getOutputLevel()) {
628e28b9357SCarlos Alberto Enciso // Print the children.
629e28b9357SCarlos Alberto Enciso if (Children)
630e28b9357SCarlos Alberto Enciso for (const LVElement *Element : *Children) {
631e28b9357SCarlos Alberto Enciso if (Match && !Element->getHasPattern())
632e28b9357SCarlos Alberto Enciso continue;
633e28b9357SCarlos Alberto Enciso if (Error Err =
634e28b9357SCarlos Alberto Enciso Element->doPrint(Split, Match, Print, *StreamSplit, Full))
635e28b9357SCarlos Alberto Enciso return Err;
636e28b9357SCarlos Alberto Enciso }
637e28b9357SCarlos Alberto Enciso
638e28b9357SCarlos Alberto Enciso // Print the line records.
639e28b9357SCarlos Alberto Enciso if (Lines)
640e28b9357SCarlos Alberto Enciso for (const LVLine *Line : *Lines) {
641e28b9357SCarlos Alberto Enciso if (Match && !Line->getHasPattern())
642e28b9357SCarlos Alberto Enciso continue;
643e28b9357SCarlos Alberto Enciso if (Error Err =
644e28b9357SCarlos Alberto Enciso Line->doPrint(Split, Match, Print, *StreamSplit, Full))
645e28b9357SCarlos Alberto Enciso return Err;
646e28b9357SCarlos Alberto Enciso }
6472c155d37SCarlos Alberto Enciso
6482c155d37SCarlos Alberto Enciso // Print the warnings.
6492c155d37SCarlos Alberto Enciso if (options().getPrintWarnings())
6502c155d37SCarlos Alberto Enciso printWarnings(*StreamSplit, Full);
651e28b9357SCarlos Alberto Enciso }
652e28b9357SCarlos Alberto Enciso }
653e28b9357SCarlos Alberto Enciso
654e28b9357SCarlos Alberto Enciso // Done printing the compile unit. Print any requested summary and
655e28b9357SCarlos Alberto Enciso // restore the original output context.
656e28b9357SCarlos Alberto Enciso if (getIsCompileUnit()) {
657e28b9357SCarlos Alberto Enciso if (options().getPrintSummary())
658e28b9357SCarlos Alberto Enciso printSummary(*StreamSplit);
659e28b9357SCarlos Alberto Enciso if (options().getPrintSizes())
660e28b9357SCarlos Alberto Enciso printSizes(*StreamSplit);
661e28b9357SCarlos Alberto Enciso if (Split) {
662e28b9357SCarlos Alberto Enciso getReaderSplitContext().close();
663e28b9357SCarlos Alberto Enciso StreamSplit = &getReader().outputStream();
664e28b9357SCarlos Alberto Enciso }
665e28b9357SCarlos Alberto Enciso }
666e28b9357SCarlos Alberto Enciso
6672c155d37SCarlos Alberto Enciso if (getIsRoot() && options().getPrintWarnings()) {
6682c155d37SCarlos Alberto Enciso getReader().printRecords(*StreamSplit);
6692c155d37SCarlos Alberto Enciso }
6702c155d37SCarlos Alberto Enciso
671e28b9357SCarlos Alberto Enciso return Error::success();
672e28b9357SCarlos Alberto Enciso }
673e28b9357SCarlos Alberto Enciso
sort()674e28b9357SCarlos Alberto Enciso void LVScope::sort() {
675e28b9357SCarlos Alberto Enciso // Preserve the lines order as they are associated with user code.
676e28b9357SCarlos Alberto Enciso LVSortFunction SortFunction = getSortFunction();
677e28b9357SCarlos Alberto Enciso if (SortFunction) {
678e28b9357SCarlos Alberto Enciso std::function<void(LVScope * Parent, LVSortFunction SortFunction)> Sort =
679e28b9357SCarlos Alberto Enciso [&](LVScope *Parent, LVSortFunction SortFunction) {
6807fbcc244SCarlos Alberto Enciso auto Traverse = [&](auto &Set, LVSortFunction SortFunction) {
681e28b9357SCarlos Alberto Enciso if (Set)
682e28b9357SCarlos Alberto Enciso std::stable_sort(Set->begin(), Set->end(), SortFunction);
683e28b9357SCarlos Alberto Enciso };
684e28b9357SCarlos Alberto Enciso Traverse(Parent->Types, SortFunction);
685e28b9357SCarlos Alberto Enciso Traverse(Parent->Symbols, SortFunction);
686e28b9357SCarlos Alberto Enciso Traverse(Parent->Scopes, SortFunction);
6873c397c90SCarlos Alberto Enciso Traverse(Parent->Ranges, compareRange);
688e28b9357SCarlos Alberto Enciso Traverse(Parent->Children, SortFunction);
689e28b9357SCarlos Alberto Enciso
690e28b9357SCarlos Alberto Enciso if (Parent->Scopes)
691e28b9357SCarlos Alberto Enciso for (LVScope *Scope : *Parent->Scopes)
692e28b9357SCarlos Alberto Enciso Sort(Scope, SortFunction);
693e28b9357SCarlos Alberto Enciso };
694e28b9357SCarlos Alberto Enciso
695e28b9357SCarlos Alberto Enciso // Start traversing the scopes root and transform the element name.
696e28b9357SCarlos Alberto Enciso Sort(this, SortFunction);
697e28b9357SCarlos Alberto Enciso }
698e28b9357SCarlos Alberto Enciso }
699e28b9357SCarlos Alberto Enciso
traverseParents(LVScopeGetFunction GetFunction,LVScopeSetFunction SetFunction)700e28b9357SCarlos Alberto Enciso void LVScope::traverseParents(LVScopeGetFunction GetFunction,
701e28b9357SCarlos Alberto Enciso LVScopeSetFunction SetFunction) {
702e28b9357SCarlos Alberto Enciso // Traverse the parent tree.
703e28b9357SCarlos Alberto Enciso LVScope *Parent = this;
704e28b9357SCarlos Alberto Enciso while (Parent) {
705e28b9357SCarlos Alberto Enciso // Terminates if the 'SetFunction' has been already executed.
706e28b9357SCarlos Alberto Enciso if ((Parent->*GetFunction)())
707e28b9357SCarlos Alberto Enciso break;
708e28b9357SCarlos Alberto Enciso (Parent->*SetFunction)();
709e28b9357SCarlos Alberto Enciso Parent = Parent->getParentScope();
710e28b9357SCarlos Alberto Enciso }
711e28b9357SCarlos Alberto Enciso }
712e28b9357SCarlos Alberto Enciso
traverseParentsAndChildren(LVObjectGetFunction GetFunction,LVObjectSetFunction SetFunction)713e28b9357SCarlos Alberto Enciso void LVScope::traverseParentsAndChildren(LVObjectGetFunction GetFunction,
714e28b9357SCarlos Alberto Enciso LVObjectSetFunction SetFunction) {
715e28b9357SCarlos Alberto Enciso if (options().getReportParents()) {
716e28b9357SCarlos Alberto Enciso // First traverse the parent tree.
717e28b9357SCarlos Alberto Enciso LVScope *Parent = this;
718e28b9357SCarlos Alberto Enciso while (Parent) {
719e28b9357SCarlos Alberto Enciso // Terminates if the 'SetFunction' has been already executed.
720e28b9357SCarlos Alberto Enciso if ((Parent->*GetFunction)())
721e28b9357SCarlos Alberto Enciso break;
722e28b9357SCarlos Alberto Enciso (Parent->*SetFunction)();
723e28b9357SCarlos Alberto Enciso Parent = Parent->getParentScope();
724e28b9357SCarlos Alberto Enciso }
725e28b9357SCarlos Alberto Enciso }
726e28b9357SCarlos Alberto Enciso
727e28b9357SCarlos Alberto Enciso std::function<void(LVScope * Scope)> TraverseChildren = [&](LVScope *Scope) {
728e28b9357SCarlos Alberto Enciso auto Traverse = [&](const auto *Set) {
729e28b9357SCarlos Alberto Enciso if (Set)
730e28b9357SCarlos Alberto Enciso for (const auto &Entry : *Set)
731e28b9357SCarlos Alberto Enciso (Entry->*SetFunction)();
732e28b9357SCarlos Alberto Enciso };
733e28b9357SCarlos Alberto Enciso
734e28b9357SCarlos Alberto Enciso (Scope->*SetFunction)();
735e28b9357SCarlos Alberto Enciso
736e28b9357SCarlos Alberto Enciso Traverse(Scope->getTypes());
737e28b9357SCarlos Alberto Enciso Traverse(Scope->getSymbols());
738e28b9357SCarlos Alberto Enciso Traverse(Scope->getLines());
739e28b9357SCarlos Alberto Enciso
740e28b9357SCarlos Alberto Enciso if (const LVScopes *Scopes = Scope->getScopes())
741e28b9357SCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
742e28b9357SCarlos Alberto Enciso TraverseChildren(Scope);
743e28b9357SCarlos Alberto Enciso };
744e28b9357SCarlos Alberto Enciso
745e28b9357SCarlos Alberto Enciso if (options().getReportChildren())
746e28b9357SCarlos Alberto Enciso TraverseChildren(this);
747e28b9357SCarlos Alberto Enciso }
748e28b9357SCarlos Alberto Enciso
7493c397c90SCarlos Alberto Enciso // Traverse the symbol location ranges and for each range:
7503c397c90SCarlos Alberto Enciso // - Apply the 'ValidLocation' validation criteria.
7513c397c90SCarlos Alberto Enciso // - Add any failed range to the 'LocationList'.
7523c397c90SCarlos Alberto Enciso // - Calculate location coverage.
getLocations(LVLocations & LocationList,LVValidLocation ValidLocation,bool RecordInvalid)7533c397c90SCarlos Alberto Enciso void LVScope::getLocations(LVLocations &LocationList,
7543c397c90SCarlos Alberto Enciso LVValidLocation ValidLocation, bool RecordInvalid) {
7553c397c90SCarlos Alberto Enciso // Traverse scopes and symbols.
7563c397c90SCarlos Alberto Enciso if (Symbols)
7573c397c90SCarlos Alberto Enciso for (LVSymbol *Symbol : *Symbols)
7583c397c90SCarlos Alberto Enciso Symbol->getLocations(LocationList, ValidLocation, RecordInvalid);
7593c397c90SCarlos Alberto Enciso if (Scopes)
7603c397c90SCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
7613c397c90SCarlos Alberto Enciso Scope->getLocations(LocationList, ValidLocation, RecordInvalid);
7623c397c90SCarlos Alberto Enciso }
7633c397c90SCarlos Alberto Enciso
7643c397c90SCarlos Alberto Enciso // Traverse the scope ranges and for each range:
7653c397c90SCarlos Alberto Enciso // - Apply the 'ValidLocation' validation criteria.
7663c397c90SCarlos Alberto Enciso // - Add any failed range to the 'LocationList'.
7673c397c90SCarlos Alberto Enciso // - Calculate location coverage.
getRanges(LVLocations & LocationList,LVValidLocation ValidLocation,bool RecordInvalid)7683c397c90SCarlos Alberto Enciso void LVScope::getRanges(LVLocations &LocationList,
7693c397c90SCarlos Alberto Enciso LVValidLocation ValidLocation, bool RecordInvalid) {
7703c397c90SCarlos Alberto Enciso // Ignore discarded or stripped scopes (functions).
7713c397c90SCarlos Alberto Enciso if (getIsDiscarded())
7723c397c90SCarlos Alberto Enciso return;
7733c397c90SCarlos Alberto Enciso
7743c397c90SCarlos Alberto Enciso // Process the ranges for current scope.
7753c397c90SCarlos Alberto Enciso if (Ranges) {
7763c397c90SCarlos Alberto Enciso for (LVLocation *Location : *Ranges) {
7773c397c90SCarlos Alberto Enciso // Add the invalid location object.
7783c397c90SCarlos Alberto Enciso if (!(Location->*ValidLocation)() && RecordInvalid)
7793c397c90SCarlos Alberto Enciso LocationList.push_back(Location);
7803c397c90SCarlos Alberto Enciso }
7813c397c90SCarlos Alberto Enciso
7823c397c90SCarlos Alberto Enciso // Calculate coverage factor.
7833c397c90SCarlos Alberto Enciso calculateCoverage();
7843c397c90SCarlos Alberto Enciso }
7853c397c90SCarlos Alberto Enciso
7863c397c90SCarlos Alberto Enciso // Traverse the scopes.
7873c397c90SCarlos Alberto Enciso if (Scopes)
7883c397c90SCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
7893c397c90SCarlos Alberto Enciso Scope->getRanges(LocationList, ValidLocation, RecordInvalid);
7903c397c90SCarlos Alberto Enciso }
7913c397c90SCarlos Alberto Enciso
7923c397c90SCarlos Alberto Enciso // Get all the ranges associated with scopes.
getRanges(LVRange & RangeList)7933c397c90SCarlos Alberto Enciso void LVScope::getRanges(LVRange &RangeList) {
7943c397c90SCarlos Alberto Enciso // Ignore discarded or stripped scopes (functions).
7953c397c90SCarlos Alberto Enciso if (getIsDiscarded())
7963c397c90SCarlos Alberto Enciso return;
7973c397c90SCarlos Alberto Enciso
7983c397c90SCarlos Alberto Enciso if (Ranges)
7993c397c90SCarlos Alberto Enciso RangeList.addEntry(this);
8003c397c90SCarlos Alberto Enciso if (Scopes)
8013c397c90SCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
8023c397c90SCarlos Alberto Enciso Scope->getRanges(RangeList);
8033c397c90SCarlos Alberto Enciso }
8043c397c90SCarlos Alberto Enciso
outermostParent(LVAddress Address)8053c397c90SCarlos Alberto Enciso LVScope *LVScope::outermostParent(LVAddress Address) {
8063c397c90SCarlos Alberto Enciso LVScope *Parent = this;
8073c397c90SCarlos Alberto Enciso while (Parent) {
8083c397c90SCarlos Alberto Enciso const LVLocations *ParentRanges = Parent->getRanges();
8093c397c90SCarlos Alberto Enciso if (ParentRanges)
8103c397c90SCarlos Alberto Enciso for (const LVLocation *Location : *ParentRanges)
8113c397c90SCarlos Alberto Enciso if (Location->getLowerAddress() <= Address)
8123c397c90SCarlos Alberto Enciso return Parent;
8133c397c90SCarlos Alberto Enciso Parent = Parent->getParentScope();
8143c397c90SCarlos Alberto Enciso }
8153c397c90SCarlos Alberto Enciso return Parent;
8163c397c90SCarlos Alberto Enciso }
8173c397c90SCarlos Alberto Enciso
findIn(const LVScopes * Targets) const818e98a4c5aSCarlos Alberto Enciso LVScope *LVScope::findIn(const LVScopes *Targets) const {
819e98a4c5aSCarlos Alberto Enciso if (!Targets)
820e98a4c5aSCarlos Alberto Enciso return nullptr;
821e98a4c5aSCarlos Alberto Enciso
822e98a4c5aSCarlos Alberto Enciso // In the case of overloaded functions, sometimes the DWARF used to
823e98a4c5aSCarlos Alberto Enciso // describe them, does not give suficient information. Try to find a
824e98a4c5aSCarlos Alberto Enciso // perfect match or mark them as possible conflicts.
825e98a4c5aSCarlos Alberto Enciso LVScopes Candidates;
826e98a4c5aSCarlos Alberto Enciso for (LVScope *Target : *Targets)
827e98a4c5aSCarlos Alberto Enciso if (LVScope::equals(Target))
828e98a4c5aSCarlos Alberto Enciso Candidates.push_back(Target);
829e98a4c5aSCarlos Alberto Enciso
830e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
831e98a4c5aSCarlos Alberto Enciso if (!Candidates.empty()) {
832e98a4c5aSCarlos Alberto Enciso dbgs() << "\n[LVScope::findIn]\n"
833e98a4c5aSCarlos Alberto Enciso << "Reference: "
834e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(getOffset()) << ", "
835e98a4c5aSCarlos Alberto Enciso << "Level = " << getLevel() << ", "
836e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(kind()) << ", "
837e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(getName()) << "\n";
838e98a4c5aSCarlos Alberto Enciso for (const LVScope *Candidate : Candidates)
839e98a4c5aSCarlos Alberto Enciso dbgs() << "Candidate: "
840e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(Candidate->getOffset()) << ", "
841e98a4c5aSCarlos Alberto Enciso << "Level = " << Candidate->getLevel() << ", "
842e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Candidate->kind()) << ", "
843e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Candidate->getName()) << "\n";
844e98a4c5aSCarlos Alberto Enciso }
845e98a4c5aSCarlos Alberto Enciso });
846e98a4c5aSCarlos Alberto Enciso
847e98a4c5aSCarlos Alberto Enciso if (!Candidates.empty())
848e98a4c5aSCarlos Alberto Enciso return (Candidates.size() == 1)
849e98a4c5aSCarlos Alberto Enciso ? (equals(Candidates[0]) ? Candidates[0] : nullptr)
850e98a4c5aSCarlos Alberto Enciso : findEqualScope(&Candidates);
851e98a4c5aSCarlos Alberto Enciso
852e98a4c5aSCarlos Alberto Enciso return nullptr;
853e98a4c5aSCarlos Alberto Enciso }
854e98a4c5aSCarlos Alberto Enciso
equalNumberOfChildren(const LVScope * Scope) const855e98a4c5aSCarlos Alberto Enciso bool LVScope::equalNumberOfChildren(const LVScope *Scope) const {
856e98a4c5aSCarlos Alberto Enciso // Same number of children. Take into account which elements are requested
857e98a4c5aSCarlos Alberto Enciso // to be included in the comparison.
858e98a4c5aSCarlos Alberto Enciso return !(
859e98a4c5aSCarlos Alberto Enciso (options().getCompareScopes() && scopeCount() != Scope->scopeCount()) ||
860e98a4c5aSCarlos Alberto Enciso (options().getCompareSymbols() &&
861e98a4c5aSCarlos Alberto Enciso symbolCount() != Scope->symbolCount()) ||
862e98a4c5aSCarlos Alberto Enciso (options().getCompareTypes() && typeCount() != Scope->typeCount()) ||
863e98a4c5aSCarlos Alberto Enciso (options().getCompareLines() && lineCount() != Scope->lineCount()));
864e98a4c5aSCarlos Alberto Enciso }
865e98a4c5aSCarlos Alberto Enciso
markMissingParents(const LVScope * Target,bool TraverseChildren)866e98a4c5aSCarlos Alberto Enciso void LVScope::markMissingParents(const LVScope *Target, bool TraverseChildren) {
8677fbcc244SCarlos Alberto Enciso auto SetCompareState = [&](auto &Container) {
868e98a4c5aSCarlos Alberto Enciso if (Container)
869e98a4c5aSCarlos Alberto Enciso for (auto *Entry : *Container)
870e98a4c5aSCarlos Alberto Enciso Entry->setIsInCompare();
871e98a4c5aSCarlos Alberto Enciso };
872e98a4c5aSCarlos Alberto Enciso SetCompareState(Types);
873e98a4c5aSCarlos Alberto Enciso SetCompareState(Symbols);
874e98a4c5aSCarlos Alberto Enciso SetCompareState(Lines);
875e98a4c5aSCarlos Alberto Enciso SetCompareState(Scopes);
876e98a4c5aSCarlos Alberto Enciso
877e98a4c5aSCarlos Alberto Enciso // At this point, we are ready to start comparing the current scope, once
878e98a4c5aSCarlos Alberto Enciso // the compare bits have been set.
879e98a4c5aSCarlos Alberto Enciso if (options().getCompareTypes() && getTypes() && Target->getTypes())
880e98a4c5aSCarlos Alberto Enciso LVType::markMissingParents(getTypes(), Target->getTypes());
881e98a4c5aSCarlos Alberto Enciso if (options().getCompareSymbols() && getSymbols() && Target->getSymbols())
882e98a4c5aSCarlos Alberto Enciso LVSymbol::markMissingParents(getSymbols(), Target->getSymbols());
883e98a4c5aSCarlos Alberto Enciso if (options().getCompareLines() && getLines() && Target->getLines())
884e98a4c5aSCarlos Alberto Enciso LVLine::markMissingParents(getLines(), Target->getLines());
885e98a4c5aSCarlos Alberto Enciso if (getScopes() && Target->getScopes())
886e98a4c5aSCarlos Alberto Enciso LVScope::markMissingParents(getScopes(), Target->getScopes(),
887e98a4c5aSCarlos Alberto Enciso TraverseChildren);
888e98a4c5aSCarlos Alberto Enciso }
889e98a4c5aSCarlos Alberto Enciso
markMissingParents(const LVScopes * References,const LVScopes * Targets,bool TraverseChildren)890e98a4c5aSCarlos Alberto Enciso void LVScope::markMissingParents(const LVScopes *References,
891e98a4c5aSCarlos Alberto Enciso const LVScopes *Targets,
892e98a4c5aSCarlos Alberto Enciso bool TraverseChildren) {
893e98a4c5aSCarlos Alberto Enciso if (!(References && Targets))
894e98a4c5aSCarlos Alberto Enciso return;
895e98a4c5aSCarlos Alberto Enciso
896e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
897e98a4c5aSCarlos Alberto Enciso dbgs() << "\n[LVScope::markMissingParents]\n";
898e98a4c5aSCarlos Alberto Enciso for (const LVScope *Reference : *References)
899e98a4c5aSCarlos Alberto Enciso dbgs() << "References: "
900e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(Reference->getOffset()) << ", "
901e98a4c5aSCarlos Alberto Enciso << "Level = " << Reference->getLevel() << ", "
902e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Reference->kind()) << ", "
903e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Reference->getName()) << "\n";
904e98a4c5aSCarlos Alberto Enciso for (const LVScope *Target : *Targets)
905e98a4c5aSCarlos Alberto Enciso dbgs() << "Targets : "
906e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(Target->getOffset()) << ", "
907e98a4c5aSCarlos Alberto Enciso << "Level = " << Target->getLevel() << ", "
908e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Target->kind()) << ", "
909e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Target->getName()) << "\n";
910e98a4c5aSCarlos Alberto Enciso });
911e98a4c5aSCarlos Alberto Enciso
912e98a4c5aSCarlos Alberto Enciso for (LVScope *Reference : *References) {
913e98a4c5aSCarlos Alberto Enciso // Don't process 'Block' scopes, as we can't identify them.
914e98a4c5aSCarlos Alberto Enciso if (Reference->getIsBlock() || Reference->getIsGeneratedName())
915e98a4c5aSCarlos Alberto Enciso continue;
916e98a4c5aSCarlos Alberto Enciso
917e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
918e98a4c5aSCarlos Alberto Enciso dbgs() << "\nSearch Reference: "
919e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(Reference->getOffset()) << " "
920e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Reference->getName()) << "\n";
921e98a4c5aSCarlos Alberto Enciso });
922e98a4c5aSCarlos Alberto Enciso LVScope *Target = Reference->findIn(Targets);
923e98a4c5aSCarlos Alberto Enciso if (Target) {
924e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
925e98a4c5aSCarlos Alberto Enciso dbgs() << "\nFound Target: "
926e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(Target->getOffset()) << " "
927e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Target->getName()) << "\n";
928e98a4c5aSCarlos Alberto Enciso });
929e98a4c5aSCarlos Alberto Enciso if (TraverseChildren)
930e98a4c5aSCarlos Alberto Enciso Reference->markMissingParents(Target, TraverseChildren);
931e98a4c5aSCarlos Alberto Enciso } else {
932e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
933e98a4c5aSCarlos Alberto Enciso dbgs() << "Missing Reference: "
934e98a4c5aSCarlos Alberto Enciso << "Offset = " << hexSquareString(Reference->getOffset()) << " "
935e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Reference->getName()) << "\n";
936e98a4c5aSCarlos Alberto Enciso });
937e98a4c5aSCarlos Alberto Enciso Reference->markBranchAsMissing();
938e98a4c5aSCarlos Alberto Enciso }
939e98a4c5aSCarlos Alberto Enciso }
940e98a4c5aSCarlos Alberto Enciso }
941e98a4c5aSCarlos Alberto Enciso
equals(const LVScope * Scope) const942e98a4c5aSCarlos Alberto Enciso bool LVScope::equals(const LVScope *Scope) const {
943e98a4c5aSCarlos Alberto Enciso if (!LVElement::equals(Scope))
944e98a4c5aSCarlos Alberto Enciso return false;
945e98a4c5aSCarlos Alberto Enciso // For lexical scopes, check if their parents are the same.
946e98a4c5aSCarlos Alberto Enciso if (getIsLexicalBlock() && Scope->getIsLexicalBlock())
947e98a4c5aSCarlos Alberto Enciso return getParentScope()->equals(Scope->getParentScope());
948e98a4c5aSCarlos Alberto Enciso return true;
949e98a4c5aSCarlos Alberto Enciso }
950e98a4c5aSCarlos Alberto Enciso
findEqualScope(const LVScopes * Scopes) const951e98a4c5aSCarlos Alberto Enciso LVScope *LVScope::findEqualScope(const LVScopes *Scopes) const {
952e98a4c5aSCarlos Alberto Enciso assert(Scopes && "Scopes must not be nullptr");
953e98a4c5aSCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
954e98a4c5aSCarlos Alberto Enciso if (equals(Scope))
955e98a4c5aSCarlos Alberto Enciso return Scope;
956e98a4c5aSCarlos Alberto Enciso return nullptr;
957e98a4c5aSCarlos Alberto Enciso }
958e98a4c5aSCarlos Alberto Enciso
equals(const LVScopes * References,const LVScopes * Targets)959e98a4c5aSCarlos Alberto Enciso bool LVScope::equals(const LVScopes *References, const LVScopes *Targets) {
960e98a4c5aSCarlos Alberto Enciso if (!References && !Targets)
961e98a4c5aSCarlos Alberto Enciso return true;
962e98a4c5aSCarlos Alberto Enciso if (References && Targets && References->size() == Targets->size()) {
963e98a4c5aSCarlos Alberto Enciso for (const LVScope *Reference : *References)
964e98a4c5aSCarlos Alberto Enciso if (!Reference->findIn(Targets))
965e98a4c5aSCarlos Alberto Enciso return false;
966e98a4c5aSCarlos Alberto Enciso return true;
967e98a4c5aSCarlos Alberto Enciso }
968e98a4c5aSCarlos Alberto Enciso return false;
969e98a4c5aSCarlos Alberto Enciso }
970e98a4c5aSCarlos Alberto Enciso
report(LVComparePass Pass)971e98a4c5aSCarlos Alberto Enciso void LVScope::report(LVComparePass Pass) {
972e98a4c5aSCarlos Alberto Enciso getComparator().printItem(this, Pass);
973e98a4c5aSCarlos Alberto Enciso getComparator().push(this);
974e98a4c5aSCarlos Alberto Enciso if (Children)
975e98a4c5aSCarlos Alberto Enciso for (LVElement *Element : *Children)
976e98a4c5aSCarlos Alberto Enciso Element->report(Pass);
977e98a4c5aSCarlos Alberto Enciso
978e98a4c5aSCarlos Alberto Enciso if (Lines)
979e98a4c5aSCarlos Alberto Enciso for (LVLine *Line : *Lines)
980e98a4c5aSCarlos Alberto Enciso Line->report(Pass);
981e98a4c5aSCarlos Alberto Enciso getComparator().pop();
982e98a4c5aSCarlos Alberto Enciso }
983e98a4c5aSCarlos Alberto Enciso
printActiveRanges(raw_ostream & OS,bool Full) const9843c397c90SCarlos Alberto Enciso void LVScope::printActiveRanges(raw_ostream &OS, bool Full) const {
9853c397c90SCarlos Alberto Enciso if (options().getPrintFormatting() && options().getAttributeRange() &&
9863c397c90SCarlos Alberto Enciso Ranges) {
9873c397c90SCarlos Alberto Enciso for (const LVLocation *Location : *Ranges)
9883c397c90SCarlos Alberto Enciso Location->print(OS, Full);
9893c397c90SCarlos Alberto Enciso }
9903c397c90SCarlos Alberto Enciso }
9913c397c90SCarlos Alberto Enciso
printEncodedArgs(raw_ostream & OS,bool Full) const992e28b9357SCarlos Alberto Enciso void LVScope::printEncodedArgs(raw_ostream &OS, bool Full) const {
993e28b9357SCarlos Alberto Enciso if (options().getPrintFormatting() && options().getAttributeEncoded())
994e28b9357SCarlos Alberto Enciso printAttributes(OS, Full, "{Encoded} ", const_cast<LVScope *>(this),
995e28b9357SCarlos Alberto Enciso getEncodedArgs(), /*UseQuotes=*/false, /*PrintRef=*/false);
996e28b9357SCarlos Alberto Enciso }
997e28b9357SCarlos Alberto Enciso
print(raw_ostream & OS,bool Full) const998e28b9357SCarlos Alberto Enciso void LVScope::print(raw_ostream &OS, bool Full) const {
999e28b9357SCarlos Alberto Enciso if (getIncludeInPrint() && getReader().doPrintScope(this)) {
1000e28b9357SCarlos Alberto Enciso // For a summary (printed elements), do not count the scope root.
10010332a8e7SCarlos Alberto Enciso // For a summary (selected elements) do not count a compile unit.
10020332a8e7SCarlos Alberto Enciso if (!(getIsRoot() || (getIsCompileUnit() && options().getSelectExecute())))
1003e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->incrementPrintedScopes();
1004e28b9357SCarlos Alberto Enciso LVElement::print(OS, Full);
1005e28b9357SCarlos Alberto Enciso printExtra(OS, Full);
1006e28b9357SCarlos Alberto Enciso }
1007e28b9357SCarlos Alberto Enciso }
1008e28b9357SCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1009e28b9357SCarlos Alberto Enciso void LVScope::printExtra(raw_ostream &OS, bool Full) const {
1010e28b9357SCarlos Alberto Enciso OS << formattedKind(kind());
1011e28b9357SCarlos Alberto Enciso // Do not print any type or name for a lexical block.
1012e28b9357SCarlos Alberto Enciso if (!getIsBlock()) {
1013e28b9357SCarlos Alberto Enciso OS << " " << formattedName(getName());
1014e28b9357SCarlos Alberto Enciso if (!getIsAggregate())
1015e28b9357SCarlos Alberto Enciso OS << " -> " << typeOffsetAsString()
1016e28b9357SCarlos Alberto Enciso << formattedNames(getTypeQualifiedName(), typeAsString());
1017e28b9357SCarlos Alberto Enciso }
1018e28b9357SCarlos Alberto Enciso OS << "\n";
10193c397c90SCarlos Alberto Enciso
10203c397c90SCarlos Alberto Enciso // Print any active ranges.
10213c397c90SCarlos Alberto Enciso if (Full && getIsBlock())
10223c397c90SCarlos Alberto Enciso printActiveRanges(OS, Full);
1023e28b9357SCarlos Alberto Enciso }
1024e28b9357SCarlos Alberto Enciso
1025e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1026e28b9357SCarlos Alberto Enciso // DWARF Union/Structure/Class.
1027e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1028e98a4c5aSCarlos Alberto Enciso bool LVScopeAggregate::equals(const LVScope *Scope) const {
1029e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1030e98a4c5aSCarlos Alberto Enciso return false;
1031e98a4c5aSCarlos Alberto Enciso
1032e98a4c5aSCarlos Alberto Enciso if (!equalNumberOfChildren(Scope))
1033e98a4c5aSCarlos Alberto Enciso return false;
1034e98a4c5aSCarlos Alberto Enciso
1035e98a4c5aSCarlos Alberto Enciso // Check if the parameters match in the case of templates.
1036e98a4c5aSCarlos Alberto Enciso if (!LVType::parametersMatch(getTypes(), Scope->getTypes()))
1037e98a4c5aSCarlos Alberto Enciso return false;
1038e98a4c5aSCarlos Alberto Enciso
1039e98a4c5aSCarlos Alberto Enciso if (!isNamed() && !Scope->isNamed())
1040e98a4c5aSCarlos Alberto Enciso // In the case of unnamed union/structure/class compare the file name.
1041e98a4c5aSCarlos Alberto Enciso if (getFilenameIndex() != Scope->getFilenameIndex())
1042e98a4c5aSCarlos Alberto Enciso return false;
1043e98a4c5aSCarlos Alberto Enciso
1044e98a4c5aSCarlos Alberto Enciso return true;
1045e98a4c5aSCarlos Alberto Enciso }
1046e98a4c5aSCarlos Alberto Enciso
findEqualScope(const LVScopes * Scopes) const1047e98a4c5aSCarlos Alberto Enciso LVScope *LVScopeAggregate::findEqualScope(const LVScopes *Scopes) const {
1048e98a4c5aSCarlos Alberto Enciso assert(Scopes && "Scopes must not be nullptr");
1049e98a4c5aSCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
1050e98a4c5aSCarlos Alberto Enciso if (equals(Scope))
1051e98a4c5aSCarlos Alberto Enciso return Scope;
1052e98a4c5aSCarlos Alberto Enciso return nullptr;
1053e98a4c5aSCarlos Alberto Enciso }
1054e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1055e28b9357SCarlos Alberto Enciso void LVScopeAggregate::printExtra(raw_ostream &OS, bool Full) const {
1056e28b9357SCarlos Alberto Enciso LVScope::printExtra(OS, Full);
1057e28b9357SCarlos Alberto Enciso if (Full) {
1058e28b9357SCarlos Alberto Enciso if (getIsTemplateResolved())
1059e28b9357SCarlos Alberto Enciso printEncodedArgs(OS, Full);
1060e28b9357SCarlos Alberto Enciso LVScope *Reference = getReference();
1061e28b9357SCarlos Alberto Enciso if (Reference)
1062e28b9357SCarlos Alberto Enciso Reference->printReference(OS, Full, const_cast<LVScopeAggregate *>(this));
1063e28b9357SCarlos Alberto Enciso }
1064e28b9357SCarlos Alberto Enciso }
1065e28b9357SCarlos Alberto Enciso
1066e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1067e28b9357SCarlos Alberto Enciso // DWARF Template alias.
1068e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1069e98a4c5aSCarlos Alberto Enciso bool LVScopeAlias::equals(const LVScope *Scope) const {
1070e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1071e98a4c5aSCarlos Alberto Enciso return false;
1072e98a4c5aSCarlos Alberto Enciso return equalNumberOfChildren(Scope);
1073e98a4c5aSCarlos Alberto Enciso }
1074e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1075e28b9357SCarlos Alberto Enciso void LVScopeAlias::printExtra(raw_ostream &OS, bool Full) const {
1076e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> "
1077e28b9357SCarlos Alberto Enciso << typeOffsetAsString()
1078e28b9357SCarlos Alberto Enciso << formattedNames(getTypeQualifiedName(), typeAsString()) << "\n";
1079e28b9357SCarlos Alberto Enciso }
1080e28b9357SCarlos Alberto Enciso
1081e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1082e28b9357SCarlos Alberto Enciso // DWARF array (DW_TAG_array_type).
1083e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
resolveExtra()1084e28b9357SCarlos Alberto Enciso void LVScopeArray::resolveExtra() {
1085e28b9357SCarlos Alberto Enciso // If the scope is an array, resolve the subrange entries and get those
1086e28b9357SCarlos Alberto Enciso // values encoded and assigned to the scope type.
1087e28b9357SCarlos Alberto Enciso // Encode the array subrange entries as part of the name.
1088e28b9357SCarlos Alberto Enciso if (getIsArrayResolved())
1089e28b9357SCarlos Alberto Enciso return;
1090e28b9357SCarlos Alberto Enciso setIsArrayResolved();
1091e28b9357SCarlos Alberto Enciso
1092e28b9357SCarlos Alberto Enciso // There are 2 cases to represent the bounds information for an array:
1093e28b9357SCarlos Alberto Enciso // 1) DW_TAG_array_type
1094e28b9357SCarlos Alberto Enciso // DW_AT_type --> ref_type
1095e28b9357SCarlos Alberto Enciso // DW_TAG_subrange_type
1096e28b9357SCarlos Alberto Enciso // DW_AT_type --> ref_type (type of object)
1097e28b9357SCarlos Alberto Enciso // DW_AT_count --> value (number of elements in subrange)
1098e28b9357SCarlos Alberto Enciso
1099e28b9357SCarlos Alberto Enciso // 2) DW_TAG_array_type
1100e28b9357SCarlos Alberto Enciso // DW_AT_type --> ref_type
1101e28b9357SCarlos Alberto Enciso // DW_TAG_subrange_type
1102e28b9357SCarlos Alberto Enciso // DW_AT_lower_bound --> value
1103e28b9357SCarlos Alberto Enciso // DW_AT_upper_bound --> value
1104e28b9357SCarlos Alberto Enciso
1105e28b9357SCarlos Alberto Enciso // The idea is to represent the bounds as a string, depending on the format:
1106e28b9357SCarlos Alberto Enciso // 1) [count]
1107e28b9357SCarlos Alberto Enciso // 2) [lower][upper]
1108e28b9357SCarlos Alberto Enciso
1109e28b9357SCarlos Alberto Enciso // Traverse scope types, looking for those types that are subranges.
1110e28b9357SCarlos Alberto Enciso LVTypes Subranges;
1111e28b9357SCarlos Alberto Enciso if (const LVTypes *Types = getTypes())
1112e28b9357SCarlos Alberto Enciso for (LVType *Type : *Types)
1113e28b9357SCarlos Alberto Enciso if (Type->getIsSubrange()) {
1114e28b9357SCarlos Alberto Enciso Type->resolve();
1115e28b9357SCarlos Alberto Enciso Subranges.push_back(Type);
1116e28b9357SCarlos Alberto Enciso }
1117e28b9357SCarlos Alberto Enciso
1118e28b9357SCarlos Alberto Enciso // Use the subrange types to generate the high level name for the array.
1119e28b9357SCarlos Alberto Enciso // Check the type has been fully resolved.
1120e28b9357SCarlos Alberto Enciso if (LVElement *BaseType = getType()) {
1121e28b9357SCarlos Alberto Enciso BaseType->resolveName();
1122e28b9357SCarlos Alberto Enciso resolveFullname(BaseType);
1123e28b9357SCarlos Alberto Enciso }
1124e28b9357SCarlos Alberto Enciso
1125e28b9357SCarlos Alberto Enciso // In 'resolveFullname' a check is done for double spaces in the type name.
1126e28b9357SCarlos Alberto Enciso std::stringstream ArrayInfo;
1127e28b9357SCarlos Alberto Enciso if (ElementType)
1128e28b9357SCarlos Alberto Enciso ArrayInfo << getTypeName().str() << " ";
1129e28b9357SCarlos Alberto Enciso
1130e28b9357SCarlos Alberto Enciso for (const LVType *Type : Subranges) {
1131e28b9357SCarlos Alberto Enciso if (Type->getIsSubrangeCount())
1132e28b9357SCarlos Alberto Enciso // Check if we have DW_AT_count subrange style.
1133e28b9357SCarlos Alberto Enciso ArrayInfo << "[" << Type->getCount() << "]";
1134e28b9357SCarlos Alberto Enciso else {
1135e28b9357SCarlos Alberto Enciso // Get lower and upper subrange values.
1136e28b9357SCarlos Alberto Enciso unsigned LowerBound;
1137e28b9357SCarlos Alberto Enciso unsigned UpperBound;
1138e28b9357SCarlos Alberto Enciso std::tie(LowerBound, UpperBound) = Type->getBounds();
1139e28b9357SCarlos Alberto Enciso
1140e28b9357SCarlos Alberto Enciso // The representation depends on the bound values. If the lower value
1141e28b9357SCarlos Alberto Enciso // is zero, treat the pair as the elements count. Otherwise, just use
1142e28b9357SCarlos Alberto Enciso // the pair, as they are representing arrays in languages other than
1143e28b9357SCarlos Alberto Enciso // C/C++ and the lower limit is not zero.
1144e28b9357SCarlos Alberto Enciso if (LowerBound)
1145e28b9357SCarlos Alberto Enciso ArrayInfo << "[" << LowerBound << ".." << UpperBound << "]";
1146e28b9357SCarlos Alberto Enciso else
1147e28b9357SCarlos Alberto Enciso ArrayInfo << "[" << UpperBound + 1 << "]";
1148e28b9357SCarlos Alberto Enciso }
1149e28b9357SCarlos Alberto Enciso }
1150e28b9357SCarlos Alberto Enciso
1151e28b9357SCarlos Alberto Enciso // Update the scope name, to reflect the encoded subranges.
1152e28b9357SCarlos Alberto Enciso setName(ArrayInfo.str());
1153e28b9357SCarlos Alberto Enciso }
1154e28b9357SCarlos Alberto Enciso
equals(const LVScope * Scope) const1155e98a4c5aSCarlos Alberto Enciso bool LVScopeArray::equals(const LVScope *Scope) const {
1156e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1157e98a4c5aSCarlos Alberto Enciso return false;
1158e98a4c5aSCarlos Alberto Enciso
1159e98a4c5aSCarlos Alberto Enciso if (!equalNumberOfChildren(Scope))
1160e98a4c5aSCarlos Alberto Enciso return false;
1161e98a4c5aSCarlos Alberto Enciso
1162e98a4c5aSCarlos Alberto Enciso // Despite the arrays are encoded, to reflect the dimensions, we have to
1163e98a4c5aSCarlos Alberto Enciso // check the subranges, in order to determine if they are the same.
1164e98a4c5aSCarlos Alberto Enciso if (!LVType::equals(getTypes(), Scope->getTypes()))
1165e98a4c5aSCarlos Alberto Enciso return false;
1166e98a4c5aSCarlos Alberto Enciso
1167e98a4c5aSCarlos Alberto Enciso return true;
1168e98a4c5aSCarlos Alberto Enciso }
1169e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1170e28b9357SCarlos Alberto Enciso void LVScopeArray::printExtra(raw_ostream &OS, bool Full) const {
1171e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << typeOffsetAsString()
1172e28b9357SCarlos Alberto Enciso << formattedName(getName()) << "\n";
1173e28b9357SCarlos Alberto Enciso }
1174e28b9357SCarlos Alberto Enciso
1175e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1176e28b9357SCarlos Alberto Enciso // An object file (single or multiple CUs).
1177e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
addSize(LVScope * Scope,LVOffset Lower,LVOffset Upper)1178e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::addSize(LVScope *Scope, LVOffset Lower,
1179e28b9357SCarlos Alberto Enciso LVOffset Upper) {
1180e28b9357SCarlos Alberto Enciso LLVM_DEBUG({
1181e28b9357SCarlos Alberto Enciso dbgs() << format(
11827292d051SMichał Górny "CU [0x%08" PRIx64 "], Scope [0x%08" PRIx64 "], Range [0x%08" PRIx64
11837292d051SMichał Górny ":0x%08" PRIx64 "], Size = %" PRId64 "\n",
1184e28b9357SCarlos Alberto Enciso getOffset(), Scope->getOffset(), Lower, Upper, Upper - Lower);
1185e28b9357SCarlos Alberto Enciso });
1186e28b9357SCarlos Alberto Enciso
1187e28b9357SCarlos Alberto Enciso // There is no need to check for a previous entry, as we are traversing the
1188e28b9357SCarlos Alberto Enciso // debug information in sequential order.
1189e28b9357SCarlos Alberto Enciso LVOffset Size = Upper - Lower;
1190e28b9357SCarlos Alberto Enciso Sizes[Scope] = Size;
1191e28b9357SCarlos Alberto Enciso if (this == Scope)
1192e28b9357SCarlos Alberto Enciso // Record contribution size for the compilation unit.
1193e28b9357SCarlos Alberto Enciso CUContributionSize = Size;
1194e28b9357SCarlos Alberto Enciso }
1195e28b9357SCarlos Alberto Enciso
11960332a8e7SCarlos Alberto Enciso // Update parents and children with pattern information.
propagatePatternMatch()11970332a8e7SCarlos Alberto Enciso void LVScopeCompileUnit::propagatePatternMatch() {
11980332a8e7SCarlos Alberto Enciso // At this stage, we have finished creating the Scopes tree and we have
11990332a8e7SCarlos Alberto Enciso // a list of elements that match the pattern specified in the command line.
12000332a8e7SCarlos Alberto Enciso // The pattern corresponds to a scope or element; mark parents and/or
12010332a8e7SCarlos Alberto Enciso // children as having that pattern, before any printing is done.
12020332a8e7SCarlos Alberto Enciso if (!options().getSelectExecute())
12030332a8e7SCarlos Alberto Enciso return;
12040332a8e7SCarlos Alberto Enciso
12050332a8e7SCarlos Alberto Enciso if (MatchedScopes.size()) {
12060332a8e7SCarlos Alberto Enciso for (LVScope *Scope : MatchedScopes)
12070332a8e7SCarlos Alberto Enciso Scope->traverseParentsAndChildren(&LVScope::getHasPattern,
12080332a8e7SCarlos Alberto Enciso &LVScope::setHasPattern);
12090332a8e7SCarlos Alberto Enciso } else {
12100332a8e7SCarlos Alberto Enciso // Mark the compile unit as having a pattern to enable any requests to
12110332a8e7SCarlos Alberto Enciso // print sizes and summary as that information is recorded at that level.
12120332a8e7SCarlos Alberto Enciso setHasPattern();
12130332a8e7SCarlos Alberto Enciso }
12140332a8e7SCarlos Alberto Enciso }
12150332a8e7SCarlos Alberto Enciso
processRangeLocationCoverage(LVValidLocation ValidLocation)12163c397c90SCarlos Alberto Enciso void LVScopeCompileUnit::processRangeLocationCoverage(
12173c397c90SCarlos Alberto Enciso LVValidLocation ValidLocation) {
12183c397c90SCarlos Alberto Enciso if (options().getAttributeRange()) {
12193c397c90SCarlos Alberto Enciso // Traverse the scopes to get scopes that have invalid ranges.
12203c397c90SCarlos Alberto Enciso LVLocations Locations;
12212c155d37SCarlos Alberto Enciso bool RecordInvalid = options().getWarningRanges();
12223c397c90SCarlos Alberto Enciso getRanges(Locations, ValidLocation, RecordInvalid);
12232c155d37SCarlos Alberto Enciso
12242c155d37SCarlos Alberto Enciso // Validate ranges associated with scopes.
12252c155d37SCarlos Alberto Enciso if (RecordInvalid)
12262c155d37SCarlos Alberto Enciso for (LVLocation *Location : Locations)
12272c155d37SCarlos Alberto Enciso addInvalidRange(Location);
12283c397c90SCarlos Alberto Enciso }
12293c397c90SCarlos Alberto Enciso
12303c397c90SCarlos Alberto Enciso if (options().getAttributeLocation()) {
12313c397c90SCarlos Alberto Enciso // Traverse the scopes to get locations that have invalid ranges.
12323c397c90SCarlos Alberto Enciso LVLocations Locations;
12332c155d37SCarlos Alberto Enciso bool RecordInvalid = options().getWarningLocations();
12343c397c90SCarlos Alberto Enciso getLocations(Locations, ValidLocation, RecordInvalid);
12352c155d37SCarlos Alberto Enciso
12362c155d37SCarlos Alberto Enciso // Validate ranges associated with locations.
12372c155d37SCarlos Alberto Enciso if (RecordInvalid)
12382c155d37SCarlos Alberto Enciso for (LVLocation *Location : Locations)
12392c155d37SCarlos Alberto Enciso addInvalidLocation(Location);
12403c397c90SCarlos Alberto Enciso }
12413c397c90SCarlos Alberto Enciso }
12423c397c90SCarlos Alberto Enciso
addMapping(LVLine * Line,LVSectionIndex SectionIndex)12434f06d46fSCarlos Alberto Enciso void LVScopeCompileUnit::addMapping(LVLine *Line, LVSectionIndex SectionIndex) {
12444f06d46fSCarlos Alberto Enciso LVAddress Address = Line->getOffset();
12454f06d46fSCarlos Alberto Enciso SectionMappings.add(SectionIndex, Address, Line);
1246e28b9357SCarlos Alberto Enciso }
1247e28b9357SCarlos Alberto Enciso
lineLowerBound(LVAddress Address,LVScope * Scope) const12484f06d46fSCarlos Alberto Enciso LVLine *LVScopeCompileUnit::lineLowerBound(LVAddress Address,
12494f06d46fSCarlos Alberto Enciso LVScope *Scope) const {
12504f06d46fSCarlos Alberto Enciso LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope);
12514f06d46fSCarlos Alberto Enciso LVAddressToLine *Map = SectionMappings.findMap(SectionIndex);
12524f06d46fSCarlos Alberto Enciso if (!Map || Map->empty())
12532c155d37SCarlos Alberto Enciso return nullptr;
12544f06d46fSCarlos Alberto Enciso LVAddressToLine::const_iterator Iter = Map->lower_bound(Address);
12554f06d46fSCarlos Alberto Enciso return (Iter != Map->end()) ? Iter->second : nullptr;
12564f06d46fSCarlos Alberto Enciso }
12574f06d46fSCarlos Alberto Enciso
lineUpperBound(LVAddress Address,LVScope * Scope) const12584f06d46fSCarlos Alberto Enciso LVLine *LVScopeCompileUnit::lineUpperBound(LVAddress Address,
12594f06d46fSCarlos Alberto Enciso LVScope *Scope) const {
12604f06d46fSCarlos Alberto Enciso LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope);
12614f06d46fSCarlos Alberto Enciso LVAddressToLine *Map = SectionMappings.findMap(SectionIndex);
12624f06d46fSCarlos Alberto Enciso if (!Map || Map->empty())
12634f06d46fSCarlos Alberto Enciso return nullptr;
12644f06d46fSCarlos Alberto Enciso LVAddressToLine::const_iterator Iter = Map->upper_bound(Address);
12654f06d46fSCarlos Alberto Enciso if (Iter != Map->begin())
1266e28b9357SCarlos Alberto Enciso Iter = std::prev(Iter);
12672c155d37SCarlos Alberto Enciso return Iter->second;
1268e28b9357SCarlos Alberto Enciso }
1269e28b9357SCarlos Alberto Enciso
lineRange(LVLocation * Location) const12704f06d46fSCarlos Alberto Enciso LVLineRange LVScopeCompileUnit::lineRange(LVLocation *Location) const {
12714f06d46fSCarlos Alberto Enciso // The parent of a location can be a symbol or a scope.
12724f06d46fSCarlos Alberto Enciso LVElement *Element = Location->getParent();
12734f06d46fSCarlos Alberto Enciso LVScope *Parent = Element->getIsScope() ? static_cast<LVScope *>(Element)
12744f06d46fSCarlos Alberto Enciso : Element->getParentScope();
12754f06d46fSCarlos Alberto Enciso LVLine *LowLine = lineLowerBound(Location->getLowerAddress(), Parent);
12764f06d46fSCarlos Alberto Enciso LVLine *HighLine = lineUpperBound(Location->getUpperAddress(), Parent);
12774f06d46fSCarlos Alberto Enciso return LVLineRange(LowLine, HighLine);
12784f06d46fSCarlos Alberto Enciso }
12794f06d46fSCarlos Alberto Enciso
getFilename(size_t Index) const1280e28b9357SCarlos Alberto Enciso StringRef LVScopeCompileUnit::getFilename(size_t Index) const {
1281e28b9357SCarlos Alberto Enciso if (Index <= 0 || Index > Filenames.size())
1282e28b9357SCarlos Alberto Enciso return StringRef();
1283e28b9357SCarlos Alberto Enciso return getStringPool().getString(Filenames[Index - 1]);
1284e28b9357SCarlos Alberto Enciso }
1285e28b9357SCarlos Alberto Enciso
equals(const LVScope * Scope) const1286e98a4c5aSCarlos Alberto Enciso bool LVScopeCompileUnit::equals(const LVScope *Scope) const {
1287e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1288e98a4c5aSCarlos Alberto Enciso return false;
1289e98a4c5aSCarlos Alberto Enciso
1290e98a4c5aSCarlos Alberto Enciso return getNameIndex() == Scope->getNameIndex();
1291e98a4c5aSCarlos Alberto Enciso }
1292e98a4c5aSCarlos Alberto Enciso
incrementPrintedLines()12930332a8e7SCarlos Alberto Enciso void LVScopeCompileUnit::incrementPrintedLines() {
12940332a8e7SCarlos Alberto Enciso options().getSelectExecute() ? ++Found.Lines : ++Printed.Lines;
12950332a8e7SCarlos Alberto Enciso }
incrementPrintedScopes()12960332a8e7SCarlos Alberto Enciso void LVScopeCompileUnit::incrementPrintedScopes() {
12970332a8e7SCarlos Alberto Enciso options().getSelectExecute() ? ++Found.Scopes : ++Printed.Scopes;
12980332a8e7SCarlos Alberto Enciso }
incrementPrintedSymbols()12990332a8e7SCarlos Alberto Enciso void LVScopeCompileUnit::incrementPrintedSymbols() {
13000332a8e7SCarlos Alberto Enciso options().getSelectExecute() ? ++Found.Symbols : ++Printed.Symbols;
13010332a8e7SCarlos Alberto Enciso }
incrementPrintedTypes()13020332a8e7SCarlos Alberto Enciso void LVScopeCompileUnit::incrementPrintedTypes() {
13030332a8e7SCarlos Alberto Enciso options().getSelectExecute() ? ++Found.Types : ++Printed.Types;
13040332a8e7SCarlos Alberto Enciso }
1305e28b9357SCarlos Alberto Enciso
1306e28b9357SCarlos Alberto Enciso // Values are used by '--summary' option (allocated).
increment(LVLine * Line)1307e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::increment(LVLine *Line) {
1308e28b9357SCarlos Alberto Enciso if (Line->getIncludeInPrint())
1309e28b9357SCarlos Alberto Enciso ++Allocated.Lines;
1310e28b9357SCarlos Alberto Enciso }
increment(LVScope * Scope)1311e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::increment(LVScope *Scope) {
1312e28b9357SCarlos Alberto Enciso if (Scope->getIncludeInPrint())
1313e28b9357SCarlos Alberto Enciso ++Allocated.Scopes;
1314e28b9357SCarlos Alberto Enciso }
increment(LVSymbol * Symbol)1315e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::increment(LVSymbol *Symbol) {
1316e28b9357SCarlos Alberto Enciso if (Symbol->getIncludeInPrint())
1317e28b9357SCarlos Alberto Enciso ++Allocated.Symbols;
1318e28b9357SCarlos Alberto Enciso }
increment(LVType * Type)1319e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::increment(LVType *Type) {
1320e28b9357SCarlos Alberto Enciso if (Type->getIncludeInPrint())
1321e28b9357SCarlos Alberto Enciso ++Allocated.Types;
1322e28b9357SCarlos Alberto Enciso }
1323e28b9357SCarlos Alberto Enciso
1324e28b9357SCarlos Alberto Enciso // A new element has been added to the scopes tree. Take the following steps:
1325e28b9357SCarlos Alberto Enciso // Increase the added element counters, for printing summary.
1326e98a4c5aSCarlos Alberto Enciso // During comparison notify the Reader of the new element.
addedElement(LVLine * Line)1327e98a4c5aSCarlos Alberto Enciso void LVScopeCompileUnit::addedElement(LVLine *Line) {
1328e98a4c5aSCarlos Alberto Enciso increment(Line);
1329e98a4c5aSCarlos Alberto Enciso getReader().notifyAddedElement(Line);
1330e98a4c5aSCarlos Alberto Enciso }
addedElement(LVScope * Scope)1331e98a4c5aSCarlos Alberto Enciso void LVScopeCompileUnit::addedElement(LVScope *Scope) {
1332e98a4c5aSCarlos Alberto Enciso increment(Scope);
1333e98a4c5aSCarlos Alberto Enciso getReader().notifyAddedElement(Scope);
1334e98a4c5aSCarlos Alberto Enciso }
addedElement(LVSymbol * Symbol)1335e98a4c5aSCarlos Alberto Enciso void LVScopeCompileUnit::addedElement(LVSymbol *Symbol) {
1336e98a4c5aSCarlos Alberto Enciso increment(Symbol);
1337e98a4c5aSCarlos Alberto Enciso getReader().notifyAddedElement(Symbol);
1338e98a4c5aSCarlos Alberto Enciso }
addedElement(LVType * Type)1339e98a4c5aSCarlos Alberto Enciso void LVScopeCompileUnit::addedElement(LVType *Type) {
1340e98a4c5aSCarlos Alberto Enciso increment(Type);
1341e98a4c5aSCarlos Alberto Enciso getReader().notifyAddedElement(Type);
1342e98a4c5aSCarlos Alberto Enciso }
1343e28b9357SCarlos Alberto Enciso
13442c155d37SCarlos Alberto Enciso // Record unsuported DWARF tags.
addDebugTag(dwarf::Tag Target,LVOffset Offset)13452c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::addDebugTag(dwarf::Tag Target, LVOffset Offset) {
13467fbcc244SCarlos Alberto Enciso addItem<LVTagOffsetsMap, dwarf::Tag, LVOffset>(&DebugTags, Target, Offset);
13472c155d37SCarlos Alberto Enciso }
13482c155d37SCarlos Alberto Enciso
13492c155d37SCarlos Alberto Enciso // Record elements with invalid offsets.
addInvalidOffset(LVOffset Offset,LVElement * Element)13502c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::addInvalidOffset(LVOffset Offset, LVElement *Element) {
13512c155d37SCarlos Alberto Enciso if (WarningOffsets.find(Offset) == WarningOffsets.end())
13522c155d37SCarlos Alberto Enciso WarningOffsets.emplace(Offset, Element);
13532c155d37SCarlos Alberto Enciso }
13542c155d37SCarlos Alberto Enciso
13552c155d37SCarlos Alberto Enciso // Record symbols with invalid coverage values.
addInvalidCoverage(LVSymbol * Symbol)13562c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::addInvalidCoverage(LVSymbol *Symbol) {
13572c155d37SCarlos Alberto Enciso LVOffset Offset = Symbol->getOffset();
13582c155d37SCarlos Alberto Enciso if (InvalidCoverages.find(Offset) == InvalidCoverages.end())
13592c155d37SCarlos Alberto Enciso InvalidCoverages.emplace(Offset, Symbol);
13602c155d37SCarlos Alberto Enciso }
13612c155d37SCarlos Alberto Enciso
13622c155d37SCarlos Alberto Enciso // Record symbols with invalid locations.
addInvalidLocation(LVLocation * Location)13632c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::addInvalidLocation(LVLocation *Location) {
13642c155d37SCarlos Alberto Enciso addInvalidLocationOrRange(Location, Location->getParentSymbol(),
13652c155d37SCarlos Alberto Enciso &InvalidLocations);
13662c155d37SCarlos Alberto Enciso }
13672c155d37SCarlos Alberto Enciso
13682c155d37SCarlos Alberto Enciso // Record scopes with invalid ranges.
addInvalidRange(LVLocation * Location)13692c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::addInvalidRange(LVLocation *Location) {
13702c155d37SCarlos Alberto Enciso addInvalidLocationOrRange(Location, Location->getParentScope(),
13712c155d37SCarlos Alberto Enciso &InvalidRanges);
13722c155d37SCarlos Alberto Enciso }
13732c155d37SCarlos Alberto Enciso
13742c155d37SCarlos Alberto Enciso // Record line zero.
addLineZero(LVLine * Line)13752c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::addLineZero(LVLine *Line) {
13762c155d37SCarlos Alberto Enciso LVScope *Scope = Line->getParentScope();
13772c155d37SCarlos Alberto Enciso LVOffset Offset = Scope->getOffset();
13782c155d37SCarlos Alberto Enciso addInvalidOffset(Offset, Scope);
13797fbcc244SCarlos Alberto Enciso addItem<LVOffsetLinesMap, LVOffset, LVLine *>(&LinesZero, Offset, Line);
13802c155d37SCarlos Alberto Enciso }
13812c155d37SCarlos Alberto Enciso
printLocalNames(raw_ostream & OS,bool Full) const1382e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printLocalNames(raw_ostream &OS, bool Full) const {
1383e28b9357SCarlos Alberto Enciso if (!options().getPrintFormatting())
1384e28b9357SCarlos Alberto Enciso return;
1385e28b9357SCarlos Alberto Enciso
1386e28b9357SCarlos Alberto Enciso // Calculate an indentation value, to preserve a nice layout.
1387e28b9357SCarlos Alberto Enciso size_t Indentation = options().indentationSize() +
1388e28b9357SCarlos Alberto Enciso lineNumberAsString().length() +
1389e28b9357SCarlos Alberto Enciso indentAsString(getLevel() + 1).length() + 3;
1390e28b9357SCarlos Alberto Enciso
1391e28b9357SCarlos Alberto Enciso enum class Option { Directory, File };
1392e28b9357SCarlos Alberto Enciso auto PrintNames = [&](Option Action) {
1393e28b9357SCarlos Alberto Enciso StringRef Kind = Action == Option::Directory ? "Directory" : "File";
1394e28b9357SCarlos Alberto Enciso std::set<std::string> UniqueNames;
1395e28b9357SCarlos Alberto Enciso for (size_t Index : Filenames) {
1396e28b9357SCarlos Alberto Enciso // In the case of missing directory name in the .debug_line table,
1397e28b9357SCarlos Alberto Enciso // the returned string has a leading '/'.
1398e28b9357SCarlos Alberto Enciso StringRef Name = getStringPool().getString(Index);
1399e28b9357SCarlos Alberto Enciso size_t Pos = Name.rfind('/');
1400e28b9357SCarlos Alberto Enciso if (Pos != std::string::npos)
1401e28b9357SCarlos Alberto Enciso Name = (Action == Option::File) ? Name.substr(Pos + 1)
1402e28b9357SCarlos Alberto Enciso : Name.substr(0, Pos);
1403e28b9357SCarlos Alberto Enciso // Collect only unique names.
1404e28b9357SCarlos Alberto Enciso UniqueNames.insert(std::string(Name));
1405e28b9357SCarlos Alberto Enciso }
1406e28b9357SCarlos Alberto Enciso for (const std::string &Name : UniqueNames)
1407e28b9357SCarlos Alberto Enciso OS << std::string(Indentation, ' ') << formattedKind(Kind) << " "
1408e28b9357SCarlos Alberto Enciso << formattedName(Name) << "\n";
1409e28b9357SCarlos Alberto Enciso };
1410e28b9357SCarlos Alberto Enciso
1411e28b9357SCarlos Alberto Enciso if (options().getAttributeDirectories())
1412e28b9357SCarlos Alberto Enciso PrintNames(Option::Directory);
1413e28b9357SCarlos Alberto Enciso if (options().getAttributeFiles())
1414e28b9357SCarlos Alberto Enciso PrintNames(Option::File);
14154f06d46fSCarlos Alberto Enciso if (options().getAttributePublics()) {
14164f06d46fSCarlos Alberto Enciso StringRef Kind = "Public";
14174f06d46fSCarlos Alberto Enciso // The public names are indexed by 'LVScope *'. We want to print
14184f06d46fSCarlos Alberto Enciso // them by logical element address, to show the scopes layout.
14194f06d46fSCarlos Alberto Enciso using OffsetSorted = std::map<LVAddress, LVPublicNames::const_iterator>;
14204f06d46fSCarlos Alberto Enciso OffsetSorted SortedNames;
14214f06d46fSCarlos Alberto Enciso for (LVPublicNames::const_iterator Iter = PublicNames.begin();
14224f06d46fSCarlos Alberto Enciso Iter != PublicNames.end(); ++Iter)
14234f06d46fSCarlos Alberto Enciso SortedNames.emplace(Iter->first->getOffset(), Iter);
14244f06d46fSCarlos Alberto Enciso
14254f06d46fSCarlos Alberto Enciso LVPublicNames::const_iterator Iter;
14264f06d46fSCarlos Alberto Enciso for (OffsetSorted::reference Entry : SortedNames) {
14274f06d46fSCarlos Alberto Enciso Iter = Entry.second;
14284f06d46fSCarlos Alberto Enciso OS << std::string(Indentation, ' ') << formattedKind(Kind) << " "
14294f06d46fSCarlos Alberto Enciso << formattedName((*Iter).first->getName());
14304f06d46fSCarlos Alberto Enciso if (options().getAttributeOffset()) {
14314f06d46fSCarlos Alberto Enciso LVAddress Address = (*Iter).second.first;
14324f06d46fSCarlos Alberto Enciso size_t Size = (*Iter).second.second;
14334f06d46fSCarlos Alberto Enciso OS << " [" << hexString(Address) << ":" << hexString(Address + Size)
14344f06d46fSCarlos Alberto Enciso << "]";
14354f06d46fSCarlos Alberto Enciso }
14364f06d46fSCarlos Alberto Enciso OS << "\n";
14374f06d46fSCarlos Alberto Enciso }
14384f06d46fSCarlos Alberto Enciso }
1439e28b9357SCarlos Alberto Enciso }
1440e28b9357SCarlos Alberto Enciso
printWarnings(raw_ostream & OS,bool Full) const14412c155d37SCarlos Alberto Enciso void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const {
14422c155d37SCarlos Alberto Enciso auto PrintHeader = [&](const char *Header) { OS << "\n" << Header << ":\n"; };
14432c155d37SCarlos Alberto Enciso auto PrintFooter = [&](auto &Set) {
14442c155d37SCarlos Alberto Enciso if (Set.empty())
14452c155d37SCarlos Alberto Enciso OS << "None\n";
14462c155d37SCarlos Alberto Enciso };
14472c155d37SCarlos Alberto Enciso auto PrintOffset = [&](unsigned &Count, LVOffset Offset) {
14482c155d37SCarlos Alberto Enciso if (Count == 5) {
14492c155d37SCarlos Alberto Enciso Count = 0;
14502c155d37SCarlos Alberto Enciso OS << "\n";
14512c155d37SCarlos Alberto Enciso }
14522c155d37SCarlos Alberto Enciso ++Count;
14532c155d37SCarlos Alberto Enciso OS << hexSquareString(Offset) << " ";
14542c155d37SCarlos Alberto Enciso };
14552c155d37SCarlos Alberto Enciso auto PrintElement = [&](const LVOffsetElementMap &Map, LVOffset Offset) {
14562c155d37SCarlos Alberto Enciso LVOffsetElementMap::const_iterator Iter = Map.find(Offset);
14572c155d37SCarlos Alberto Enciso LVElement *Element = Iter != Map.end() ? Iter->second : nullptr;
14582c155d37SCarlos Alberto Enciso OS << "[" << hexString(Offset) << "]";
14592c155d37SCarlos Alberto Enciso if (Element)
14602c155d37SCarlos Alberto Enciso OS << " " << formattedKind(Element->kind()) << " "
14612c155d37SCarlos Alberto Enciso << formattedName(Element->getName());
14622c155d37SCarlos Alberto Enciso OS << "\n";
14632c155d37SCarlos Alberto Enciso };
14642c155d37SCarlos Alberto Enciso auto PrintInvalidLocations = [&](const LVOffsetLocationsMap &Map,
14652c155d37SCarlos Alberto Enciso const char *Header) {
14662c155d37SCarlos Alberto Enciso PrintHeader(Header);
14672c155d37SCarlos Alberto Enciso for (LVOffsetLocationsMap::const_reference Entry : Map) {
14682c155d37SCarlos Alberto Enciso PrintElement(WarningOffsets, Entry.first);
14697fbcc244SCarlos Alberto Enciso for (const LVLocation *Location : Entry.second)
14702c155d37SCarlos Alberto Enciso OS << hexSquareString(Location->getOffset()) << " "
14712c155d37SCarlos Alberto Enciso << Location->getIntervalInfo() << "\n";
14722c155d37SCarlos Alberto Enciso }
14732c155d37SCarlos Alberto Enciso PrintFooter(Map);
14742c155d37SCarlos Alberto Enciso };
14752c155d37SCarlos Alberto Enciso
14762c155d37SCarlos Alberto Enciso if (options().getInternalTag() && getReader().isBinaryTypeELF()) {
14772c155d37SCarlos Alberto Enciso PrintHeader("Unsupported DWARF Tags");
14782c155d37SCarlos Alberto Enciso for (LVTagOffsetsMap::const_reference Entry : DebugTags) {
14792c155d37SCarlos Alberto Enciso OS << format("\n0x%02x", (unsigned)Entry.first) << ", "
14802c155d37SCarlos Alberto Enciso << dwarf::TagString(Entry.first) << "\n";
14812c155d37SCarlos Alberto Enciso unsigned Count = 0;
14827fbcc244SCarlos Alberto Enciso for (const LVOffset &Offset : Entry.second)
14832c155d37SCarlos Alberto Enciso PrintOffset(Count, Offset);
14842c155d37SCarlos Alberto Enciso OS << "\n";
14852c155d37SCarlos Alberto Enciso }
14862c155d37SCarlos Alberto Enciso PrintFooter(DebugTags);
14872c155d37SCarlos Alberto Enciso }
14882c155d37SCarlos Alberto Enciso
14892c155d37SCarlos Alberto Enciso if (options().getWarningCoverages()) {
14902c155d37SCarlos Alberto Enciso PrintHeader("Symbols Invalid Coverages");
14912c155d37SCarlos Alberto Enciso for (LVOffsetSymbolMap::const_reference Entry : InvalidCoverages) {
14922c155d37SCarlos Alberto Enciso // Symbol basic information.
14932c155d37SCarlos Alberto Enciso LVSymbol *Symbol = Entry.second;
14942c155d37SCarlos Alberto Enciso OS << hexSquareString(Entry.first) << " {Coverage} "
14952c155d37SCarlos Alberto Enciso << format("%.2f%%", Symbol->getCoveragePercentage()) << " "
14962c155d37SCarlos Alberto Enciso << formattedKind(Symbol->kind()) << " "
14972c155d37SCarlos Alberto Enciso << formattedName(Symbol->getName()) << "\n";
14982c155d37SCarlos Alberto Enciso }
14992c155d37SCarlos Alberto Enciso PrintFooter(InvalidCoverages);
15002c155d37SCarlos Alberto Enciso }
15012c155d37SCarlos Alberto Enciso
15022c155d37SCarlos Alberto Enciso if (options().getWarningLines()) {
15032c155d37SCarlos Alberto Enciso PrintHeader("Lines Zero References");
15042c155d37SCarlos Alberto Enciso for (LVOffsetLinesMap::const_reference Entry : LinesZero) {
15052c155d37SCarlos Alberto Enciso PrintElement(WarningOffsets, Entry.first);
15062c155d37SCarlos Alberto Enciso unsigned Count = 0;
15077fbcc244SCarlos Alberto Enciso for (const LVLine *Line : Entry.second)
15082c155d37SCarlos Alberto Enciso PrintOffset(Count, Line->getOffset());
15092c155d37SCarlos Alberto Enciso OS << "\n";
15102c155d37SCarlos Alberto Enciso }
15112c155d37SCarlos Alberto Enciso PrintFooter(LinesZero);
15122c155d37SCarlos Alberto Enciso }
15132c155d37SCarlos Alberto Enciso
15142c155d37SCarlos Alberto Enciso if (options().getWarningLocations())
15152c155d37SCarlos Alberto Enciso PrintInvalidLocations(InvalidLocations, "Invalid Location Ranges");
15162c155d37SCarlos Alberto Enciso
15172c155d37SCarlos Alberto Enciso if (options().getWarningRanges())
15182c155d37SCarlos Alberto Enciso PrintInvalidLocations(InvalidRanges, "Invalid Code Ranges");
15192c155d37SCarlos Alberto Enciso }
15202c155d37SCarlos Alberto Enciso
printTotals(raw_ostream & OS) const1521e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printTotals(raw_ostream &OS) const {
1522e28b9357SCarlos Alberto Enciso OS << "\nTotals by lexical level:\n";
1523e28b9357SCarlos Alberto Enciso for (size_t Index = 1; Index <= MaxSeenLevel; ++Index)
1524e28b9357SCarlos Alberto Enciso OS << format("[%03d]: %10d (%6.2f%%)\n", Index, Totals[Index].first,
1525e28b9357SCarlos Alberto Enciso Totals[Index].second);
1526e28b9357SCarlos Alberto Enciso }
1527e28b9357SCarlos Alberto Enciso
printScopeSize(const LVScope * Scope,raw_ostream & OS)1528e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printScopeSize(const LVScope *Scope, raw_ostream &OS) {
1529e28b9357SCarlos Alberto Enciso LVSizesMap::const_iterator Iter = Sizes.find(Scope);
1530e28b9357SCarlos Alberto Enciso if (Iter != Sizes.end()) {
1531e28b9357SCarlos Alberto Enciso LVOffset Size = Iter->second;
1532e28b9357SCarlos Alberto Enciso assert(CUContributionSize && "Invalid CU contribution size.");
1533e28b9357SCarlos Alberto Enciso // Get a percentage rounded to two decimal digits. This avoids
1534e28b9357SCarlos Alberto Enciso // implementation-defined rounding inside printing functions.
1535e28b9357SCarlos Alberto Enciso float Percentage =
1536e28b9357SCarlos Alberto Enciso rint((float(Size) / CUContributionSize) * 100.0 * 100.0) / 100.0;
15377292d051SMichał Górny OS << format("%10" PRId64 " (%6.2f%%) : ", Size, Percentage);
1538e28b9357SCarlos Alberto Enciso Scope->print(OS);
1539e28b9357SCarlos Alberto Enciso
1540e28b9357SCarlos Alberto Enciso // Keep record of the total sizes at each lexical level.
1541e28b9357SCarlos Alberto Enciso LVLevel Level = Scope->getLevel();
1542e28b9357SCarlos Alberto Enciso if (Level > MaxSeenLevel)
1543e28b9357SCarlos Alberto Enciso MaxSeenLevel = Level;
1544e28b9357SCarlos Alberto Enciso if (Level >= Totals.size())
1545e28b9357SCarlos Alberto Enciso Totals.resize(2 * Level);
1546e28b9357SCarlos Alberto Enciso Totals[Level].first += Size;
1547e28b9357SCarlos Alberto Enciso Totals[Level].second += Percentage;
1548e28b9357SCarlos Alberto Enciso }
1549e28b9357SCarlos Alberto Enciso }
1550e28b9357SCarlos Alberto Enciso
printSizes(raw_ostream & OS) const1551e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printSizes(raw_ostream &OS) const {
1552e28b9357SCarlos Alberto Enciso // Recursively print the contributions for each scope.
1553e28b9357SCarlos Alberto Enciso std::function<void(const LVScope *Scope)> PrintScope =
1554e28b9357SCarlos Alberto Enciso [&](const LVScope *Scope) {
15550332a8e7SCarlos Alberto Enciso // If we have selection criteria, then use only the selected scopes.
15560332a8e7SCarlos Alberto Enciso if (options().getSelectExecute() && options().getReportAnyView()) {
15570332a8e7SCarlos Alberto Enciso for (const LVScope *Scope : MatchedScopes)
15580332a8e7SCarlos Alberto Enciso if (Scope->getLevel() < options().getOutputLevel())
15590332a8e7SCarlos Alberto Enciso printScopeSize(Scope, OS);
15600332a8e7SCarlos Alberto Enciso return;
15610332a8e7SCarlos Alberto Enciso }
1562e28b9357SCarlos Alberto Enciso if (Scope->getLevel() < options().getOutputLevel()) {
1563e28b9357SCarlos Alberto Enciso if (const LVScopes *Scopes = Scope->getScopes())
1564e28b9357SCarlos Alberto Enciso for (const LVScope *Scope : *Scopes) {
1565e28b9357SCarlos Alberto Enciso printScopeSize(Scope, OS);
1566e28b9357SCarlos Alberto Enciso PrintScope(Scope);
1567e28b9357SCarlos Alberto Enciso }
1568e28b9357SCarlos Alberto Enciso }
1569e28b9357SCarlos Alberto Enciso };
1570e28b9357SCarlos Alberto Enciso
1571e28b9357SCarlos Alberto Enciso bool PrintScopes = options().getPrintScopes();
1572e28b9357SCarlos Alberto Enciso if (!PrintScopes)
1573e28b9357SCarlos Alberto Enciso options().setPrintScopes();
1574e28b9357SCarlos Alberto Enciso getReader().setCompileUnit(const_cast<LVScopeCompileUnit *>(this));
1575e28b9357SCarlos Alberto Enciso
1576e28b9357SCarlos Alberto Enciso OS << "\nScope Sizes:\n";
1577e28b9357SCarlos Alberto Enciso options().resetPrintFormatting();
1578e28b9357SCarlos Alberto Enciso options().setPrintOffset();
1579e28b9357SCarlos Alberto Enciso
1580e28b9357SCarlos Alberto Enciso // Print the scopes regardless if the user has requested any scopes
1581e28b9357SCarlos Alberto Enciso // printing. Set the option just to allow printing the contributions.
1582e28b9357SCarlos Alberto Enciso printScopeSize(this, OS);
1583e28b9357SCarlos Alberto Enciso PrintScope(this);
1584e28b9357SCarlos Alberto Enciso
1585e28b9357SCarlos Alberto Enciso // Print total scope sizes by level.
1586e28b9357SCarlos Alberto Enciso printTotals(OS);
1587e28b9357SCarlos Alberto Enciso
1588e28b9357SCarlos Alberto Enciso options().resetPrintOffset();
1589e28b9357SCarlos Alberto Enciso options().setPrintFormatting();
1590e28b9357SCarlos Alberto Enciso
1591e28b9357SCarlos Alberto Enciso if (!PrintScopes)
1592e28b9357SCarlos Alberto Enciso options().resetPrintScopes();
1593e28b9357SCarlos Alberto Enciso }
1594e28b9357SCarlos Alberto Enciso
printSummary(raw_ostream & OS) const1595e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printSummary(raw_ostream &OS) const {
15960332a8e7SCarlos Alberto Enciso printSummary(OS, options().getSelectExecute() ? Found : Printed, "Printed");
1597e28b9357SCarlos Alberto Enciso }
1598e28b9357SCarlos Alberto Enciso
1599e28b9357SCarlos Alberto Enciso // Print summary details for the scopes tree.
printSummary(raw_ostream & OS,const LVCounter & Counter,const char * Header) const1600e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printSummary(raw_ostream &OS, const LVCounter &Counter,
1601e28b9357SCarlos Alberto Enciso const char *Header) const {
1602e28b9357SCarlos Alberto Enciso std::string Separator = std::string(29, '-');
1603e28b9357SCarlos Alberto Enciso auto PrintSeparator = [&]() { OS << Separator << "\n"; };
1604e28b9357SCarlos Alberto Enciso auto PrintHeadingRow = [&](const char *T, const char *U, const char *V) {
1605e28b9357SCarlos Alberto Enciso OS << format("%-9s%9s %9s\n", T, U, V);
1606e28b9357SCarlos Alberto Enciso };
1607e28b9357SCarlos Alberto Enciso auto PrintDataRow = [&](const char *T, unsigned U, unsigned V) {
1608e28b9357SCarlos Alberto Enciso OS << format("%-9s%9d %9d\n", T, U, V);
1609e28b9357SCarlos Alberto Enciso };
1610e28b9357SCarlos Alberto Enciso
1611e28b9357SCarlos Alberto Enciso OS << "\n";
1612e28b9357SCarlos Alberto Enciso PrintSeparator();
1613e28b9357SCarlos Alberto Enciso PrintHeadingRow("Element", "Total", Header);
1614e28b9357SCarlos Alberto Enciso PrintSeparator();
1615e28b9357SCarlos Alberto Enciso PrintDataRow("Scopes", Allocated.Scopes, Counter.Scopes);
1616e28b9357SCarlos Alberto Enciso PrintDataRow("Symbols", Allocated.Symbols, Counter.Symbols);
1617e28b9357SCarlos Alberto Enciso PrintDataRow("Types", Allocated.Types, Counter.Types);
1618e28b9357SCarlos Alberto Enciso PrintDataRow("Lines", Allocated.Lines, Counter.Lines);
1619e28b9357SCarlos Alberto Enciso PrintSeparator();
1620e28b9357SCarlos Alberto Enciso PrintDataRow(
1621e28b9357SCarlos Alberto Enciso "Total",
1622e28b9357SCarlos Alberto Enciso Allocated.Scopes + Allocated.Symbols + Allocated.Lines + Allocated.Types,
1623e28b9357SCarlos Alberto Enciso Counter.Scopes + Counter.Symbols + Counter.Lines + Counter.Types);
1624e28b9357SCarlos Alberto Enciso }
1625e28b9357SCarlos Alberto Enciso
printMatchedElements(raw_ostream & OS,bool UseMatchedElements)1626e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printMatchedElements(raw_ostream &OS,
1627e28b9357SCarlos Alberto Enciso bool UseMatchedElements) {
1628e28b9357SCarlos Alberto Enciso LVSortFunction SortFunction = getSortFunction();
1629e28b9357SCarlos Alberto Enciso if (SortFunction)
1630e28b9357SCarlos Alberto Enciso std::stable_sort(MatchedElements.begin(), MatchedElements.end(),
1631e28b9357SCarlos Alberto Enciso SortFunction);
1632e28b9357SCarlos Alberto Enciso
1633e28b9357SCarlos Alberto Enciso // Check the type of elements required to be printed. 'MatchedElements'
1634e28b9357SCarlos Alberto Enciso // contains generic elements (lines, scopes, symbols, types). If we have a
1635e28b9357SCarlos Alberto Enciso // request to print any generic element, then allow the normal printing.
1636e28b9357SCarlos Alberto Enciso if (options().getPrintAnyElement()) {
1637e28b9357SCarlos Alberto Enciso if (UseMatchedElements)
1638e28b9357SCarlos Alberto Enciso OS << "\n";
1639e28b9357SCarlos Alberto Enciso print(OS);
1640e28b9357SCarlos Alberto Enciso
1641e28b9357SCarlos Alberto Enciso if (UseMatchedElements) {
1642e28b9357SCarlos Alberto Enciso // Print the details for the matched elements.
1643e28b9357SCarlos Alberto Enciso for (const LVElement *Element : MatchedElements)
1644e28b9357SCarlos Alberto Enciso Element->print(OS);
1645e28b9357SCarlos Alberto Enciso } else {
1646e28b9357SCarlos Alberto Enciso // Print the view for the matched scopes.
1647e28b9357SCarlos Alberto Enciso for (const LVScope *Scope : MatchedScopes) {
1648e28b9357SCarlos Alberto Enciso Scope->print(OS);
1649e28b9357SCarlos Alberto Enciso if (const LVElements *Elements = Scope->getChildren())
1650e28b9357SCarlos Alberto Enciso for (LVElement *Element : *Elements)
1651e28b9357SCarlos Alberto Enciso Element->print(OS);
1652e28b9357SCarlos Alberto Enciso }
1653e28b9357SCarlos Alberto Enciso }
1654e28b9357SCarlos Alberto Enciso
1655e28b9357SCarlos Alberto Enciso // Print any requested summary.
1656e28b9357SCarlos Alberto Enciso if (options().getPrintSummary()) {
1657e28b9357SCarlos Alberto Enciso // In the case of '--report=details' the matched elements are
1658e28b9357SCarlos Alberto Enciso // already counted; just proceed to print any requested summary.
1659e28b9357SCarlos Alberto Enciso // Otherwise, count them and print the summary.
1660e28b9357SCarlos Alberto Enciso if (!options().getReportList()) {
1661e28b9357SCarlos Alberto Enciso for (LVElement *Element : MatchedElements) {
1662e28b9357SCarlos Alberto Enciso if (!Element->getIncludeInPrint())
1663e28b9357SCarlos Alberto Enciso continue;
1664e28b9357SCarlos Alberto Enciso if (Element->getIsType())
1665e28b9357SCarlos Alberto Enciso ++Found.Types;
1666e28b9357SCarlos Alberto Enciso else if (Element->getIsSymbol())
1667e28b9357SCarlos Alberto Enciso ++Found.Symbols;
1668e28b9357SCarlos Alberto Enciso else if (Element->getIsScope())
1669e28b9357SCarlos Alberto Enciso ++Found.Scopes;
1670e28b9357SCarlos Alberto Enciso else if (Element->getIsLine())
1671e28b9357SCarlos Alberto Enciso ++Found.Lines;
1672e28b9357SCarlos Alberto Enciso else
1673e28b9357SCarlos Alberto Enciso assert(Element && "Invalid element.");
1674e28b9357SCarlos Alberto Enciso }
1675e28b9357SCarlos Alberto Enciso }
1676e28b9357SCarlos Alberto Enciso printSummary(OS, Found, "Printed");
1677e28b9357SCarlos Alberto Enciso }
1678e28b9357SCarlos Alberto Enciso }
1679e28b9357SCarlos Alberto Enciso
1680e28b9357SCarlos Alberto Enciso // Check if we have a request to print sizes for the matched elements
1681e28b9357SCarlos Alberto Enciso // that are scopes.
1682e28b9357SCarlos Alberto Enciso if (options().getPrintSizes()) {
1683e28b9357SCarlos Alberto Enciso OS << "\n";
1684e28b9357SCarlos Alberto Enciso print(OS);
1685e28b9357SCarlos Alberto Enciso
1686e28b9357SCarlos Alberto Enciso OS << "\nScope Sizes:\n";
1687e28b9357SCarlos Alberto Enciso printScopeSize(this, OS);
1688e28b9357SCarlos Alberto Enciso for (LVElement *Element : MatchedElements)
1689e28b9357SCarlos Alberto Enciso if (Element->getIsScope())
1690e28b9357SCarlos Alberto Enciso // Print sizes only for scopes.
1691e28b9357SCarlos Alberto Enciso printScopeSize(static_cast<LVScope *>(Element), OS);
1692e28b9357SCarlos Alberto Enciso
1693e28b9357SCarlos Alberto Enciso printTotals(OS);
1694e28b9357SCarlos Alberto Enciso }
1695e28b9357SCarlos Alberto Enciso }
1696e28b9357SCarlos Alberto Enciso
print(raw_ostream & OS,bool Full) const1697e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::print(raw_ostream &OS, bool Full) const {
1698e28b9357SCarlos Alberto Enciso // Reset counters for printed and found elements.
1699e28b9357SCarlos Alberto Enciso const_cast<LVScopeCompileUnit *>(this)->Found.reset();
1700e28b9357SCarlos Alberto Enciso const_cast<LVScopeCompileUnit *>(this)->Printed.reset();
1701e28b9357SCarlos Alberto Enciso
1702e28b9357SCarlos Alberto Enciso if (getReader().doPrintScope(this) && options().getPrintFormatting())
1703e28b9357SCarlos Alberto Enciso OS << "\n";
1704e28b9357SCarlos Alberto Enciso
1705e28b9357SCarlos Alberto Enciso LVScope::print(OS, Full);
1706e28b9357SCarlos Alberto Enciso }
1707e28b9357SCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1708e28b9357SCarlos Alberto Enciso void LVScopeCompileUnit::printExtra(raw_ostream &OS, bool Full) const {
1709e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " '" << getName() << "'\n";
1710e28b9357SCarlos Alberto Enciso if (options().getPrintFormatting() && options().getAttributeProducer())
1711e28b9357SCarlos Alberto Enciso printAttributes(OS, Full, "{Producer} ",
1712e28b9357SCarlos Alberto Enciso const_cast<LVScopeCompileUnit *>(this), getProducer(),
1713e28b9357SCarlos Alberto Enciso /*UseQuotes=*/true,
1714e28b9357SCarlos Alberto Enciso /*PrintRef=*/false);
1715e28b9357SCarlos Alberto Enciso
1716e28b9357SCarlos Alberto Enciso // Reset file index, to allow its children to print the correct filename.
1717e28b9357SCarlos Alberto Enciso options().resetFilenameIndex();
1718e28b9357SCarlos Alberto Enciso
17193c397c90SCarlos Alberto Enciso // Print any files, directories, public names and active ranges.
1720e28b9357SCarlos Alberto Enciso if (Full) {
1721e28b9357SCarlos Alberto Enciso printLocalNames(OS, Full);
17223c397c90SCarlos Alberto Enciso printActiveRanges(OS, Full);
1723e28b9357SCarlos Alberto Enciso }
1724e28b9357SCarlos Alberto Enciso }
1725e28b9357SCarlos Alberto Enciso
1726e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1727e28b9357SCarlos Alberto Enciso // DWARF enumeration (DW_TAG_enumeration_type).
1728e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1729e98a4c5aSCarlos Alberto Enciso bool LVScopeEnumeration::equals(const LVScope *Scope) const {
1730e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1731e98a4c5aSCarlos Alberto Enciso return false;
1732e98a4c5aSCarlos Alberto Enciso return equalNumberOfChildren(Scope);
1733e98a4c5aSCarlos Alberto Enciso }
1734e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1735e28b9357SCarlos Alberto Enciso void LVScopeEnumeration::printExtra(raw_ostream &OS, bool Full) const {
1736e28b9357SCarlos Alberto Enciso // Print the full type name.
1737e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << (getIsEnumClass() ? "class " : "")
1738e28b9357SCarlos Alberto Enciso << formattedName(getName());
1739e28b9357SCarlos Alberto Enciso if (getHasType())
1740e28b9357SCarlos Alberto Enciso OS << " -> " << typeOffsetAsString()
1741e28b9357SCarlos Alberto Enciso << formattedNames(getTypeQualifiedName(), typeAsString());
1742e28b9357SCarlos Alberto Enciso OS << "\n";
1743e28b9357SCarlos Alberto Enciso }
1744e28b9357SCarlos Alberto Enciso
1745e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1746e28b9357SCarlos Alberto Enciso // DWARF formal parameter pack (DW_TAG_GNU_formal_parameter_pack).
1747e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1748e98a4c5aSCarlos Alberto Enciso bool LVScopeFormalPack::equals(const LVScope *Scope) const {
1749e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1750e98a4c5aSCarlos Alberto Enciso return false;
1751e98a4c5aSCarlos Alberto Enciso return equalNumberOfChildren(Scope);
1752e98a4c5aSCarlos Alberto Enciso }
1753e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1754e28b9357SCarlos Alberto Enciso void LVScopeFormalPack::printExtra(raw_ostream &OS, bool Full) const {
1755e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
1756e28b9357SCarlos Alberto Enciso }
1757e28b9357SCarlos Alberto Enciso
1758e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1759e28b9357SCarlos Alberto Enciso // DWARF function.
1760e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
resolveReferences()1761e28b9357SCarlos Alberto Enciso void LVScopeFunction::resolveReferences() {
1762e28b9357SCarlos Alberto Enciso // Before we resolve any references to other elements, check if we have
1763e28b9357SCarlos Alberto Enciso // to insert missing elements, that have been stripped, which will help
1764e28b9357SCarlos Alberto Enciso // the logical view comparison.
1765e28b9357SCarlos Alberto Enciso if (options().getAttributeInserted() && getHasReferenceAbstract() &&
1766e28b9357SCarlos Alberto Enciso !getAddedMissing()) {
1767e28b9357SCarlos Alberto Enciso // Add missing elements at the function scope.
1768e28b9357SCarlos Alberto Enciso addMissingElements(getReference());
1769e28b9357SCarlos Alberto Enciso if (Scopes)
1770e28b9357SCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
1771e28b9357SCarlos Alberto Enciso if (Scope->getHasReferenceAbstract() && !Scope->getAddedMissing())
1772e28b9357SCarlos Alberto Enciso Scope->addMissingElements(Scope->getReference());
1773e28b9357SCarlos Alberto Enciso }
1774e28b9357SCarlos Alberto Enciso
1775e28b9357SCarlos Alberto Enciso LVScope::resolveReferences();
1776e28b9357SCarlos Alberto Enciso
1777e28b9357SCarlos Alberto Enciso // The DWARF 'extern' attribute is generated at the class level.
1778e28b9357SCarlos Alberto Enciso // 0000003f DW_TAG_class_type "CLASS"
1779e28b9357SCarlos Alberto Enciso // 00000048 DW_TAG_subprogram "bar"
1780e28b9357SCarlos Alberto Enciso // DW_AT_external DW_FORM_flag_present
1781e28b9357SCarlos Alberto Enciso // 00000070 DW_TAG_subprogram "bar"
1782e28b9357SCarlos Alberto Enciso // DW_AT_specification DW_FORM_ref4 0x00000048
1783e7950fceSCarlos Alberto Enciso // CodeView does not include any information at the class level to
1784e7950fceSCarlos Alberto Enciso // mark the member function as external.
1785e28b9357SCarlos Alberto Enciso // If there is a reference linking the declaration and definition, mark
1786e28b9357SCarlos Alberto Enciso // the definition as extern, to facilitate the logical view comparison.
1787e28b9357SCarlos Alberto Enciso if (getHasReferenceSpecification()) {
1788e28b9357SCarlos Alberto Enciso LVScope *Reference = getReference();
1789e28b9357SCarlos Alberto Enciso if (Reference && Reference->getIsExternal()) {
1790e28b9357SCarlos Alberto Enciso Reference->resetIsExternal();
1791e28b9357SCarlos Alberto Enciso setIsExternal();
1792e28b9357SCarlos Alberto Enciso }
1793e28b9357SCarlos Alberto Enciso }
1794e28b9357SCarlos Alberto Enciso
1795e28b9357SCarlos Alberto Enciso // Resolve the function associated type.
1796e28b9357SCarlos Alberto Enciso if (!getType())
1797e28b9357SCarlos Alberto Enciso if (LVScope *Reference = getReference())
1798e28b9357SCarlos Alberto Enciso setType(Reference->getType());
1799e28b9357SCarlos Alberto Enciso }
1800e28b9357SCarlos Alberto Enciso
setName(StringRef ObjectName)1801e28b9357SCarlos Alberto Enciso void LVScopeFunction::setName(StringRef ObjectName) {
1802e28b9357SCarlos Alberto Enciso LVScope::setName(ObjectName);
1803e28b9357SCarlos Alberto Enciso // Check for system generated functions.
1804e28b9357SCarlos Alberto Enciso getReader().isSystemEntry(this, ObjectName);
1805e28b9357SCarlos Alberto Enciso }
1806e28b9357SCarlos Alberto Enciso
resolveExtra()1807e28b9357SCarlos Alberto Enciso void LVScopeFunction::resolveExtra() {
1808e28b9357SCarlos Alberto Enciso // Check if we need to encode the template arguments.
1809e28b9357SCarlos Alberto Enciso if (getIsTemplate())
1810e28b9357SCarlos Alberto Enciso resolveTemplate();
1811e28b9357SCarlos Alberto Enciso }
1812e28b9357SCarlos Alberto Enciso
equals(const LVScope * Scope) const1813e98a4c5aSCarlos Alberto Enciso bool LVScopeFunction::equals(const LVScope *Scope) const {
1814e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1815e98a4c5aSCarlos Alberto Enciso return false;
1816e98a4c5aSCarlos Alberto Enciso
1817e98a4c5aSCarlos Alberto Enciso // When comparing logical elements, ignore any difference in the children.
1818e98a4c5aSCarlos Alberto Enciso if (options().getCompareContext() && !equalNumberOfChildren(Scope))
1819e98a4c5aSCarlos Alberto Enciso return false;
1820e98a4c5aSCarlos Alberto Enciso
1821e98a4c5aSCarlos Alberto Enciso // Check if the linkage name matches.
1822e98a4c5aSCarlos Alberto Enciso if (getLinkageNameIndex() != Scope->getLinkageNameIndex())
1823e98a4c5aSCarlos Alberto Enciso return false;
1824e98a4c5aSCarlos Alberto Enciso
1825e98a4c5aSCarlos Alberto Enciso // Check if the parameters match in the case of templates.
1826e98a4c5aSCarlos Alberto Enciso if (!LVType::parametersMatch(getTypes(), Scope->getTypes()))
1827e98a4c5aSCarlos Alberto Enciso return false;
1828e98a4c5aSCarlos Alberto Enciso
1829e98a4c5aSCarlos Alberto Enciso // Check if the arguments match.
1830e98a4c5aSCarlos Alberto Enciso if (!LVSymbol::parametersMatch(getSymbols(), Scope->getSymbols()))
1831e98a4c5aSCarlos Alberto Enciso return false;
1832e98a4c5aSCarlos Alberto Enciso
1833e98a4c5aSCarlos Alberto Enciso // Check if the lines match.
1834e98a4c5aSCarlos Alberto Enciso if (options().getCompareLines() &&
1835e98a4c5aSCarlos Alberto Enciso !LVLine::equals(getLines(), Scope->getLines()))
1836e98a4c5aSCarlos Alberto Enciso return false;
1837e98a4c5aSCarlos Alberto Enciso
1838e98a4c5aSCarlos Alberto Enciso // Check if any reference is the same.
1839e98a4c5aSCarlos Alberto Enciso if (!referenceMatch(Scope))
1840e98a4c5aSCarlos Alberto Enciso return false;
1841e98a4c5aSCarlos Alberto Enciso
1842e98a4c5aSCarlos Alberto Enciso if (getReference() && !getReference()->equals(Scope->getReference()))
1843e98a4c5aSCarlos Alberto Enciso return false;
1844e98a4c5aSCarlos Alberto Enciso
1845e98a4c5aSCarlos Alberto Enciso return true;
1846e98a4c5aSCarlos Alberto Enciso }
1847e98a4c5aSCarlos Alberto Enciso
findEqualScope(const LVScopes * Scopes) const1848e98a4c5aSCarlos Alberto Enciso LVScope *LVScopeFunction::findEqualScope(const LVScopes *Scopes) const {
1849e98a4c5aSCarlos Alberto Enciso assert(Scopes && "Scopes must not be nullptr");
1850e98a4c5aSCarlos Alberto Enciso // Go through candidates and try to find a best match.
1851e98a4c5aSCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
1852e98a4c5aSCarlos Alberto Enciso // Match arguments, children, lines, references.
1853e98a4c5aSCarlos Alberto Enciso if (equals(Scope))
1854e98a4c5aSCarlos Alberto Enciso return Scope;
1855e98a4c5aSCarlos Alberto Enciso return nullptr;
1856e98a4c5aSCarlos Alberto Enciso }
1857e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1858e28b9357SCarlos Alberto Enciso void LVScopeFunction::printExtra(raw_ostream &OS, bool Full) const {
1859e28b9357SCarlos Alberto Enciso LVScope *Reference = getReference();
1860e28b9357SCarlos Alberto Enciso
1861e28b9357SCarlos Alberto Enciso // Inline attributes based on the reference element.
1862e28b9357SCarlos Alberto Enciso uint32_t InlineCode =
1863e28b9357SCarlos Alberto Enciso Reference ? Reference->getInlineCode() : getInlineCode();
1864e28b9357SCarlos Alberto Enciso
1865e28b9357SCarlos Alberto Enciso // Accessibility depends on the parent (class, structure).
1866e28b9357SCarlos Alberto Enciso uint32_t AccessCode = 0;
1867e28b9357SCarlos Alberto Enciso if (getIsMember())
1868e28b9357SCarlos Alberto Enciso AccessCode = getParentScope()->getIsClass() ? dwarf::DW_ACCESS_private
1869e28b9357SCarlos Alberto Enciso : dwarf::DW_ACCESS_public;
1870e28b9357SCarlos Alberto Enciso
1871e28b9357SCarlos Alberto Enciso std::string Attributes =
1872e28b9357SCarlos Alberto Enciso getIsCallSite()
1873e28b9357SCarlos Alberto Enciso ? ""
1874e28b9357SCarlos Alberto Enciso : formatAttributes(externalString(), accessibilityString(AccessCode),
1875e28b9357SCarlos Alberto Enciso inlineCodeString(InlineCode), virtualityString());
1876e28b9357SCarlos Alberto Enciso
1877e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << Attributes << formattedName(getName())
1878e28b9357SCarlos Alberto Enciso << discriminatorAsString() << " -> " << typeOffsetAsString()
1879e28b9357SCarlos Alberto Enciso << formattedNames(getTypeQualifiedName(), typeAsString()) << "\n";
1880e28b9357SCarlos Alberto Enciso
1881e28b9357SCarlos Alberto Enciso // Print any active ranges.
1882e28b9357SCarlos Alberto Enciso if (Full) {
1883e28b9357SCarlos Alberto Enciso if (getIsTemplateResolved())
1884e28b9357SCarlos Alberto Enciso printEncodedArgs(OS, Full);
18853c397c90SCarlos Alberto Enciso printActiveRanges(OS, Full);
18864f06d46fSCarlos Alberto Enciso if (getLinkageNameIndex())
18874f06d46fSCarlos Alberto Enciso printLinkageName(OS, Full, const_cast<LVScopeFunction *>(this),
18884f06d46fSCarlos Alberto Enciso const_cast<LVScopeFunction *>(this));
1889e28b9357SCarlos Alberto Enciso if (Reference)
1890e28b9357SCarlos Alberto Enciso Reference->printReference(OS, Full, const_cast<LVScopeFunction *>(this));
1891e28b9357SCarlos Alberto Enciso }
1892e28b9357SCarlos Alberto Enciso }
1893e28b9357SCarlos Alberto Enciso
1894e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1895e28b9357SCarlos Alberto Enciso // DWARF inlined function (DW_TAG_inlined_function).
1896e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
resolveExtra()1897e28b9357SCarlos Alberto Enciso void LVScopeFunctionInlined::resolveExtra() {
1898e28b9357SCarlos Alberto Enciso // Check if we need to encode the template arguments.
1899e28b9357SCarlos Alberto Enciso if (getIsTemplate())
1900e28b9357SCarlos Alberto Enciso resolveTemplate();
1901e28b9357SCarlos Alberto Enciso }
1902e28b9357SCarlos Alberto Enciso
equals(const LVScope * Scope) const1903e98a4c5aSCarlos Alberto Enciso bool LVScopeFunctionInlined::equals(const LVScope *Scope) const {
1904e98a4c5aSCarlos Alberto Enciso if (!LVScopeFunction::equals(Scope))
1905e98a4c5aSCarlos Alberto Enciso return false;
1906e98a4c5aSCarlos Alberto Enciso
1907e98a4c5aSCarlos Alberto Enciso // Check if any reference is the same.
1908e98a4c5aSCarlos Alberto Enciso if (getHasDiscriminator() && Scope->getHasDiscriminator())
1909e98a4c5aSCarlos Alberto Enciso if (getDiscriminator() != Scope->getDiscriminator())
1910e98a4c5aSCarlos Alberto Enciso return false;
1911e98a4c5aSCarlos Alberto Enciso
1912e98a4c5aSCarlos Alberto Enciso // Check the call site information.
1913e98a4c5aSCarlos Alberto Enciso if (getCallFilenameIndex() != Scope->getCallFilenameIndex() ||
1914e98a4c5aSCarlos Alberto Enciso getCallLineNumber() != Scope->getCallLineNumber())
1915e98a4c5aSCarlos Alberto Enciso return false;
1916e98a4c5aSCarlos Alberto Enciso
1917e98a4c5aSCarlos Alberto Enciso return true;
1918e98a4c5aSCarlos Alberto Enciso }
1919e98a4c5aSCarlos Alberto Enciso
findEqualScope(const LVScopes * Scopes) const1920e98a4c5aSCarlos Alberto Enciso LVScope *LVScopeFunctionInlined::findEqualScope(const LVScopes *Scopes) const {
1921e98a4c5aSCarlos Alberto Enciso return LVScopeFunction::findEqualScope(Scopes);
1922e98a4c5aSCarlos Alberto Enciso }
1923e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1924e28b9357SCarlos Alberto Enciso void LVScopeFunctionInlined::printExtra(raw_ostream &OS, bool Full) const {
1925e28b9357SCarlos Alberto Enciso LVScopeFunction::printExtra(OS, Full);
1926e28b9357SCarlos Alberto Enciso }
1927e28b9357SCarlos Alberto Enciso
1928e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1929e28b9357SCarlos Alberto Enciso // DWARF subroutine type.
1930e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1931e28b9357SCarlos Alberto Enciso // Resolve a Subroutine Type (Callback).
resolveExtra()1932e28b9357SCarlos Alberto Enciso void LVScopeFunctionType::resolveExtra() {
1933e28b9357SCarlos Alberto Enciso if (getIsMemberPointerResolved())
1934e28b9357SCarlos Alberto Enciso return;
1935e28b9357SCarlos Alberto Enciso setIsMemberPointerResolved();
1936e28b9357SCarlos Alberto Enciso
1937e28b9357SCarlos Alberto Enciso // The encoded string has the return type and the formal parameters type.
1938e28b9357SCarlos Alberto Enciso std::string Name(typeAsString());
1939e28b9357SCarlos Alberto Enciso Name.append(" (*)");
1940e28b9357SCarlos Alberto Enciso Name.append("(");
1941e28b9357SCarlos Alberto Enciso
1942e28b9357SCarlos Alberto Enciso // Traverse the scope symbols, looking for those which are parameters.
1943e28b9357SCarlos Alberto Enciso if (const LVSymbols *Symbols = getSymbols()) {
1944e28b9357SCarlos Alberto Enciso bool AddComma = false;
1945e28b9357SCarlos Alberto Enciso for (LVSymbol *Symbol : *Symbols)
1946e28b9357SCarlos Alberto Enciso if (Symbol->getIsParameter()) {
1947e28b9357SCarlos Alberto Enciso Symbol->resolve();
1948e28b9357SCarlos Alberto Enciso if (LVElement *Type = Symbol->getType())
1949e28b9357SCarlos Alberto Enciso Type->resolveName();
1950e28b9357SCarlos Alberto Enciso if (AddComma)
1951e28b9357SCarlos Alberto Enciso Name.append(", ");
1952e28b9357SCarlos Alberto Enciso Name.append(std::string(Symbol->getTypeName()));
1953e28b9357SCarlos Alberto Enciso AddComma = true;
1954e28b9357SCarlos Alberto Enciso }
1955e28b9357SCarlos Alberto Enciso }
1956e28b9357SCarlos Alberto Enciso
1957e28b9357SCarlos Alberto Enciso Name.append(")");
1958e28b9357SCarlos Alberto Enciso
1959e28b9357SCarlos Alberto Enciso // Update the scope name, to reflect the encoded parameters.
1960d22f050eSGregory Alfonso setName(Name);
1961e28b9357SCarlos Alberto Enciso }
1962e28b9357SCarlos Alberto Enciso
1963e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
1964e28b9357SCarlos Alberto Enciso // DWARF namespace (DW_TAG_namespace).
1965e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1966e98a4c5aSCarlos Alberto Enciso bool LVScopeNamespace::equals(const LVScope *Scope) const {
1967e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
1968e98a4c5aSCarlos Alberto Enciso return false;
1969e98a4c5aSCarlos Alberto Enciso
1970e98a4c5aSCarlos Alberto Enciso if (!equalNumberOfChildren(Scope))
1971e98a4c5aSCarlos Alberto Enciso return false;
1972e98a4c5aSCarlos Alberto Enciso
1973e98a4c5aSCarlos Alberto Enciso // Check if any reference is the same.
1974e98a4c5aSCarlos Alberto Enciso if (!referenceMatch(Scope))
1975e98a4c5aSCarlos Alberto Enciso return false;
1976e98a4c5aSCarlos Alberto Enciso
1977e98a4c5aSCarlos Alberto Enciso if (getReference() && !getReference()->equals(Scope->getReference()))
1978e98a4c5aSCarlos Alberto Enciso return false;
1979e98a4c5aSCarlos Alberto Enciso
1980e98a4c5aSCarlos Alberto Enciso return true;
1981e98a4c5aSCarlos Alberto Enciso }
1982e98a4c5aSCarlos Alberto Enciso
findEqualScope(const LVScopes * Scopes) const1983e98a4c5aSCarlos Alberto Enciso LVScope *LVScopeNamespace::findEqualScope(const LVScopes *Scopes) const {
1984e98a4c5aSCarlos Alberto Enciso assert(Scopes && "Scopes must not be nullptr");
1985e98a4c5aSCarlos Alberto Enciso // Go through candidates and try to find a best match.
1986e98a4c5aSCarlos Alberto Enciso for (LVScope *Scope : *Scopes)
1987e98a4c5aSCarlos Alberto Enciso if (equals(Scope))
1988e98a4c5aSCarlos Alberto Enciso return Scope;
1989e98a4c5aSCarlos Alberto Enciso return nullptr;
1990e98a4c5aSCarlos Alberto Enciso }
1991e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const1992e28b9357SCarlos Alberto Enciso void LVScopeNamespace::printExtra(raw_ostream &OS, bool Full) const {
1993e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
1994e28b9357SCarlos Alberto Enciso
19953c397c90SCarlos Alberto Enciso // Print any active ranges.
1996e28b9357SCarlos Alberto Enciso if (Full) {
19973c397c90SCarlos Alberto Enciso printActiveRanges(OS, Full);
19983c397c90SCarlos Alberto Enciso
1999e28b9357SCarlos Alberto Enciso if (LVScope *Reference = getReference())
2000e28b9357SCarlos Alberto Enciso Reference->printReference(OS, Full, const_cast<LVScopeNamespace *>(this));
2001e28b9357SCarlos Alberto Enciso }
2002e28b9357SCarlos Alberto Enciso }
2003e28b9357SCarlos Alberto Enciso
20043c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
20053c397c90SCarlos Alberto Enciso // An object file (single or multiple CUs).
20063c397c90SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
processRangeInformation()20073c397c90SCarlos Alberto Enciso void LVScopeRoot::processRangeInformation() {
20083c397c90SCarlos Alberto Enciso if (!options().getAttributeAnyLocation())
20093c397c90SCarlos Alberto Enciso return;
20103c397c90SCarlos Alberto Enciso
20113c397c90SCarlos Alberto Enciso if (Scopes)
20123c397c90SCarlos Alberto Enciso for (LVScope *Scope : *Scopes) {
20133c397c90SCarlos Alberto Enciso LVScopeCompileUnit *CompileUnit =
20143c397c90SCarlos Alberto Enciso static_cast<LVScopeCompileUnit *>(Scope);
20153c397c90SCarlos Alberto Enciso getReader().setCompileUnit(CompileUnit);
20163c397c90SCarlos Alberto Enciso CompileUnit->processRangeLocationCoverage();
20173c397c90SCarlos Alberto Enciso }
20183c397c90SCarlos Alberto Enciso }
20193c397c90SCarlos Alberto Enciso
transformScopedName()2020e7950fceSCarlos Alberto Enciso void LVScopeRoot::transformScopedName() {
2021e7950fceSCarlos Alberto Enciso // Recursively transform all names.
2022e7950fceSCarlos Alberto Enciso std::function<void(LVScope * Parent)> TraverseScope = [&](LVScope *Parent) {
2023e7950fceSCarlos Alberto Enciso auto Traverse = [&](const auto *Set) {
2024e7950fceSCarlos Alberto Enciso if (Set)
2025e7950fceSCarlos Alberto Enciso for (const auto &Entry : *Set)
2026e7950fceSCarlos Alberto Enciso Entry->setInnerComponent();
2027e7950fceSCarlos Alberto Enciso };
2028e7950fceSCarlos Alberto Enciso if (const LVScopes *Scopes = Parent->getScopes())
2029e7950fceSCarlos Alberto Enciso for (LVScope *Scope : *Scopes) {
2030e7950fceSCarlos Alberto Enciso Scope->setInnerComponent();
2031e7950fceSCarlos Alberto Enciso TraverseScope(Scope);
2032e7950fceSCarlos Alberto Enciso }
2033e7950fceSCarlos Alberto Enciso Traverse(Parent->getSymbols());
2034e7950fceSCarlos Alberto Enciso Traverse(Parent->getTypes());
2035e7950fceSCarlos Alberto Enciso Traverse(Parent->getLines());
2036e7950fceSCarlos Alberto Enciso };
2037e7950fceSCarlos Alberto Enciso
2038e7950fceSCarlos Alberto Enciso // Start traversing the scopes root and transform the element name.
2039e7950fceSCarlos Alberto Enciso TraverseScope(this);
2040e7950fceSCarlos Alberto Enciso }
2041e7950fceSCarlos Alberto Enciso
equals(const LVScope * Scope) const2042e98a4c5aSCarlos Alberto Enciso bool LVScopeRoot::equals(const LVScope *Scope) const {
2043e98a4c5aSCarlos Alberto Enciso return LVScope::equals(Scope);
2044e98a4c5aSCarlos Alberto Enciso }
2045e98a4c5aSCarlos Alberto Enciso
print(raw_ostream & OS,bool Full) const2046e28b9357SCarlos Alberto Enciso void LVScopeRoot::print(raw_ostream &OS, bool Full) const {
2047e28b9357SCarlos Alberto Enciso OS << "\nLogical View:\n";
2048e28b9357SCarlos Alberto Enciso LVScope::print(OS, Full);
2049e28b9357SCarlos Alberto Enciso }
2050e28b9357SCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const2051e28b9357SCarlos Alberto Enciso void LVScopeRoot::printExtra(raw_ostream &OS, bool Full) const {
2052e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << formattedName(getName()) << "";
2053e28b9357SCarlos Alberto Enciso if (options().getAttributeFormat())
2054e28b9357SCarlos Alberto Enciso OS << " -> " << getFileFormatName();
2055e28b9357SCarlos Alberto Enciso OS << "\n";
2056e28b9357SCarlos Alberto Enciso }
2057e28b9357SCarlos Alberto Enciso
doPrintMatches(bool Split,raw_ostream & OS,bool UseMatchedElements) const2058e28b9357SCarlos Alberto Enciso Error LVScopeRoot::doPrintMatches(bool Split, raw_ostream &OS,
2059e28b9357SCarlos Alberto Enciso bool UseMatchedElements) const {
2060e28b9357SCarlos Alberto Enciso // During a view output splitting, use the output stream created by the
2061e28b9357SCarlos Alberto Enciso // split context, then switch to the reader output stream.
2062e28b9357SCarlos Alberto Enciso static raw_ostream *StreamSplit = &OS;
2063e28b9357SCarlos Alberto Enciso
2064e28b9357SCarlos Alberto Enciso if (Scopes) {
2065e28b9357SCarlos Alberto Enciso if (UseMatchedElements)
2066e28b9357SCarlos Alberto Enciso options().resetPrintFormatting();
2067e28b9357SCarlos Alberto Enciso print(OS);
2068e28b9357SCarlos Alberto Enciso
2069e28b9357SCarlos Alberto Enciso for (LVScope *Scope : *Scopes) {
2070e28b9357SCarlos Alberto Enciso getReader().setCompileUnit(const_cast<LVScope *>(Scope));
2071e28b9357SCarlos Alberto Enciso
2072e28b9357SCarlos Alberto Enciso // If 'Split', we use the scope name (CU name) as the ouput file; the
2073e28b9357SCarlos Alberto Enciso // delimiters in the pathname, must be replaced by a normal character.
2074e28b9357SCarlos Alberto Enciso if (Split) {
2075e28b9357SCarlos Alberto Enciso std::string ScopeName(Scope->getName());
2076e28b9357SCarlos Alberto Enciso if (std::error_code EC =
2077e28b9357SCarlos Alberto Enciso getReaderSplitContext().open(ScopeName, ".txt", OS))
2078e28b9357SCarlos Alberto Enciso return createStringError(EC, "Unable to create split output file %s",
2079e28b9357SCarlos Alberto Enciso ScopeName.c_str());
2080e28b9357SCarlos Alberto Enciso StreamSplit = static_cast<raw_ostream *>(&getReaderSplitContext().os());
2081e28b9357SCarlos Alberto Enciso }
2082e28b9357SCarlos Alberto Enciso
2083e28b9357SCarlos Alberto Enciso Scope->printMatchedElements(*StreamSplit, UseMatchedElements);
2084e28b9357SCarlos Alberto Enciso
2085e28b9357SCarlos Alberto Enciso // Done printing the compile unit. Restore the original output context.
2086e28b9357SCarlos Alberto Enciso if (Split) {
2087e28b9357SCarlos Alberto Enciso getReaderSplitContext().close();
2088e28b9357SCarlos Alberto Enciso StreamSplit = &getReader().outputStream();
2089e28b9357SCarlos Alberto Enciso }
2090e28b9357SCarlos Alberto Enciso }
2091e28b9357SCarlos Alberto Enciso if (UseMatchedElements)
2092e28b9357SCarlos Alberto Enciso options().setPrintFormatting();
2093e28b9357SCarlos Alberto Enciso }
2094e28b9357SCarlos Alberto Enciso
2095e28b9357SCarlos Alberto Enciso return Error::success();
2096e28b9357SCarlos Alberto Enciso }
2097e28b9357SCarlos Alberto Enciso
2098e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
2099e28b9357SCarlos Alberto Enciso // DWARF template parameter pack (DW_TAG_GNU_template_parameter_pack).
2100e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const2101e98a4c5aSCarlos Alberto Enciso bool LVScopeTemplatePack::equals(const LVScope *Scope) const {
2102e98a4c5aSCarlos Alberto Enciso if (!LVScope::equals(Scope))
2103e98a4c5aSCarlos Alberto Enciso return false;
2104e98a4c5aSCarlos Alberto Enciso return equalNumberOfChildren(Scope);
2105e98a4c5aSCarlos Alberto Enciso }
2106e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const2107e28b9357SCarlos Alberto Enciso void LVScopeTemplatePack::printExtra(raw_ostream &OS, bool Full) const {
2108e28b9357SCarlos Alberto Enciso OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
2109e28b9357SCarlos Alberto Enciso }
2110