//===--- DeclNameLoc.h - Declaration Name Location Info ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file defines the DeclNameLoc class. // //===----------------------------------------------------------------------===// #ifndef SWIFT_AST_DECL_NAME_LOC_H #define SWIFT_AST_DECL_NAME_LOC_H #include "swift/Basic/LLVM.h" #include "swift/Basic/SourceLoc.h" #include "llvm/ADT/ArrayRef.h" class BridgedDeclNameLoc; namespace swift { class ASTContext; /// Source location information for a declaration name (\c DeclName) /// written in the source. class DeclNameLoc { friend class ::BridgedDeclNameLoc; /// Source location information. /// /// If \c NumArgumentLabels == 0 and \c !HasModuleSelectorLoc, this is the /// SourceLoc for the base name. Otherwise, it points to an array of /// SourceLocs, which contains: /// * The base name location /// * The module selector location /// * The left parentheses location /// * The right parentheses location /// * The locations of each of the argument labels. const void *LocationInfo; /// The number of argument labels stored in the name. uint32_t NumArgumentLabels; bool HasModuleSelectorLoc; enum { BaseNameIndex = 0, ModuleSelectorIndex = 1, LParenIndex = 2, RParenIndex = 3, FirstArgumentLabelIndex = 4, }; /// Retrieve a pointer to either the only source location that was /// stored or to the array of source locations that was stored. SourceLoc const * getSourceLocs() const { if (NumArgumentLabels == 0 && !HasModuleSelectorLoc) { if (LocationInfo == nullptr) return nullptr; return reinterpret_cast(&LocationInfo); } return reinterpret_cast(LocationInfo); } DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels, bool HasModuleSelectorLoc) : LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels), HasModuleSelectorLoc(HasModuleSelectorLoc) {} public: /// Create an invalid declaration name location. DeclNameLoc() : DeclNameLoc(nullptr, 0, false) {} /// Create declaration name location information for a base name. explicit DeclNameLoc(SourceLoc baseNameLoc) : DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0, false) {} explicit DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc, SourceLoc baseNameLoc) : DeclNameLoc(ctx, moduleSelectorLoc, baseNameLoc, SourceLoc(), {}, SourceLoc()) { } /// Create declaration name location information for a compound /// name. DeclNameLoc(ASTContext &ctx, SourceLoc baseNameLoc, SourceLoc lParenLoc, ArrayRef argumentLabelLocs, SourceLoc rParenLoc) : DeclNameLoc(ctx, SourceLoc(), baseNameLoc, lParenLoc, argumentLabelLocs, rParenLoc) { } DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc, SourceLoc baseNameLoc, SourceLoc lParenLoc, ArrayRef argumentLabelLocs, SourceLoc rParenLoc); /// Whether the location information is valid. bool isValid() const { return getBaseNameLoc().isValid(); } /// Whether the location information is invalid. bool isInvalid() const { return getBaseNameLoc().isInvalid(); } /// Whether this was written as a compound name. bool isCompound() const { return NumArgumentLabels > 0; } /// Retrieve the location of the base name. SourceLoc getBaseNameLoc() const { const SourceLoc *SourceLocs = getSourceLocs(); if (SourceLocs == nullptr) return SourceLoc(); return SourceLocs[BaseNameIndex]; } /// Retrieve the location of the left parentheses. SourceLoc getLParenLoc() const { if (NumArgumentLabels == 0) return SourceLoc(); return getSourceLocs()[LParenIndex]; } /// Retrieve the location of the right parentheses. SourceLoc getRParenLoc() const { if (NumArgumentLabels == 0) return SourceLoc(); return getSourceLocs()[RParenIndex]; } /// Retrieve the location of an argument label. SourceLoc getArgumentLabelLoc(unsigned index) const { if (index >= NumArgumentLabels) return SourceLoc(); return getSourceLocs()[FirstArgumentLabelIndex + index]; } SourceLoc getModuleSelectorLoc() const { if (!HasModuleSelectorLoc) return SourceLoc(); return getSourceLocs()[ModuleSelectorIndex]; } SourceLoc getStartLoc() const { return HasModuleSelectorLoc ? getModuleSelectorLoc() : getBaseNameLoc(); } SourceLoc getEndLoc() const { return NumArgumentLabels == 0 ? getBaseNameLoc() : getRParenLoc(); } /// Retrieve the complete source range for this declaration name. SourceRange getSourceRange() const { return SourceRange(getStartLoc(), getEndLoc()); } }; } #endif // SWIFT_AST_DECL_NAME_LOC_H