X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FIR%2FDebugInfo.h;h=6294b797389ad80594793e99bbb3cfc7c1b53cc3;hb=b74553f910314e9545bc7fa76fef25086c371bfb;hp=00652a72d83f3ef878c7f290bd015aa1acbb1174;hpb=1e6990e4dcc4ce10770774a182af1d4836637df6;p=oota-llvm.git diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 00652a72d83..6294b797389 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -18,10 +18,10 @@ #define LLVM_IR_DEBUGINFO_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Dwarf.h" @@ -59,14 +59,14 @@ class DIObjCProperty; typedef DenseMap DITypeIdentifierMap; class DIHeaderFieldIterator - : public std::iterator { StringRef Header; StringRef Current; public: DIHeaderFieldIterator() {} - DIHeaderFieldIterator(StringRef Header) + explicit DIHeaderFieldIterator(StringRef Header) : Header(Header), Current(Header.slice(0, Header.find('\0'))) {} StringRef operator*() const { return Current; } const StringRef * operator->() const { return &Current; } @@ -99,6 +99,16 @@ public: return Header.slice(Current.end() - Header.begin() + 1, StringRef::npos); } + /// \brief Get the current field as a number. + /// + /// Convert the current field into a number. Return \c 0 on error. + template T getNumber() const { + T Int; + if (getCurrent().getAsInteger(0, Int)) + return 0; + return Int; + } + private: void increment() { assert(Current.data() != nullptr && "Cannot increment past the end"); @@ -138,9 +148,8 @@ public: FlagObjectPointer = 1 << 10, FlagVector = 1 << 11, FlagStaticMember = 1 << 12, - FlagIndirectVariable = 1 << 13, - FlagLValueReference = 1 << 14, - FlagRValueReference = 1 << 15 + FlagLValueReference = 1 << 13, + FlagRValueReference = 1 << 14 }; protected: @@ -191,20 +200,26 @@ public: DIHeaderFieldIterator()); } - StringRef getHeaderField(unsigned Index) const { + DIHeaderFieldIterator header_begin() const { + return DIHeaderFieldIterator(getHeader()); + } + DIHeaderFieldIterator header_end() const { return DIHeaderFieldIterator(); } + + DIHeaderFieldIterator getHeaderIterator(unsigned Index) const { // Since callers expect an empty string for out-of-range accesses, we can't // use std::advance() here. - for (DIHeaderFieldIterator I(getHeader()), E; I != E; ++I, --Index) + for (auto I = header_begin(), E = header_end(); I != E; ++I, --Index) if (!Index) - return *I; - return StringRef(); + return I; + return header_end(); + } + + StringRef getHeaderField(unsigned Index) const { + return *getHeaderIterator(Index); } template T getHeaderFieldAs(unsigned Index) const { - T Int; - if (getHeaderField(Index).getAsInteger(0, Int)) - return 0; - return Int; + return getHeaderIterator(Index).getNumber(); } uint16_t getTag() const { return getHeaderFieldAs(0); } @@ -382,7 +397,7 @@ template <> DITypeRef DIDescriptor::getFieldAs(unsigned Elt) const; /// \brief Specialize DIRef constructor for DITypeRef. template <> DIRef::DIRef(const Metadata *V); -/// \briefThis is a wrapper for a type. +/// \brief This is a wrapper for a type. /// /// FIXME: Types should be factored much better so that CV qualifiers and /// others do not require a huge and empty descriptor full of zeros. @@ -816,11 +831,6 @@ public: return (getHeaderFieldAs(3) & FlagObjectPointer) != 0; } - /// \brief Return true if this variable is represented as a pointer. - bool isIndirect() const { - return (getHeaderFieldAs(3) & FlagIndirectVariable) != 0; - } - /// \brief If this variable is inlined then return inline location. MDNode *getInlinedAt() const; @@ -840,7 +850,13 @@ public: void printExtendedName(raw_ostream &OS) const; }; -/// \brief A complex location expression. +/// \brief A complex location expression in postfix notation. +/// +/// This is (almost) a DWARF expression that modifies the location of a +/// variable or (or the location of a single piece of a variable). +/// +/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const +/// and have DW_OP_plus consume the topmost elements on the stack. class DIExpression : public DIDescriptor { friend class DIDescriptor; void printInternal(raw_ostream &OS) const; @@ -868,6 +884,55 @@ public: uint64_t getPieceOffset() const; /// \brief Return the size of this piece in bytes. uint64_t getPieceSize() const; + + /// \brief An iterator for DIExpression elements. + class iterator + : public std::iterator { + DIHeaderFieldIterator I; + iterator(DIHeaderFieldIterator I) : I(I) {} + public: + iterator() {} + iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {} + uint64_t operator*() const { return I.getNumber(); } + iterator &operator++() { + increment(); + return *this; + } + iterator operator++(int) { + iterator X(*this); + increment(); + return X; + } + bool operator==(const iterator &X) const { + return I == X.I; + } + bool operator!=(const iterator &X) const { + return !(*this == X); + } + + uint64_t getArg(unsigned N) const { + auto In = I; + std::advance(In, N); + return In.getNumber(); + } + + const DIHeaderFieldIterator& getBase() const { return I; } + + private: + void increment() { + switch (**this) { + case dwarf::DW_OP_piece: std::advance(I, 3); break; + case dwarf::DW_OP_plus: std::advance(I, 2); break; + case dwarf::DW_OP_deref: std::advance(I, 1); break; + default: + assert("unsupported operand"); + } + } + }; + + iterator begin() const; + iterator end() const; }; /// \brief This object holds location information. @@ -877,10 +942,26 @@ class DILocation : public DIDescriptor { public: explicit DILocation(const MDNode *N) : DIDescriptor(N) {} - unsigned getLineNumber() const { return getUnsignedField(0); } - unsigned getColumnNumber() const { return getUnsignedField(1); } - DIScope getScope() const { return getFieldAs(2); } - DILocation getOrigLocation() const { return getFieldAs(3); } + unsigned getLineNumber() const { + if (auto *L = dyn_cast_or_null(DbgNode)) + return L->getLine(); + return 0; + } + unsigned getColumnNumber() const { + if (auto *L = dyn_cast_or_null(DbgNode)) + return L->getColumn(); + return 0; + } + DIScope getScope() const { + if (auto *L = dyn_cast_or_null(DbgNode)) + return DIScope(dyn_cast_or_null(L->getScope())); + return DIScope(nullptr); + } + DILocation getOrigLocation() const { + if (auto *L = dyn_cast_or_null(DbgNode)) + return DILocation(dyn_cast_or_null(L->getInlinedAt())); + return DILocation(nullptr); + } StringRef getFilename() const { return getScope().getFilename(); } StringRef getDirectory() const { return getScope().getDirectory(); } bool Verify() const; @@ -901,7 +982,9 @@ public: // sure this location is a lexical block before retrieving its // value. return getScope().isLexicalBlockFile() - ? getFieldAs(2).getDiscriminator() + ? DILexicalBlockFile( + cast(cast(DbgNode)->getScope())) + .getDiscriminator() : 0; } @@ -1024,6 +1107,9 @@ public: /// \brief Process DILocation. void processLocation(const Module &M, DILocation Loc); + /// \brief Process DIExpression. + void processExpression(DIExpression Expr); + /// \brief Clear all lists. void reset();