diff options
Diffstat (limited to 'include/clang/Sema')
34 files changed, 0 insertions, 21568 deletions
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h deleted file mode 100644 index 64dd2d3..0000000 --- a/include/clang/Sema/AnalysisBasedWarnings.h +++ /dev/null @@ -1,103 +0,0 @@ -//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines AnalysisBasedWarnings, a worker object used by Sema -// that issues warnings based on dataflow-analysis. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H -#define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H - -#include "llvm/ADT/DenseMap.h" - -namespace clang { - -class BlockExpr; -class Decl; -class FunctionDecl; -class ObjCMethodDecl; -class QualType; -class Sema; -namespace sema { - class FunctionScopeInfo; -} - -namespace sema { - -class AnalysisBasedWarnings { -public: - class Policy { - friend class AnalysisBasedWarnings; - // The warnings to run. - unsigned enableCheckFallThrough : 1; - unsigned enableCheckUnreachable : 1; - unsigned enableThreadSafetyAnalysis : 1; - unsigned enableConsumedAnalysis : 1; - public: - Policy(); - void disableCheckFallThrough() { enableCheckFallThrough = 0; } - }; - -private: - Sema &S; - Policy DefaultPolicy; - - enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 }; - llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD; - - /// \name Statistics - /// @{ - - /// \brief Number of function CFGs built and analyzed. - unsigned NumFunctionsAnalyzed; - - /// \brief Number of functions for which the CFG could not be successfully - /// built. - unsigned NumFunctionsWithBadCFGs; - - /// \brief Total number of blocks across all CFGs. - unsigned NumCFGBlocks; - - /// \brief Largest number of CFG blocks for a single function analyzed. - unsigned MaxCFGBlocksPerFunction; - - /// \brief Total number of CFGs with variables analyzed for uninitialized - /// uses. - unsigned NumUninitAnalysisFunctions; - - /// \brief Total number of variables analyzed for uninitialized uses. - unsigned NumUninitAnalysisVariables; - - /// \brief Max number of variables analyzed for uninitialized uses in a single - /// function. - unsigned MaxUninitAnalysisVariablesPerFunction; - - /// \brief Total number of block visits during uninitialized use analysis. - unsigned NumUninitAnalysisBlockVisits; - - /// \brief Max number of block visits during uninitialized use analysis of - /// a single function. - unsigned MaxUninitAnalysisBlockVisitsPerFunction; - - /// @} - -public: - AnalysisBasedWarnings(Sema &s); - - void IssueWarnings(Policy P, FunctionScopeInfo *fscope, - const Decl *D, const BlockExpr *blkExpr); - - Policy getDefaultPolicy() { return DefaultPolicy; } - - void PrintStats() const; -}; - -}} // end namespace clang::sema - -#endif diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h deleted file mode 100644 index e32781d..0000000 --- a/include/clang/Sema/AttributeList.h +++ /dev/null @@ -1,863 +0,0 @@ -//===--- AttributeList.h - Parsed attribute sets ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the AttributeList class, which is used to collect -// parsed attributes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H -#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H - -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Basic/VersionTuple.h" -#include "clang/Sema/Ownership.h" -#include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Allocator.h" -#include <cassert> - -namespace clang { - class ASTContext; - class IdentifierInfo; - class Expr; - -/// \brief Represents information about a change in availability for -/// an entity, which is part of the encoding of the 'availability' -/// attribute. -struct AvailabilityChange { - /// \brief The location of the keyword indicating the kind of change. - SourceLocation KeywordLoc; - - /// \brief The version number at which the change occurred. - VersionTuple Version; - - /// \brief The source range covering the version number. - SourceRange VersionRange; - - /// \brief Determine whether this availability change is valid. - bool isValid() const { return !Version.empty(); } -}; - -/// \brief Wraps an identifier and optional source location for the identifier. -struct IdentifierLoc { - SourceLocation Loc; - IdentifierInfo *Ident; - - static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, - IdentifierInfo *Ident); -}; - -/// \brief A union of the various pointer types that can be passed to an -/// AttributeList as an argument. -typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion; -typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector; - -/// AttributeList - Represents a syntactic attribute. -/// -/// For a GNU attribute, there are four forms of this construct: -/// -/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused. -/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused. -/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. -/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. -/// -class AttributeList { // TODO: This should really be called ParsedAttribute -public: - /// The style used to specify an attribute. - enum Syntax { - /// __attribute__((...)) - AS_GNU, - /// [[...]] - AS_CXX11, - /// __declspec(...) - AS_Declspec, - /// __ptr16, alignas(...), etc. - AS_Keyword, - /// Context-sensitive version of a keyword attribute. - AS_ContextSensitiveKeyword, - /// #pragma ... - AS_Pragma - }; - -private: - IdentifierInfo *AttrName; - IdentifierInfo *ScopeName; - SourceRange AttrRange; - SourceLocation ScopeLoc; - SourceLocation EllipsisLoc; - - /// The number of expression arguments this attribute has. - /// The expressions themselves are stored after the object. - unsigned NumArgs : 15; - - /// Corresponds to the Syntax enum. - unsigned SyntaxUsed : 3; - - /// True if already diagnosed as invalid. - mutable unsigned Invalid : 1; - - /// True if this attribute was used as a type attribute. - mutable unsigned UsedAsTypeAttr : 1; - - /// True if this has the extra information associated with an - /// availability attribute. - unsigned IsAvailability : 1; - - /// True if this has extra information associated with a - /// type_tag_for_datatype attribute. - unsigned IsTypeTagForDatatype : 1; - - /// True if this has extra information associated with a - /// Microsoft __delcspec(property) attribute. - unsigned IsProperty : 1; - - /// True if this has a ParsedType - unsigned HasParsedType : 1; - - unsigned AttrKind : 8; - - /// \brief The location of the 'unavailable' keyword in an - /// availability attribute. - SourceLocation UnavailableLoc; - - const Expr *MessageExpr; - - /// The next attribute in the current position. - AttributeList *NextInPosition; - - /// The next attribute allocated in the current Pool. - AttributeList *NextInPool; - - /// Arguments, if any, are stored immediately following the object. - ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); } - ArgsUnion const *getArgsBuffer() const { - return reinterpret_cast<ArgsUnion const *>(this + 1); - } - - enum AvailabilitySlot { - IntroducedSlot, DeprecatedSlot, ObsoletedSlot - }; - - /// Availability information is stored immediately following the arguments, - /// if any, at the end of the object. - AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { - return reinterpret_cast<AvailabilityChange*>(getArgsBuffer() - + NumArgs)[index]; - } - const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { - return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() - + NumArgs)[index]; - } - -public: - struct TypeTagForDatatypeData { - ParsedType *MatchingCType; - unsigned LayoutCompatible : 1; - unsigned MustBeNull : 1; - }; - struct PropertyData { - IdentifierInfo *GetterId, *SetterId; - PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId) - : GetterId(getterId), SetterId(setterId) {} - }; - -private: - /// Type tag information is stored immediately following the arguments, if - /// any, at the end of the object. They are mutually exlusive with - /// availability slots. - TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { - return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs); - } - - const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { - return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer() - + NumArgs); - } - - /// The type buffer immediately follows the object and are mutually exclusive - /// with arguments. - ParsedType &getTypeBuffer() { - return *reinterpret_cast<ParsedType *>(this + 1); - } - - const ParsedType &getTypeBuffer() const { - return *reinterpret_cast<const ParsedType *>(this + 1); - } - - /// The property data immediately follows the object is is mutually exclusive - /// with arguments. - PropertyData &getPropertyDataBuffer() { - assert(IsProperty); - return *reinterpret_cast<PropertyData*>(this + 1); - } - - const PropertyData &getPropertyDataBuffer() const { - assert(IsProperty); - return *reinterpret_cast<const PropertyData*>(this + 1); - } - - AttributeList(const AttributeList &) = delete; - void operator=(const AttributeList &) = delete; - void operator delete(void *) = delete; - ~AttributeList() = delete; - - size_t allocated_size() const; - - /// Constructor for attributes with expression arguments. - AttributeList(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - ArgsUnion *args, unsigned numArgs, - Syntax syntaxUsed, SourceLocation ellipsisLoc) - : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), - ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), - SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), - IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), - HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) { - if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); - AttrKind = getKind(getName(), getScopeName(), syntaxUsed); - } - - /// Constructor for availability attributes. - AttributeList(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *Parm, const AvailabilityChange &introduced, - const AvailabilityChange &deprecated, - const AvailabilityChange &obsoleted, - SourceLocation unavailable, - const Expr *messageExpr, - Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), - ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), - IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - UnavailableLoc(unavailable), MessageExpr(messageExpr), - NextInPosition(nullptr), NextInPool(nullptr) { - ArgsUnion PVal(Parm); - memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); - new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); - new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); - new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); - AttrKind = getKind(getName(), getScopeName(), syntaxUsed); - } - - /// Constructor for objc_bridge_related attributes. - AttributeList(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *Parm1, - IdentifierLoc *Parm2, - IdentifierLoc *Parm3, - Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), - ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { - ArgsVector Args; - Args.push_back(Parm1); - Args.push_back(Parm2); - Args.push_back(Parm3); - memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion)); - AttrKind = getKind(getName(), getScopeName(), syntaxUsed); - } - - /// Constructor for type_tag_for_datatype attribute. - AttributeList(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *ArgKind, ParsedType matchingCType, - bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), - ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { - ArgsUnion PVal(ArgKind); - memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); - TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); - new (&ExtraData.MatchingCType) ParsedType(matchingCType); - ExtraData.LayoutCompatible = layoutCompatible; - ExtraData.MustBeNull = mustBeNull; - AttrKind = getKind(getName(), getScopeName(), syntaxUsed); - } - - /// Constructor for attributes with a single type argument. - AttributeList(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - ParsedType typeArg, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), - ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), - NextInPosition(nullptr), NextInPool(nullptr) { - new (&getTypeBuffer()) ParsedType(typeArg); - AttrKind = getKind(getName(), getScopeName(), syntaxUsed); - } - - /// Constructor for microsoft __declspec(property) attribute. - AttributeList(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *getterId, IdentifierInfo *setterId, - Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), - ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { - new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); - AttrKind = getKind(getName(), getScopeName(), syntaxUsed); - } - - friend class AttributePool; - friend class AttributeFactory; - -public: - enum Kind { - #define PARSED_ATTR(NAME) AT_##NAME, - #include "clang/Sema/AttrParsedAttrList.inc" - #undef PARSED_ATTR - IgnoredAttribute, - UnknownAttribute - }; - - IdentifierInfo *getName() const { return AttrName; } - SourceLocation getLoc() const { return AttrRange.getBegin(); } - SourceRange getRange() const { return AttrRange; } - - bool hasScope() const { return ScopeName; } - IdentifierInfo *getScopeName() const { return ScopeName; } - SourceLocation getScopeLoc() const { return ScopeLoc; } - - bool hasParsedType() const { return HasParsedType; } - - /// Is this the Microsoft __declspec(property) attribute? - bool isDeclspecPropertyAttribute() const { - return IsProperty; - } - - bool isAlignasAttribute() const { - // FIXME: Use a better mechanism to determine this. - return getKind() == AT_Aligned && isKeywordAttribute(); - } - - bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } - bool isCXX11Attribute() const { - return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); - } - bool isKeywordAttribute() const { - return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword; - } - - bool isContextSensitiveKeywordAttribute() const { - return SyntaxUsed == AS_ContextSensitiveKeyword; - } - - bool isInvalid() const { return Invalid; } - void setInvalid(bool b = true) const { Invalid = b; } - - bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } - void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } - - bool isPackExpansion() const { return EllipsisLoc.isValid(); } - SourceLocation getEllipsisLoc() const { return EllipsisLoc; } - - Kind getKind() const { return Kind(AttrKind); } - static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope, - Syntax SyntaxUsed); - - AttributeList *getNext() const { return NextInPosition; } - void setNext(AttributeList *N) { NextInPosition = N; } - - /// getNumArgs - Return the number of actual arguments to this attribute. - unsigned getNumArgs() const { return NumArgs; } - - /// getArg - Return the specified argument. - ArgsUnion getArg(unsigned Arg) const { - assert(Arg < NumArgs && "Arg access out of range!"); - return getArgsBuffer()[Arg]; - } - - bool isArgExpr(unsigned Arg) const { - return Arg < NumArgs && getArg(Arg).is<Expr*>(); - } - Expr *getArgAsExpr(unsigned Arg) const { - return getArg(Arg).get<Expr*>(); - } - - bool isArgIdent(unsigned Arg) const { - return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>(); - } - IdentifierLoc *getArgAsIdent(unsigned Arg) const { - return getArg(Arg).get<IdentifierLoc*>(); - } - - const AvailabilityChange &getAvailabilityIntroduced() const { - assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(IntroducedSlot); - } - - const AvailabilityChange &getAvailabilityDeprecated() const { - assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(DeprecatedSlot); - } - - const AvailabilityChange &getAvailabilityObsoleted() const { - assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(ObsoletedSlot); - } - - SourceLocation getUnavailableLoc() const { - assert(getKind() == AT_Availability && "Not an availability attribute"); - return UnavailableLoc; - } - - const Expr * getMessageExpr() const { - assert(getKind() == AT_Availability && "Not an availability attribute"); - return MessageExpr; - } - - const ParsedType &getMatchingCType() const { - assert(getKind() == AT_TypeTagForDatatype && - "Not a type_tag_for_datatype attribute"); - return *getTypeTagForDatatypeDataSlot().MatchingCType; - } - - bool getLayoutCompatible() const { - assert(getKind() == AT_TypeTagForDatatype && - "Not a type_tag_for_datatype attribute"); - return getTypeTagForDatatypeDataSlot().LayoutCompatible; - } - - bool getMustBeNull() const { - assert(getKind() == AT_TypeTagForDatatype && - "Not a type_tag_for_datatype attribute"); - return getTypeTagForDatatypeDataSlot().MustBeNull; - } - - const ParsedType &getTypeArg() const { - assert(HasParsedType && "Not a type attribute"); - return getTypeBuffer(); - } - - const PropertyData &getPropertyData() const { - assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute"); - return getPropertyDataBuffer(); - } - - /// \brief Get an index into the attribute spelling list - /// defined in Attr.td. This index is used by an attribute - /// to pretty print itself. - unsigned getAttributeSpellingListIndex() const; - - bool isTargetSpecificAttr() const; - bool isTypeAttr() const; - - bool hasCustomParsing() const; - unsigned getMinArgs() const; - unsigned getMaxArgs() const; - bool hasVariadicArg() const; - bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; - bool diagnoseLangOpts(class Sema &S) const; - bool existsInTarget(const TargetInfo &Target) const; - bool isKnownToGCC() const; - - /// \brief If the parsed attribute has a semantic equivalent, and it would - /// have a semantic Spelling enumeration (due to having semantically-distinct - /// spelling variations), return the value of that semantic spelling. If the - /// parsed attribute does not have a semantic equivalent, or would not have - /// a Spelling enumeration, the value UINT_MAX is returned. - unsigned getSemanticSpelling() const; -}; - -/// A factory, from which one makes pools, from which one creates -/// individual attributes which are deallocated with the pool. -/// -/// Note that it's tolerably cheap to create and destroy one of -/// these as long as you don't actually allocate anything in it. -class AttributeFactory { -public: - enum { - /// The required allocation size of an availability attribute, - /// which we want to ensure is a multiple of sizeof(void*). - AvailabilityAllocSize = - sizeof(AttributeList) - + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + - sizeof(ArgsUnion) - 1) - / sizeof(void*) * sizeof(void*)), - TypeTagForDatatypeAllocSize = - sizeof(AttributeList) - + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) + - sizeof(ArgsUnion) - 1) - / sizeof(void*) * sizeof(void*), - PropertyAllocSize = - sizeof(AttributeList) - + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1) - / sizeof(void*) * sizeof(void*) - }; - -private: - enum { - /// The number of free lists we want to be sure to support - /// inline. This is just enough that availability attributes - /// don't surpass it. It's actually very unlikely we'll see an - /// attribute that needs more than that; on x86-64 you'd need 10 - /// expression arguments, and on i386 you'd need 19. - InlineFreeListsCapacity = - 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*) - }; - - llvm::BumpPtrAllocator Alloc; - - /// Free lists. The index is determined by the following formula: - /// (size - sizeof(AttributeList)) / sizeof(void*) - SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists; - - // The following are the private interface used by AttributePool. - friend class AttributePool; - - /// Allocate an attribute of the given size. - void *allocate(size_t size); - - /// Reclaim all the attributes in the given pool chain, which is - /// non-empty. Note that the current implementation is safe - /// against reclaiming things which were not actually allocated - /// with the allocator, although of course it's important to make - /// sure that their allocator lives at least as long as this one. - void reclaimPool(AttributeList *head); - -public: - AttributeFactory(); - ~AttributeFactory(); -}; - -class AttributePool { - AttributeFactory &Factory; - AttributeList *Head; - - void *allocate(size_t size) { - return Factory.allocate(size); - } - - AttributeList *add(AttributeList *attr) { - // We don't care about the order of the pool. - attr->NextInPool = Head; - Head = attr; - return attr; - } - - void takePool(AttributeList *pool); - -public: - /// Create a new pool for a factory. - AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {} - - AttributePool(const AttributePool &) = delete; - - /// Move the given pool's allocations to this pool. - AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) { - pool.Head = nullptr; - } - - AttributeFactory &getFactory() const { return Factory; } - - void clear() { - if (Head) { - Factory.reclaimPool(Head); - Head = nullptr; - } - } - - /// Take the given pool's allocations and add them to this pool. - void takeAllFrom(AttributePool &pool) { - if (pool.Head) { - takePool(pool.Head); - pool.Head = nullptr; - } - } - - ~AttributePool() { - if (Head) Factory.reclaimPool(Head); - } - - AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - ArgsUnion *args, unsigned numArgs, - AttributeList::Syntax syntax, - SourceLocation ellipsisLoc = SourceLocation()) { - void *memory = allocate(sizeof(AttributeList) - + numArgs * sizeof(ArgsUnion)); - return add(new (memory) AttributeList(attrName, attrRange, - scopeName, scopeLoc, - args, numArgs, syntax, - ellipsisLoc)); - } - - AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *Param, - const AvailabilityChange &introduced, - const AvailabilityChange &deprecated, - const AvailabilityChange &obsoleted, - SourceLocation unavailable, - const Expr *MessageExpr, - AttributeList::Syntax syntax) { - void *memory = allocate(AttributeFactory::AvailabilityAllocSize); - return add(new (memory) AttributeList(attrName, attrRange, - scopeName, scopeLoc, - Param, introduced, deprecated, - obsoleted, unavailable, MessageExpr, - syntax)); - } - - AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *Param1, - IdentifierLoc *Param2, - IdentifierLoc *Param3, - AttributeList::Syntax syntax) { - size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion); - void *memory = allocate(size); - return add(new (memory) AttributeList(attrName, attrRange, - scopeName, scopeLoc, - Param1, Param2, Param3, - syntax)); - } - - AttributeList *createTypeTagForDatatype( - IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *argumentKind, ParsedType matchingCType, - bool layoutCompatible, bool mustBeNull, - AttributeList::Syntax syntax) { - void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); - return add(new (memory) AttributeList(attrName, attrRange, - scopeName, scopeLoc, - argumentKind, matchingCType, - layoutCompatible, mustBeNull, - syntax)); - } - - AttributeList *createTypeAttribute( - IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - ParsedType typeArg, AttributeList::Syntax syntaxUsed) { - void *memory = allocate(sizeof(AttributeList) + sizeof(void *)); - return add(new (memory) AttributeList(attrName, attrRange, - scopeName, scopeLoc, - typeArg, syntaxUsed)); - } - - AttributeList *createPropertyAttribute( - IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *getterId, IdentifierInfo *setterId, - AttributeList::Syntax syntaxUsed) { - void *memory = allocate(AttributeFactory::PropertyAllocSize); - return add(new (memory) AttributeList(attrName, attrRange, - scopeName, scopeLoc, - getterId, setterId, - syntaxUsed)); - } -}; - -/// ParsedAttributes - A collection of parsed attributes. Currently -/// we don't differentiate between the various attribute syntaxes, -/// which is basically silly. -/// -/// Right now this is a very lightweight container, but the expectation -/// is that this will become significantly more serious. -class ParsedAttributes { -public: - ParsedAttributes(AttributeFactory &factory) - : pool(factory), list(nullptr) { - } - - ParsedAttributes(const ParsedAttributes &) = delete; - - AttributePool &getPool() const { return pool; } - - bool empty() const { return list == nullptr; } - - void add(AttributeList *newAttr) { - assert(newAttr); - assert(newAttr->getNext() == nullptr); - newAttr->setNext(list); - list = newAttr; - } - - void addAll(AttributeList *newList) { - if (!newList) return; - - AttributeList *lastInNewList = newList; - while (AttributeList *next = lastInNewList->getNext()) - lastInNewList = next; - - lastInNewList->setNext(list); - list = newList; - } - - void set(AttributeList *newList) { - list = newList; - } - - void takeAllFrom(ParsedAttributes &attrs) { - addAll(attrs.list); - attrs.list = nullptr; - pool.takeAllFrom(attrs.pool); - } - - void clear() { list = nullptr; pool.clear(); } - AttributeList *getList() const { return list; } - - /// Returns a reference to the attribute list. Try not to introduce - /// dependencies on this method, it may not be long-lived. - AttributeList *&getListRef() { return list; } - - /// Add attribute with expression arguments. - AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - ArgsUnion *args, unsigned numArgs, - AttributeList::Syntax syntax, - SourceLocation ellipsisLoc = SourceLocation()) { - AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs, - syntax, ellipsisLoc); - add(attr); - return attr; - } - - /// Add availability attribute. - AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *Param, - const AvailabilityChange &introduced, - const AvailabilityChange &deprecated, - const AvailabilityChange &obsoleted, - SourceLocation unavailable, - const Expr *MessageExpr, - AttributeList::Syntax syntax) { - AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, - deprecated, obsoleted, unavailable, MessageExpr, syntax); - add(attr); - return attr; - } - - /// Add objc_bridge_related attribute. - AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *Param1, - IdentifierLoc *Param2, - IdentifierLoc *Param3, - AttributeList::Syntax syntax) { - AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, - Param1, Param2, Param3, syntax); - add(attr); - return attr; - } - - /// Add type_tag_for_datatype attribute. - AttributeList *addNewTypeTagForDatatype( - IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierLoc *argumentKind, ParsedType matchingCType, - bool layoutCompatible, bool mustBeNull, - AttributeList::Syntax syntax) { - AttributeList *attr = - pool.createTypeTagForDatatype(attrName, attrRange, - scopeName, scopeLoc, - argumentKind, matchingCType, - layoutCompatible, mustBeNull, syntax); - add(attr); - return attr; - } - - /// Add an attribute with a single type argument. - AttributeList * - addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - ParsedType typeArg, AttributeList::Syntax syntaxUsed) { - AttributeList *attr = - pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc, - typeArg, syntaxUsed); - add(attr); - return attr; - } - - /// Add microsoft __delspec(property) attribute. - AttributeList * - addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, - IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *getterId, IdentifierInfo *setterId, - AttributeList::Syntax syntaxUsed) { - AttributeList *attr = - pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, - getterId, setterId, syntaxUsed); - add(attr); - return attr; - } - -private: - mutable AttributePool pool; - AttributeList *list; -}; - -/// These constants match the enumerated choices of -/// err_attribute_argument_n_type and err_attribute_argument_type. -enum AttributeArgumentNType { - AANT_ArgumentIntOrBool, - AANT_ArgumentIntegerConstant, - AANT_ArgumentString, - AANT_ArgumentIdentifier -}; - -/// These constants match the enumerated choices of -/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. -enum AttributeDeclKind { - ExpectedFunction, - ExpectedUnion, - ExpectedVariableOrFunction, - ExpectedFunctionOrMethod, - ExpectedParameter, - ExpectedFunctionMethodOrBlock, - ExpectedFunctionMethodOrClass, - ExpectedFunctionMethodOrParameter, - ExpectedClass, - ExpectedEnum, - ExpectedVariable, - ExpectedMethod, - ExpectedVariableFunctionOrLabel, - ExpectedFieldOrGlobalVar, - ExpectedStruct, - ExpectedVariableOrTypedef, - ExpectedTLSVar, - ExpectedVariableOrField, - ExpectedVariableFieldOrTag, - ExpectedTypeOrNamespace, - ExpectedObjectiveCInterface, - ExpectedMethodOrProperty, - ExpectedStructOrUnion, - ExpectedStructOrUnionOrClass, - ExpectedType, - ExpectedObjCInstanceMethod, - ExpectedObjCInterfaceDeclInitMethod, - ExpectedFunctionVariableOrClass, - ExpectedObjectiveCProtocol, - ExpectedFunctionGlobalVarMethodOrProperty, - ExpectedStructOrUnionOrTypedef, - ExpectedStructOrTypedef, - ExpectedObjectiveCInterfaceOrProtocol, - ExpectedKernelFunction, - ExpectedFunctionWithProtoType -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/CMakeLists.txt b/include/clang/Sema/CMakeLists.txt deleted file mode 100644 index 5a48b90..0000000 --- a/include/clang/Sema/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -clang_tablegen(AttrTemplateInstantiate.inc -gen-clang-attr-template-instantiate - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrTemplateInstantiate) - -clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrParsedAttrList) - -clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrParsedAttrKinds) - -clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrSpellingListIndex) - -clang_tablegen(AttrParsedAttrImpl.inc -gen-clang-attr-parsed-attr-impl - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrParsedAttrImpl) diff --git a/include/clang/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h deleted file mode 100644 index 6685751..0000000 --- a/include/clang/Sema/CXXFieldCollector.h +++ /dev/null @@ -1,80 +0,0 @@ -//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides CXXFieldCollector that is used during parsing & semantic -// analysis of C++ classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H -#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - class FieldDecl; - -/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of -/// C++ classes. -class CXXFieldCollector { - /// Fields - Contains all FieldDecls collected during parsing of a C++ - /// class. When a nested class is entered, its fields are appended to the - /// fields of its parent class, when it is exited its fields are removed. - SmallVector<FieldDecl*, 32> Fields; - - /// FieldCount - Each entry represents the number of fields collected during - /// the parsing of a C++ class. When a nested class is entered, a new field - /// count is pushed, when it is exited, the field count is popped. - SmallVector<size_t, 4> FieldCount; - - // Example: - // - // class C { - // int x,y; - // class NC { - // int q; - // // At this point, Fields contains [x,y,q] decls and FieldCount contains - // // [2,1]. - // }; - // int z; - // // At this point, Fields contains [x,y,z] decls and FieldCount contains - // // [3]. - // }; - -public: - /// StartClass - Called by Sema::ActOnStartCXXClassDef. - void StartClass() { FieldCount.push_back(0); } - - /// Add - Called by Sema::ActOnCXXMemberDeclarator. - void Add(FieldDecl *D) { - Fields.push_back(D); - ++FieldCount.back(); - } - - /// getCurNumField - The number of fields added to the currently parsed class. - size_t getCurNumFields() const { - assert(!FieldCount.empty() && "no currently-parsed class"); - return FieldCount.back(); - } - - /// getCurFields - Pointer to array of fields added to the currently parsed - /// class. - FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); } - - /// FinishClass - Called by Sema::ActOnFinishCXXClassDef. - void FinishClass() { - Fields.resize(Fields.size() - getCurNumFields()); - FieldCount.pop_back(); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h deleted file mode 100644 index 9702273..0000000 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ /dev/null @@ -1,976 +0,0 @@ -//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the CodeCompleteConsumer class. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H -#define LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H - -#include "clang-c/Index.h" -#include "clang/AST/CanonicalType.h" -#include "clang/AST/Type.h" -#include "clang/Sema/CodeCompleteOptions.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Allocator.h" -#include <string> - -namespace clang { - -class Decl; - -/// \brief Default priority values for code-completion results based -/// on their kind. -enum { - /// \brief Priority for the next initialization in a constructor initializer - /// list. - CCP_NextInitializer = 7, - /// \brief Priority for an enumeration constant inside a switch whose - /// condition is of the enumeration type. - CCP_EnumInCase = 7, - /// \brief Priority for a send-to-super completion. - CCP_SuperCompletion = 20, - /// \brief Priority for a declaration that is in the local scope. - CCP_LocalDeclaration = 34, - /// \brief Priority for a member declaration found from the current - /// method or member function. - CCP_MemberDeclaration = 35, - /// \brief Priority for a language keyword (that isn't any of the other - /// categories). - CCP_Keyword = 40, - /// \brief Priority for a code pattern. - CCP_CodePattern = 40, - /// \brief Priority for a non-type declaration. - CCP_Declaration = 50, - /// \brief Priority for a type. - CCP_Type = CCP_Declaration, - /// \brief Priority for a constant value (e.g., enumerator). - CCP_Constant = 65, - /// \brief Priority for a preprocessor macro. - CCP_Macro = 70, - /// \brief Priority for a nested-name-specifier. - CCP_NestedNameSpecifier = 75, - /// \brief Priority for a result that isn't likely to be what the user wants, - /// but is included for completeness. - CCP_Unlikely = 80, - - /// \brief Priority for the Objective-C "_cmd" implicit parameter. - CCP_ObjC_cmd = CCP_Unlikely -}; - -/// \brief Priority value deltas that are added to code-completion results -/// based on the context of the result. -enum { - /// \brief The result is in a base class. - CCD_InBaseClass = 2, - /// \brief The result is a C++ non-static member function whose qualifiers - /// exactly match the object type on which the member function can be called. - CCD_ObjectQualifierMatch = -1, - /// \brief The selector of the given message exactly matches the selector - /// of the current method, which might imply that some kind of delegation - /// is occurring. - CCD_SelectorMatch = -3, - - /// \brief Adjustment to the "bool" type in Objective-C, where the typedef - /// "BOOL" is preferred. - CCD_bool_in_ObjC = 1, - - /// \brief Adjustment for KVC code pattern priorities when it doesn't look - /// like the - CCD_ProbablyNotObjCCollection = 15, - - /// \brief An Objective-C method being used as a property. - CCD_MethodAsProperty = 2 -}; - -/// \brief Priority value factors by which we will divide or multiply the -/// priority of a code-completion result. -enum { - /// \brief Divide by this factor when a code-completion result's type exactly - /// matches the type we expect. - CCF_ExactTypeMatch = 4, - /// \brief Divide by this factor when a code-completion result's type is - /// similar to the type we expect (e.g., both arithmetic types, both - /// Objective-C object pointer types). - CCF_SimilarTypeMatch = 2 -}; - -/// \brief A simplified classification of types used when determining -/// "similar" types for code completion. -enum SimplifiedTypeClass { - STC_Arithmetic, - STC_Array, - STC_Block, - STC_Function, - STC_ObjectiveC, - STC_Other, - STC_Pointer, - STC_Record, - STC_Void -}; - -/// \brief Determine the simplified type class of the given canonical type. -SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T); - -/// \brief Determine the type that this declaration will have if it is used -/// as a type or in an expression. -QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND); - -/// \brief Determine the priority to be given to a macro code completion result -/// with the given name. -/// -/// \param MacroName The name of the macro. -/// -/// \param LangOpts Options describing the current language dialect. -/// -/// \param PreferredTypeIsPointer Whether the preferred type for the context -/// of this macro is a pointer type. -unsigned getMacroUsagePriority(StringRef MacroName, - const LangOptions &LangOpts, - bool PreferredTypeIsPointer = false); - -/// \brief Determine the libclang cursor kind associated with the given -/// declaration. -CXCursorKind getCursorKindForDecl(const Decl *D); - -class FunctionDecl; -class FunctionType; -class FunctionTemplateDecl; -class IdentifierInfo; -class NamedDecl; -class NestedNameSpecifier; -class Sema; - -/// \brief The context in which code completion occurred, so that the -/// code-completion consumer can process the results accordingly. -class CodeCompletionContext { -public: - enum Kind { - /// \brief An unspecified code-completion context. - CCC_Other, - /// \brief An unspecified code-completion context where we should also add - /// macro completions. - CCC_OtherWithMacros, - /// \brief Code completion occurred within a "top-level" completion context, - /// e.g., at namespace or global scope. - CCC_TopLevel, - /// \brief Code completion occurred within an Objective-C interface, - /// protocol, or category interface. - CCC_ObjCInterface, - /// \brief Code completion occurred within an Objective-C implementation - /// or category implementation. - CCC_ObjCImplementation, - /// \brief Code completion occurred within the instance variable list of - /// an Objective-C interface, implementation, or category implementation. - CCC_ObjCIvarList, - /// \brief Code completion occurred within a class, struct, or union. - CCC_ClassStructUnion, - /// \brief Code completion occurred where a statement (or declaration) is - /// expected in a function, method, or block. - CCC_Statement, - /// \brief Code completion occurred where an expression is expected. - CCC_Expression, - /// \brief Code completion occurred where an Objective-C message receiver - /// is expected. - CCC_ObjCMessageReceiver, - /// \brief Code completion occurred on the right-hand side of a member - /// access expression using the dot operator. - /// - /// The results of this completion are the members of the type being - /// accessed. The type itself is available via - /// \c CodeCompletionContext::getType(). - CCC_DotMemberAccess, - /// \brief Code completion occurred on the right-hand side of a member - /// access expression using the arrow operator. - /// - /// The results of this completion are the members of the type being - /// accessed. The type itself is available via - /// \c CodeCompletionContext::getType(). - CCC_ArrowMemberAccess, - /// \brief Code completion occurred on the right-hand side of an Objective-C - /// property access expression. - /// - /// The results of this completion are the members of the type being - /// accessed. The type itself is available via - /// \c CodeCompletionContext::getType(). - CCC_ObjCPropertyAccess, - /// \brief Code completion occurred after the "enum" keyword, to indicate - /// an enumeration name. - CCC_EnumTag, - /// \brief Code completion occurred after the "union" keyword, to indicate - /// a union name. - CCC_UnionTag, - /// \brief Code completion occurred after the "struct" or "class" keyword, - /// to indicate a struct or class name. - CCC_ClassOrStructTag, - /// \brief Code completion occurred where a protocol name is expected. - CCC_ObjCProtocolName, - /// \brief Code completion occurred where a namespace or namespace alias - /// is expected. - CCC_Namespace, - /// \brief Code completion occurred where a type name is expected. - CCC_Type, - /// \brief Code completion occurred where a new name is expected. - CCC_Name, - /// \brief Code completion occurred where a new name is expected and a - /// qualified name is permissible. - CCC_PotentiallyQualifiedName, - /// \brief Code completion occurred where an macro is being defined. - CCC_MacroName, - /// \brief Code completion occurred where a macro name is expected - /// (without any arguments, in the case of a function-like macro). - CCC_MacroNameUse, - /// \brief Code completion occurred within a preprocessor expression. - CCC_PreprocessorExpression, - /// \brief Code completion occurred where a preprocessor directive is - /// expected. - CCC_PreprocessorDirective, - /// \brief Code completion occurred in a context where natural language is - /// expected, e.g., a comment or string literal. - /// - /// This context usually implies that no completions should be added, - /// unless they come from an appropriate natural-language dictionary. - CCC_NaturalLanguage, - /// \brief Code completion for a selector, as in an \@selector expression. - CCC_SelectorName, - /// \brief Code completion within a type-qualifier list. - CCC_TypeQualifiers, - /// \brief Code completion in a parenthesized expression, which means that - /// we may also have types here in C and Objective-C (as well as in C++). - CCC_ParenthesizedExpression, - /// \brief Code completion where an Objective-C instance message is - /// expected. - CCC_ObjCInstanceMessage, - /// \brief Code completion where an Objective-C class message is expected. - CCC_ObjCClassMessage, - /// \brief Code completion where the name of an Objective-C class is - /// expected. - CCC_ObjCInterfaceName, - /// \brief Code completion where an Objective-C category name is expected. - CCC_ObjCCategoryName, - /// \brief An unknown context, in which we are recovering from a parsing - /// error and don't know which completions we should give. - CCC_Recovery - }; - -private: - enum Kind Kind; - - /// \brief The type that would prefer to see at this point (e.g., the type - /// of an initializer or function parameter). - QualType PreferredType; - - /// \brief The type of the base object in a member access expression. - QualType BaseType; - - /// \brief The identifiers for Objective-C selector parts. - ArrayRef<IdentifierInfo *> SelIdents; - -public: - /// \brief Construct a new code-completion context of the given kind. - CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(None) { } - - /// \brief Construct a new code-completion context of the given kind. - CodeCompletionContext(enum Kind Kind, QualType T, - ArrayRef<IdentifierInfo *> SelIdents = None) - : Kind(Kind), - SelIdents(SelIdents) { - if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess || - Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage || - Kind == CCC_ObjCInstanceMessage) - BaseType = T; - else - PreferredType = T; - } - - /// \brief Retrieve the kind of code-completion context. - enum Kind getKind() const { return Kind; } - - /// \brief Retrieve the type that this expression would prefer to have, e.g., - /// if the expression is a variable initializer or a function argument, the - /// type of the corresponding variable or function parameter. - QualType getPreferredType() const { return PreferredType; } - - /// \brief Retrieve the type of the base object in a member-access - /// expression. - QualType getBaseType() const { return BaseType; } - - /// \brief Retrieve the Objective-C selector identifiers. - ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; } - - /// \brief Determines whether we want C++ constructors as results within this - /// context. - bool wantConstructorResults() const; -}; - - -/// \brief A "string" used to describe how code completion can -/// be performed for an entity. -/// -/// A code completion string typically shows how a particular entity can be -/// used. For example, the code completion string for a function would show -/// the syntax to call it, including the parentheses, placeholders for the -/// arguments, etc. -class CodeCompletionString { -public: - /// \brief The different kinds of "chunks" that can occur within a code - /// completion string. - enum ChunkKind { - /// \brief The piece of text that the user is expected to type to - /// match the code-completion string, typically a keyword or the name of a - /// declarator or macro. - CK_TypedText, - /// \brief A piece of text that should be placed in the buffer, e.g., - /// parentheses or a comma in a function call. - CK_Text, - /// \brief A code completion string that is entirely optional. For example, - /// an optional code completion string that describes the default arguments - /// in a function call. - CK_Optional, - /// \brief A string that acts as a placeholder for, e.g., a function - /// call argument. - CK_Placeholder, - /// \brief A piece of text that describes something about the result but - /// should not be inserted into the buffer. - CK_Informative, - /// \brief A piece of text that describes the type of an entity or, for - /// functions and methods, the return type. - CK_ResultType, - /// \brief A piece of text that describes the parameter that corresponds - /// to the code-completion location within a function call, message send, - /// macro invocation, etc. - CK_CurrentParameter, - /// \brief A left parenthesis ('('). - CK_LeftParen, - /// \brief A right parenthesis (')'). - CK_RightParen, - /// \brief A left bracket ('['). - CK_LeftBracket, - /// \brief A right bracket (']'). - CK_RightBracket, - /// \brief A left brace ('{'). - CK_LeftBrace, - /// \brief A right brace ('}'). - CK_RightBrace, - /// \brief A left angle bracket ('<'). - CK_LeftAngle, - /// \brief A right angle bracket ('>'). - CK_RightAngle, - /// \brief A comma separator (','). - CK_Comma, - /// \brief A colon (':'). - CK_Colon, - /// \brief A semicolon (';'). - CK_SemiColon, - /// \brief An '=' sign. - CK_Equal, - /// \brief Horizontal whitespace (' '). - CK_HorizontalSpace, - /// \brief Vertical whitespace ('\\n' or '\\r\\n', depending on the - /// platform). - CK_VerticalSpace - }; - - /// \brief One piece of the code completion string. - struct Chunk { - /// \brief The kind of data stored in this piece of the code completion - /// string. - ChunkKind Kind; - - union { - /// \brief The text string associated with a CK_Text, CK_Placeholder, - /// CK_Informative, or CK_Comma chunk. - /// The string is owned by the chunk and will be deallocated - /// (with delete[]) when the chunk is destroyed. - const char *Text; - - /// \brief The code completion string associated with a CK_Optional chunk. - /// The optional code completion string is owned by the chunk, and will - /// be deallocated (with delete) when the chunk is destroyed. - CodeCompletionString *Optional; - }; - - Chunk() : Kind(CK_Text), Text(nullptr) { } - - explicit Chunk(ChunkKind Kind, const char *Text = ""); - - /// \brief Create a new text chunk. - static Chunk CreateText(const char *Text); - - /// \brief Create a new optional chunk. - static Chunk CreateOptional(CodeCompletionString *Optional); - - /// \brief Create a new placeholder chunk. - static Chunk CreatePlaceholder(const char *Placeholder); - - /// \brief Create a new informative chunk. - static Chunk CreateInformative(const char *Informative); - - /// \brief Create a new result type chunk. - static Chunk CreateResultType(const char *ResultType); - - /// \brief Create a new current-parameter chunk. - static Chunk CreateCurrentParameter(const char *CurrentParameter); - }; - -private: - /// \brief The number of chunks stored in this string. - unsigned NumChunks : 16; - - /// \brief The number of annotations for this code-completion result. - unsigned NumAnnotations : 16; - - /// \brief The priority of this code-completion string. - unsigned Priority : 16; - - /// \brief The availability of this code-completion result. - unsigned Availability : 2; - - /// \brief The name of the parent context. - StringRef ParentName; - - /// \brief A brief documentation comment attached to the declaration of - /// entity being completed by this result. - const char *BriefComment; - - CodeCompletionString(const CodeCompletionString &) = delete; - void operator=(const CodeCompletionString &) = delete; - - CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, - unsigned Priority, CXAvailabilityKind Availability, - const char **Annotations, unsigned NumAnnotations, - StringRef ParentName, - const char *BriefComment); - ~CodeCompletionString() = default; - - friend class CodeCompletionBuilder; - friend class CodeCompletionResult; - -public: - typedef const Chunk *iterator; - iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); } - iterator end() const { return begin() + NumChunks; } - bool empty() const { return NumChunks == 0; } - unsigned size() const { return NumChunks; } - - const Chunk &operator[](unsigned I) const { - assert(I < size() && "Chunk index out-of-range"); - return begin()[I]; - } - - /// \brief Returns the text in the TypedText chunk. - const char *getTypedText() const; - - /// \brief Retrieve the priority of this code completion result. - unsigned getPriority() const { return Priority; } - - /// \brief Retrieve the availability of this code completion result. - unsigned getAvailability() const { return Availability; } - - /// \brief Retrieve the number of annotations for this code completion result. - unsigned getAnnotationCount() const; - - /// \brief Retrieve the annotation string specified by \c AnnotationNr. - const char *getAnnotation(unsigned AnnotationNr) const; - - /// \brief Retrieve the name of the parent context. - StringRef getParentContextName() const { - return ParentName; - } - - const char *getBriefComment() const { - return BriefComment; - } - - /// \brief Retrieve a string representation of the code completion string, - /// which is mainly useful for debugging. - std::string getAsString() const; -}; - -/// \brief An allocator used specifically for the purpose of code completion. -class CodeCompletionAllocator : public llvm::BumpPtrAllocator { -public: - /// \brief Copy the given string into this allocator. - const char *CopyString(const Twine &String); -}; - -/// \brief Allocator for a cached set of global code completions. -class GlobalCodeCompletionAllocator - : public CodeCompletionAllocator, - public RefCountedBase<GlobalCodeCompletionAllocator> -{ - -}; - -class CodeCompletionTUInfo { - llvm::DenseMap<const DeclContext *, StringRef> ParentNames; - IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> AllocatorRef; - -public: - explicit CodeCompletionTUInfo( - IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator) - : AllocatorRef(Allocator) { } - - IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const { - return AllocatorRef; - } - CodeCompletionAllocator &getAllocator() const { - assert(AllocatorRef); - return *AllocatorRef; - } - - StringRef getParentName(const DeclContext *DC); -}; - -} // end namespace clang - -namespace llvm { - template <> struct isPodLike<clang::CodeCompletionString::Chunk> { - static const bool value = true; - }; -} - -namespace clang { - -/// \brief A builder class used to construct new code-completion strings. -class CodeCompletionBuilder { -public: - typedef CodeCompletionString::Chunk Chunk; - -private: - CodeCompletionAllocator &Allocator; - CodeCompletionTUInfo &CCTUInfo; - unsigned Priority; - CXAvailabilityKind Availability; - StringRef ParentName; - const char *BriefComment; - - /// \brief The chunks stored in this string. - SmallVector<Chunk, 4> Chunks; - - SmallVector<const char *, 2> Annotations; - -public: - CodeCompletionBuilder(CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo) - : Allocator(Allocator), CCTUInfo(CCTUInfo), - Priority(0), Availability(CXAvailability_Available), - BriefComment(nullptr) { } - - CodeCompletionBuilder(CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - unsigned Priority, CXAvailabilityKind Availability) - : Allocator(Allocator), CCTUInfo(CCTUInfo), - Priority(Priority), Availability(Availability), - BriefComment(nullptr) { } - - /// \brief Retrieve the allocator into which the code completion - /// strings should be allocated. - CodeCompletionAllocator &getAllocator() const { return Allocator; } - - CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; } - - /// \brief Take the resulting completion string. - /// - /// This operation can only be performed once. - CodeCompletionString *TakeString(); - - /// \brief Add a new typed-text chunk. - void AddTypedTextChunk(const char *Text); - - /// \brief Add a new text chunk. - void AddTextChunk(const char *Text); - - /// \brief Add a new optional chunk. - void AddOptionalChunk(CodeCompletionString *Optional); - - /// \brief Add a new placeholder chunk. - void AddPlaceholderChunk(const char *Placeholder); - - /// \brief Add a new informative chunk. - void AddInformativeChunk(const char *Text); - - /// \brief Add a new result-type chunk. - void AddResultTypeChunk(const char *ResultType); - - /// \brief Add a new current-parameter chunk. - void AddCurrentParameterChunk(const char *CurrentParameter); - - /// \brief Add a new chunk. - void AddChunk(CodeCompletionString::ChunkKind CK, const char *Text = ""); - - void AddAnnotation(const char *A) { Annotations.push_back(A); } - - /// \brief Add the parent context information to this code completion. - void addParentContext(const DeclContext *DC); - - const char *getBriefComment() const { return BriefComment; } - void addBriefComment(StringRef Comment); - - StringRef getParentName() const { return ParentName; } -}; - -/// \brief Captures a result of code completion. -class CodeCompletionResult { -public: - /// \brief Describes the kind of result generated. - enum ResultKind { - RK_Declaration = 0, ///< Refers to a declaration - RK_Keyword, ///< Refers to a keyword or symbol. - RK_Macro, ///< Refers to a macro - RK_Pattern ///< Refers to a precomputed pattern. - }; - - /// \brief When Kind == RK_Declaration or RK_Pattern, the declaration we are - /// referring to. In the latter case, the declaration might be NULL. - const NamedDecl *Declaration; - - union { - /// \brief When Kind == RK_Keyword, the string representing the keyword - /// or symbol's spelling. - const char *Keyword; - - /// \brief When Kind == RK_Pattern, the code-completion string that - /// describes the completion text to insert. - CodeCompletionString *Pattern; - - /// \brief When Kind == RK_Macro, the identifier that refers to a macro. - const IdentifierInfo *Macro; - }; - - /// \brief The priority of this particular code-completion result. - unsigned Priority; - - /// \brief Specifies which parameter (of a function, Objective-C method, - /// macro, etc.) we should start with when formatting the result. - unsigned StartParameter; - - /// \brief The kind of result stored here. - ResultKind Kind; - - /// \brief The cursor kind that describes this result. - CXCursorKind CursorKind; - - /// \brief The availability of this result. - CXAvailabilityKind Availability; - - /// \brief Whether this result is hidden by another name. - bool Hidden : 1; - - /// \brief Whether this result was found via lookup into a base class. - bool QualifierIsInformative : 1; - - /// \brief Whether this declaration is the beginning of a - /// nested-name-specifier and, therefore, should be followed by '::'. - bool StartsNestedNameSpecifier : 1; - - /// \brief Whether all parameters (of a function, Objective-C - /// method, etc.) should be considered "informative". - bool AllParametersAreInformative : 1; - - /// \brief Whether we're completing a declaration of the given entity, - /// rather than a use of that entity. - bool DeclaringEntity : 1; - - /// \brief If the result should have a nested-name-specifier, this is it. - /// When \c QualifierIsInformative, the nested-name-specifier is - /// informative rather than required. - NestedNameSpecifier *Qualifier; - - /// \brief Build a result that refers to a declaration. - CodeCompletionResult(const NamedDecl *Declaration, - unsigned Priority, - NestedNameSpecifier *Qualifier = nullptr, - bool QualifierIsInformative = false, - bool Accessible = true) - : Declaration(Declaration), Priority(Priority), - StartParameter(0), Kind(RK_Declaration), - Availability(CXAvailability_Available), Hidden(false), - QualifierIsInformative(QualifierIsInformative), - StartsNestedNameSpecifier(false), AllParametersAreInformative(false), - DeclaringEntity(false), Qualifier(Qualifier) { - computeCursorKindAndAvailability(Accessible); - } - - /// \brief Build a result that refers to a keyword or symbol. - CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword) - : Declaration(nullptr), Keyword(Keyword), Priority(Priority), - StartParameter(0), Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented), - Availability(CXAvailability_Available), Hidden(false), - QualifierIsInformative(0), StartsNestedNameSpecifier(false), - AllParametersAreInformative(false), DeclaringEntity(false), - Qualifier(nullptr) {} - - /// \brief Build a result that refers to a macro. - CodeCompletionResult(const IdentifierInfo *Macro, - unsigned Priority = CCP_Macro) - : Declaration(nullptr), Macro(Macro), Priority(Priority), StartParameter(0), - Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition), - Availability(CXAvailability_Available), Hidden(false), - QualifierIsInformative(0), StartsNestedNameSpecifier(false), - AllParametersAreInformative(false), DeclaringEntity(false), - Qualifier(nullptr) {} - - /// \brief Build a result that refers to a pattern. - CodeCompletionResult(CodeCompletionString *Pattern, - unsigned Priority = CCP_CodePattern, - CXCursorKind CursorKind = CXCursor_NotImplemented, - CXAvailabilityKind Availability = CXAvailability_Available, - const NamedDecl *D = nullptr) - : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0), - Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability), - Hidden(false), QualifierIsInformative(0), - StartsNestedNameSpecifier(false), AllParametersAreInformative(false), - DeclaringEntity(false), Qualifier(nullptr) - { - } - - /// \brief Build a result that refers to a pattern with an associated - /// declaration. - CodeCompletionResult(CodeCompletionString *Pattern, NamedDecl *D, - unsigned Priority) - : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0), - Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false), - QualifierIsInformative(false), StartsNestedNameSpecifier(false), - AllParametersAreInformative(false), DeclaringEntity(false), - Qualifier(nullptr) { - computeCursorKindAndAvailability(); - } - - /// \brief Retrieve the declaration stored in this result. - const NamedDecl *getDeclaration() const { - assert(Kind == RK_Declaration && "Not a declaration result"); - return Declaration; - } - - /// \brief Retrieve the keyword stored in this result. - const char *getKeyword() const { - assert(Kind == RK_Keyword && "Not a keyword result"); - return Keyword; - } - - /// \brief Create a new code-completion string that describes how to insert - /// this result into a program. - /// - /// \param S The semantic analysis that created the result. - /// - /// \param Allocator The allocator that will be used to allocate the - /// string itself. - CodeCompletionString *CreateCodeCompletionString(Sema &S, - const CodeCompletionContext &CCContext, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments); - CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx, - Preprocessor &PP, - const CodeCompletionContext &CCContext, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments); - -private: - void computeCursorKindAndAvailability(bool Accessible = true); -}; - -bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y); - -inline bool operator>(const CodeCompletionResult &X, - const CodeCompletionResult &Y) { - return Y < X; -} - -inline bool operator<=(const CodeCompletionResult &X, - const CodeCompletionResult &Y) { - return !(Y < X); -} - -inline bool operator>=(const CodeCompletionResult &X, - const CodeCompletionResult &Y) { - return !(X < Y); -} - - -raw_ostream &operator<<(raw_ostream &OS, - const CodeCompletionString &CCS); - -/// \brief Abstract interface for a consumer of code-completion -/// information. -class CodeCompleteConsumer { -protected: - const CodeCompleteOptions CodeCompleteOpts; - - /// \brief Whether the output format for the code-completion consumer is - /// binary. - bool OutputIsBinary; - -public: - class OverloadCandidate { - public: - /// \brief Describes the type of overload candidate. - enum CandidateKind { - /// \brief The candidate is a function declaration. - CK_Function, - /// \brief The candidate is a function template. - CK_FunctionTemplate, - /// \brief The "candidate" is actually a variable, expression, or block - /// for which we only have a function prototype. - CK_FunctionType - }; - - private: - /// \brief The kind of overload candidate. - CandidateKind Kind; - - union { - /// \brief The function overload candidate, available when - /// Kind == CK_Function. - FunctionDecl *Function; - - /// \brief The function template overload candidate, available when - /// Kind == CK_FunctionTemplate. - FunctionTemplateDecl *FunctionTemplate; - - /// \brief The function type that describes the entity being called, - /// when Kind == CK_FunctionType. - const FunctionType *Type; - }; - - public: - OverloadCandidate(FunctionDecl *Function) - : Kind(CK_Function), Function(Function) { } - - OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl) - : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { } - - OverloadCandidate(const FunctionType *Type) - : Kind(CK_FunctionType), Type(Type) { } - - /// \brief Determine the kind of overload candidate. - CandidateKind getKind() const { return Kind; } - - /// \brief Retrieve the function overload candidate or the templated - /// function declaration for a function template. - FunctionDecl *getFunction() const; - - /// \brief Retrieve the function template overload candidate. - FunctionTemplateDecl *getFunctionTemplate() const { - assert(getKind() == CK_FunctionTemplate && "Not a function template"); - return FunctionTemplate; - } - - /// \brief Retrieve the function type of the entity, regardless of how the - /// function is stored. - const FunctionType *getFunctionType() const; - - /// \brief Create a new code-completion string that describes the function - /// signature of this overload candidate. - CodeCompletionString *CreateSignatureString(unsigned CurrentArg, - Sema &S, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments) const; - }; - - CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, - bool OutputIsBinary) - : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) - { } - - /// \brief Whether the code-completion consumer wants to see macros. - bool includeMacros() const { - return CodeCompleteOpts.IncludeMacros; - } - - /// \brief Whether the code-completion consumer wants to see code patterns. - bool includeCodePatterns() const { - return CodeCompleteOpts.IncludeCodePatterns; - } - - /// \brief Whether to include global (top-level) declaration results. - bool includeGlobals() const { - return CodeCompleteOpts.IncludeGlobals; - } - - /// \brief Whether to include brief documentation comments within the set of - /// code completions returned. - bool includeBriefComments() const { - return CodeCompleteOpts.IncludeBriefComments; - } - - /// \brief Determine whether the output of this consumer is binary. - bool isOutputBinary() const { return OutputIsBinary; } - - /// \brief Deregisters and destroys this code-completion consumer. - virtual ~CodeCompleteConsumer(); - - /// \name Code-completion callbacks - //@{ - /// \brief Process the finalized code-completion results. - virtual void ProcessCodeCompleteResults(Sema &S, - CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults) { } - - /// \param S the semantic-analyzer object for which code-completion is being - /// done. - /// - /// \param CurrentArg the index of the current argument. - /// - /// \param Candidates an array of overload candidates. - /// - /// \param NumCandidates the number of overload candidates - virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates) { } - //@} - - /// \brief Retrieve the allocator that will be used to allocate - /// code completion strings. - virtual CodeCompletionAllocator &getAllocator() = 0; - - virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0; -}; - -/// \brief A simple code-completion consumer that prints the results it -/// receives in a simple format. -class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { - /// \brief The raw output stream. - raw_ostream &OS; - - CodeCompletionTUInfo CCTUInfo; - -public: - /// \brief Create a new printing code-completion consumer that prints its - /// results to the given raw output stream. - PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, - raw_ostream &OS) - : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS), - CCTUInfo(new GlobalCodeCompletionAllocator) {} - - /// \brief Prints the finalized code-completion results. - void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults) override; - - void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates) override; - - CodeCompletionAllocator &getAllocator() override { - return CCTUInfo.getAllocator(); - } - - CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; } -}; - -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h deleted file mode 100644 index fc7713c..0000000 --- a/include/clang/Sema/CodeCompleteOptions.h +++ /dev/null @@ -1,41 +0,0 @@ -//===---- CodeCompleteOptions.h - Code Completion Options -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H -#define LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H - -namespace clang { - -/// Options controlling the behavior of code completion. -class CodeCompleteOptions { -public: - /// Show macros in code completion results. - unsigned IncludeMacros : 1; - - /// Show code patterns in code completion results. - unsigned IncludeCodePatterns : 1; - - /// Show top-level decls in code completion results. - unsigned IncludeGlobals : 1; - - /// Show brief documentation comments in code completion results. - unsigned IncludeBriefComments : 1; - - CodeCompleteOptions() : - IncludeMacros(0), - IncludeCodePatterns(0), - IncludeGlobals(1), - IncludeBriefComments(0) - { } -}; - -} // namespace clang - -#endif - diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h deleted file mode 100644 index e9fdb70..0000000 --- a/include/clang/Sema/DeclSpec.h +++ /dev/null @@ -1,2313 +0,0 @@ -//===--- DeclSpec.h - Parsed declaration specifiers -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief This file defines the classes used to store parsed information about -/// declaration-specifiers and declarators. -/// -/// \verbatim -/// static const int volatile x, *y, *(*(*z)[10])(const void *x); -/// ------------------------- - -- --------------------------- -/// declaration-specifiers \ | / -/// declarators -/// \endverbatim -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_DECLSPEC_H -#define LLVM_CLANG_SEMA_DECLSPEC_H - -#include "clang/AST/NestedNameSpecifier.h" -#include "clang/Basic/ExceptionSpecificationType.h" -#include "clang/Basic/Lambda.h" -#include "clang/Basic/OperatorKinds.h" -#include "clang/Basic/Specifiers.h" -#include "clang/Lex/Token.h" -#include "clang/Sema/AttributeList.h" -#include "clang/Sema/Ownership.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" - -namespace clang { - class ASTContext; - class CXXRecordDecl; - class TypeLoc; - class LangOptions; - class IdentifierInfo; - class NamespaceAliasDecl; - class NamespaceDecl; - class ObjCDeclSpec; - class Sema; - class Declarator; - struct TemplateIdAnnotation; - -/// \brief Represents a C++ nested-name-specifier or a global scope specifier. -/// -/// These can be in 3 states: -/// 1) Not present, identified by isEmpty() -/// 2) Present, identified by isNotEmpty() -/// 2.a) Valid, identified by isValid() -/// 2.b) Invalid, identified by isInvalid(). -/// -/// isSet() is deprecated because it mostly corresponded to "valid" but was -/// often used as if it meant "present". -/// -/// The actual scope is described by getScopeRep(). -class CXXScopeSpec { - SourceRange Range; - NestedNameSpecifierLocBuilder Builder; - -public: - SourceRange getRange() const { return Range; } - void setRange(SourceRange R) { Range = R; } - void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } - void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } - SourceLocation getBeginLoc() const { return Range.getBegin(); } - SourceLocation getEndLoc() const { return Range.getEnd(); } - - /// \brief Retrieve the representation of the nested-name-specifier. - NestedNameSpecifier *getScopeRep() const { - return Builder.getRepresentation(); - } - - /// \brief Extend the current nested-name-specifier by another - /// nested-name-specifier component of the form 'type::'. - /// - /// \param Context The AST context in which this nested-name-specifier - /// resides. - /// - /// \param TemplateKWLoc The location of the 'template' keyword, if present. - /// - /// \param TL The TypeLoc that describes the type preceding the '::'. - /// - /// \param ColonColonLoc The location of the trailing '::'. - void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, - SourceLocation ColonColonLoc); - - /// \brief Extend the current nested-name-specifier by another - /// nested-name-specifier component of the form 'identifier::'. - /// - /// \param Context The AST context in which this nested-name-specifier - /// resides. - /// - /// \param Identifier The identifier. - /// - /// \param IdentifierLoc The location of the identifier. - /// - /// \param ColonColonLoc The location of the trailing '::'. - void Extend(ASTContext &Context, IdentifierInfo *Identifier, - SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); - - /// \brief Extend the current nested-name-specifier by another - /// nested-name-specifier component of the form 'namespace::'. - /// - /// \param Context The AST context in which this nested-name-specifier - /// resides. - /// - /// \param Namespace The namespace. - /// - /// \param NamespaceLoc The location of the namespace name. - /// - /// \param ColonColonLoc The location of the trailing '::'. - void Extend(ASTContext &Context, NamespaceDecl *Namespace, - SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); - - /// \brief Extend the current nested-name-specifier by another - /// nested-name-specifier component of the form 'namespace-alias::'. - /// - /// \param Context The AST context in which this nested-name-specifier - /// resides. - /// - /// \param Alias The namespace alias. - /// - /// \param AliasLoc The location of the namespace alias - /// name. - /// - /// \param ColonColonLoc The location of the trailing '::'. - void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, - SourceLocation AliasLoc, SourceLocation ColonColonLoc); - - /// \brief Turn this (empty) nested-name-specifier into the global - /// nested-name-specifier '::'. - void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); - - /// \brief Turns this (empty) nested-name-specifier into '__super' - /// nested-name-specifier. - /// - /// \param Context The AST context in which this nested-name-specifier - /// resides. - /// - /// \param RD The declaration of the class in which nested-name-specifier - /// appeared. - /// - /// \param SuperLoc The location of the '__super' keyword. - /// name. - /// - /// \param ColonColonLoc The location of the trailing '::'. - void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, - SourceLocation SuperLoc, SourceLocation ColonColonLoc); - - /// \brief Make a new nested-name-specifier from incomplete source-location - /// information. - /// - /// FIXME: This routine should be used very, very rarely, in cases where we - /// need to synthesize a nested-name-specifier. Most code should instead use - /// \c Adopt() with a proper \c NestedNameSpecifierLoc. - void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, - SourceRange R); - - /// \brief Adopt an existing nested-name-specifier (with source-range - /// information). - void Adopt(NestedNameSpecifierLoc Other); - - /// \brief Retrieve a nested-name-specifier with location information, copied - /// into the given AST context. - /// - /// \param Context The context into which this nested-name-specifier will be - /// copied. - NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; - - /// \brief Retrieve the location of the name in the last qualifier - /// in this nested name specifier. - /// - /// For example, the location of \c bar - /// in - /// \verbatim - /// \::foo::bar<0>:: - /// ^~~ - /// \endverbatim - SourceLocation getLastQualifierNameLoc() const; - - /// No scope specifier. - bool isEmpty() const { return !Range.isValid(); } - /// A scope specifier is present, but may be valid or invalid. - bool isNotEmpty() const { return !isEmpty(); } - - /// An error occurred during parsing of the scope specifier. - bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; } - /// A scope specifier is present, and it refers to a real scope. - bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; } - - /// \brief Indicate that this nested-name-specifier is invalid. - void SetInvalid(SourceRange R) { - assert(R.isValid() && "Must have a valid source range"); - if (Range.getBegin().isInvalid()) - Range.setBegin(R.getBegin()); - Range.setEnd(R.getEnd()); - Builder.Clear(); - } - - /// Deprecated. Some call sites intend isNotEmpty() while others intend - /// isValid(). - bool isSet() const { return getScopeRep() != nullptr; } - - void clear() { - Range = SourceRange(); - Builder.Clear(); - } - - /// \brief Retrieve the data associated with the source-location information. - char *location_data() const { return Builder.getBuffer().first; } - - /// \brief Retrieve the size of the data associated with source-location - /// information. - unsigned location_size() const { return Builder.getBuffer().second; } -}; - -/// \brief Captures information about "declaration specifiers". -/// -/// "Declaration specifiers" encompasses storage-class-specifiers, -/// type-specifiers, type-qualifiers, and function-specifiers. -class DeclSpec { -public: - /// \brief storage-class-specifier - /// \note The order of these enumerators is important for diagnostics. - enum SCS { - SCS_unspecified = 0, - SCS_typedef, - SCS_extern, - SCS_static, - SCS_auto, - SCS_register, - SCS_private_extern, - SCS_mutable - }; - - // Import thread storage class specifier enumeration and constants. - // These can be combined with SCS_extern and SCS_static. - typedef ThreadStorageClassSpecifier TSCS; - static const TSCS TSCS_unspecified = clang::TSCS_unspecified; - static const TSCS TSCS___thread = clang::TSCS___thread; - static const TSCS TSCS_thread_local = clang::TSCS_thread_local; - static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local; - - // Import type specifier width enumeration and constants. - typedef TypeSpecifierWidth TSW; - static const TSW TSW_unspecified = clang::TSW_unspecified; - static const TSW TSW_short = clang::TSW_short; - static const TSW TSW_long = clang::TSW_long; - static const TSW TSW_longlong = clang::TSW_longlong; - - enum TSC { - TSC_unspecified, - TSC_imaginary, - TSC_complex - }; - - // Import type specifier sign enumeration and constants. - typedef TypeSpecifierSign TSS; - static const TSS TSS_unspecified = clang::TSS_unspecified; - static const TSS TSS_signed = clang::TSS_signed; - static const TSS TSS_unsigned = clang::TSS_unsigned; - - // Import type specifier type enumeration and constants. - typedef TypeSpecifierType TST; - static const TST TST_unspecified = clang::TST_unspecified; - static const TST TST_void = clang::TST_void; - static const TST TST_char = clang::TST_char; - static const TST TST_wchar = clang::TST_wchar; - static const TST TST_char16 = clang::TST_char16; - static const TST TST_char32 = clang::TST_char32; - static const TST TST_int = clang::TST_int; - static const TST TST_int128 = clang::TST_int128; - static const TST TST_half = clang::TST_half; - static const TST TST_float = clang::TST_float; - static const TST TST_double = clang::TST_double; - static const TST TST_bool = clang::TST_bool; - static const TST TST_decimal32 = clang::TST_decimal32; - static const TST TST_decimal64 = clang::TST_decimal64; - static const TST TST_decimal128 = clang::TST_decimal128; - static const TST TST_enum = clang::TST_enum; - static const TST TST_union = clang::TST_union; - static const TST TST_struct = clang::TST_struct; - static const TST TST_interface = clang::TST_interface; - static const TST TST_class = clang::TST_class; - static const TST TST_typename = clang::TST_typename; - static const TST TST_typeofType = clang::TST_typeofType; - static const TST TST_typeofExpr = clang::TST_typeofExpr; - static const TST TST_decltype = clang::TST_decltype; - static const TST TST_decltype_auto = clang::TST_decltype_auto; - static const TST TST_underlyingType = clang::TST_underlyingType; - static const TST TST_auto = clang::TST_auto; - static const TST TST_auto_type = clang::TST_auto_type; - static const TST TST_unknown_anytype = clang::TST_unknown_anytype; - static const TST TST_atomic = clang::TST_atomic; - static const TST TST_error = clang::TST_error; - - // type-qualifiers - enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ. - TQ_unspecified = 0, - TQ_const = 1, - TQ_restrict = 2, - TQ_volatile = 4, - // This has no corresponding Qualifiers::TQ value, because it's not treated - // as a qualifier in our type system. - TQ_atomic = 8 - }; - - /// ParsedSpecifiers - Flags to query which specifiers were applied. This is - /// returned by getParsedSpecifiers. - enum ParsedSpecifiers { - PQ_None = 0, - PQ_StorageClassSpecifier = 1, - PQ_TypeSpecifier = 2, - PQ_TypeQualifier = 4, - PQ_FunctionSpecifier = 8 - }; - -private: - // storage-class-specifier - /*SCS*/unsigned StorageClassSpec : 3; - /*TSCS*/unsigned ThreadStorageClassSpec : 2; - unsigned SCS_extern_in_linkage_spec : 1; - - // type-specifier - /*TSW*/unsigned TypeSpecWidth : 2; - /*TSC*/unsigned TypeSpecComplex : 2; - /*TSS*/unsigned TypeSpecSign : 2; - /*TST*/unsigned TypeSpecType : 6; - unsigned TypeAltiVecVector : 1; - unsigned TypeAltiVecPixel : 1; - unsigned TypeAltiVecBool : 1; - unsigned TypeSpecOwned : 1; - - // type-qualifiers - unsigned TypeQualifiers : 4; // Bitwise OR of TQ. - - // function-specifier - unsigned FS_inline_specified : 1; - unsigned FS_forceinline_specified: 1; - unsigned FS_virtual_specified : 1; - unsigned FS_explicit_specified : 1; - unsigned FS_noreturn_specified : 1; - - // friend-specifier - unsigned Friend_specified : 1; - - // constexpr-specifier - unsigned Constexpr_specified : 1; - - // concept-specifier - unsigned Concept_specified : 1; - - union { - UnionParsedType TypeRep; - Decl *DeclRep; - Expr *ExprRep; - }; - - // attributes. - ParsedAttributes Attrs; - - // Scope specifier for the type spec, if applicable. - CXXScopeSpec TypeScope; - - // SourceLocation info. These are null if the item wasn't specified or if - // the setting was synthesized. - SourceRange Range; - - SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc; - SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc; - /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, - /// typename, then this is the location of the named type (if present); - /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and - /// TSTNameLoc provides source range info for tag types. - SourceLocation TSTNameLoc; - SourceRange TypeofParensRange; - SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; - SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; - SourceLocation FS_forceinlineLoc; - SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc, ConceptLoc; - - WrittenBuiltinSpecs writtenBS; - void SaveWrittenBuiltinSpecs(); - - ObjCDeclSpec *ObjCQualifiers; - - static bool isTypeRep(TST T) { - return (T == TST_typename || T == TST_typeofType || - T == TST_underlyingType || T == TST_atomic); - } - static bool isExprRep(TST T) { - return (T == TST_typeofExpr || T == TST_decltype); - } - - DeclSpec(const DeclSpec &) = delete; - void operator=(const DeclSpec &) = delete; -public: - static bool isDeclRep(TST T) { - return (T == TST_enum || T == TST_struct || - T == TST_interface || T == TST_union || - T == TST_class); - } - - DeclSpec(AttributeFactory &attrFactory) - : StorageClassSpec(SCS_unspecified), - ThreadStorageClassSpec(TSCS_unspecified), - SCS_extern_in_linkage_spec(false), - TypeSpecWidth(TSW_unspecified), - TypeSpecComplex(TSC_unspecified), - TypeSpecSign(TSS_unspecified), - TypeSpecType(TST_unspecified), - TypeAltiVecVector(false), - TypeAltiVecPixel(false), - TypeAltiVecBool(false), - TypeSpecOwned(false), - TypeQualifiers(TQ_unspecified), - FS_inline_specified(false), - FS_forceinline_specified(false), - FS_virtual_specified(false), - FS_explicit_specified(false), - FS_noreturn_specified(false), - Friend_specified(false), - Constexpr_specified(false), - Concept_specified(false), - Attrs(attrFactory), - writtenBS(), - ObjCQualifiers(nullptr) { - } - - // storage-class-specifier - SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } - TSCS getThreadStorageClassSpec() const { - return (TSCS)ThreadStorageClassSpec; - } - bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; } - void setExternInLinkageSpec(bool Value) { - SCS_extern_in_linkage_spec = Value; - } - - SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; } - SourceLocation getThreadStorageClassSpecLoc() const { - return ThreadStorageClassSpecLoc; - } - - void ClearStorageClassSpecs() { - StorageClassSpec = DeclSpec::SCS_unspecified; - ThreadStorageClassSpec = DeclSpec::TSCS_unspecified; - SCS_extern_in_linkage_spec = false; - StorageClassSpecLoc = SourceLocation(); - ThreadStorageClassSpecLoc = SourceLocation(); - } - - void ClearTypeSpecType() { - TypeSpecType = DeclSpec::TST_unspecified; - TypeSpecOwned = false; - TSTLoc = SourceLocation(); - } - - // type-specifier - TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; } - TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; } - TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; } - TST getTypeSpecType() const { return (TST)TypeSpecType; } - bool isTypeAltiVecVector() const { return TypeAltiVecVector; } - bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; } - bool isTypeAltiVecBool() const { return TypeAltiVecBool; } - bool isTypeSpecOwned() const { return TypeSpecOwned; } - bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); } - - ParsedType getRepAsType() const { - assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); - return TypeRep; - } - Decl *getRepAsDecl() const { - assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl"); - return DeclRep; - } - Expr *getRepAsExpr() const { - assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr"); - return ExprRep; - } - CXXScopeSpec &getTypeSpecScope() { return TypeScope; } - const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } - - SourceRange getSourceRange() const LLVM_READONLY { return Range; } - SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } - SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } - - SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; } - SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; } - SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } - SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } - SourceLocation getAltiVecLoc() const { return AltiVecLoc; } - - SourceLocation getTypeSpecTypeNameLoc() const { - assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename); - return TSTNameLoc; - } - - SourceRange getTypeofParensRange() const { return TypeofParensRange; } - void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } - - bool containsPlaceholderType() const { - return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type || - TypeSpecType == TST_decltype_auto); - } - - bool hasTagDefinition() const; - - /// \brief Turn a type-specifier-type into a string like "_Bool" or "union". - static const char *getSpecifierName(DeclSpec::TST T, - const PrintingPolicy &Policy); - static const char *getSpecifierName(DeclSpec::TQ Q); - static const char *getSpecifierName(DeclSpec::TSS S); - static const char *getSpecifierName(DeclSpec::TSC C); - static const char *getSpecifierName(DeclSpec::TSW W); - static const char *getSpecifierName(DeclSpec::SCS S); - static const char *getSpecifierName(DeclSpec::TSCS S); - - // type-qualifiers - - /// getTypeQualifiers - Return a set of TQs. - unsigned getTypeQualifiers() const { return TypeQualifiers; } - SourceLocation getConstSpecLoc() const { return TQ_constLoc; } - SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } - SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } - SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } - - /// \brief Clear out all of the type qualifiers. - void ClearTypeQualifiers() { - TypeQualifiers = 0; - TQ_constLoc = SourceLocation(); - TQ_restrictLoc = SourceLocation(); - TQ_volatileLoc = SourceLocation(); - TQ_atomicLoc = SourceLocation(); - } - - // function-specifier - bool isInlineSpecified() const { - return FS_inline_specified | FS_forceinline_specified; - } - SourceLocation getInlineSpecLoc() const { - return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc; - } - - bool isVirtualSpecified() const { return FS_virtual_specified; } - SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; } - - bool isExplicitSpecified() const { return FS_explicit_specified; } - SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; } - - bool isNoreturnSpecified() const { return FS_noreturn_specified; } - SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; } - - void ClearFunctionSpecs() { - FS_inline_specified = false; - FS_inlineLoc = SourceLocation(); - FS_forceinline_specified = false; - FS_forceinlineLoc = SourceLocation(); - FS_virtual_specified = false; - FS_virtualLoc = SourceLocation(); - FS_explicit_specified = false; - FS_explicitLoc = SourceLocation(); - FS_noreturn_specified = false; - FS_noreturnLoc = SourceLocation(); - } - - /// \brief Return true if any type-specifier has been found. - bool hasTypeSpecifier() const { - return getTypeSpecType() != DeclSpec::TST_unspecified || - getTypeSpecWidth() != DeclSpec::TSW_unspecified || - getTypeSpecComplex() != DeclSpec::TSC_unspecified || - getTypeSpecSign() != DeclSpec::TSS_unspecified; - } - - /// \brief Return a bitmask of which flavors of specifiers this - /// DeclSpec includes. - unsigned getParsedSpecifiers() const; - - /// isEmpty - Return true if this declaration specifier is completely empty: - /// no tokens were parsed in the production of it. - bool isEmpty() const { - return getParsedSpecifiers() == DeclSpec::PQ_None; - } - - void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); } - void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); } - - /// These methods set the specified attribute of the DeclSpec and - /// return false if there was no error. If an error occurs (for - /// example, if we tried to set "auto" on a spec with "extern" - /// already set), they return true and set PrevSpec and DiagID - /// such that - /// Diag(Loc, DiagID) << PrevSpec; - /// will yield a useful result. - /// - /// TODO: use a more general approach that still allows these - /// diagnostics to be ignored when desired. - bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID, - const PrintingPolicy &Policy); - bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID); - bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const PrintingPolicy &Policy); - bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const PrintingPolicy &Policy); - bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, ParsedType Rep, - const PrintingPolicy &Policy); - bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, Decl *Rep, bool Owned, - const PrintingPolicy &Policy); - bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, - SourceLocation TagNameLoc, const char *&PrevSpec, - unsigned &DiagID, ParsedType Rep, - const PrintingPolicy &Policy); - bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, - SourceLocation TagNameLoc, const char *&PrevSpec, - unsigned &DiagID, Decl *Rep, bool Owned, - const PrintingPolicy &Policy); - - bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, Expr *Rep, - const PrintingPolicy &policy); - bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID, - const PrintingPolicy &Policy); - bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID, - const PrintingPolicy &Policy); - bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID, - const PrintingPolicy &Policy); - bool SetTypeSpecError(); - void UpdateDeclRep(Decl *Rep) { - assert(isDeclRep((TST) TypeSpecType)); - DeclRep = Rep; - } - void UpdateTypeRep(ParsedType Rep) { - assert(isTypeRep((TST) TypeSpecType)); - TypeRep = Rep; - } - void UpdateExprRep(Expr *Rep) { - assert(isExprRep((TST) TypeSpecType)); - ExprRep = Rep; - } - - bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang); - - bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - - bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - bool SetConceptSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); - - bool isFriendSpecified() const { return Friend_specified; } - SourceLocation getFriendSpecLoc() const { return FriendLoc; } - - bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); } - SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } - - bool isConstexprSpecified() const { return Constexpr_specified; } - SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } - - bool isConceptSpecified() const { return Concept_specified; } - SourceLocation getConceptSpecLoc() const { return ConceptLoc; } - - void ClearConstexprSpec() { - Constexpr_specified = false; - ConstexprLoc = SourceLocation(); - } - - void ClearConceptSpec() { - Concept_specified = false; - ConceptLoc = SourceLocation(); - } - - AttributePool &getAttributePool() const { - return Attrs.getPool(); - } - - /// \brief Concatenates two attribute lists. - /// - /// The GCC attribute syntax allows for the following: - /// - /// \code - /// short __attribute__(( unused, deprecated )) - /// int __attribute__(( may_alias, aligned(16) )) var; - /// \endcode - /// - /// This declares 4 attributes using 2 lists. The following syntax is - /// also allowed and equivalent to the previous declaration. - /// - /// \code - /// short __attribute__((unused)) __attribute__((deprecated)) - /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; - /// \endcode - /// - void addAttributes(AttributeList *AL) { - Attrs.addAll(AL); - } - - bool hasAttributes() const { return !Attrs.empty(); } - - ParsedAttributes &getAttributes() { return Attrs; } - const ParsedAttributes &getAttributes() const { return Attrs; } - - void takeAttributesFrom(ParsedAttributes &attrs) { - Attrs.takeAllFrom(attrs); - } - - /// Finish - This does final analysis of the declspec, issuing diagnostics for - /// things like "_Imaginary" (lacking an FP type). After calling this method, - /// DeclSpec is guaranteed self-consistent, even if an error occurred. - void Finish(Sema &S, const PrintingPolicy &Policy); - - const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { - return writtenBS; - } - - ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; } - void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; } - - /// \brief Checks if this DeclSpec can stand alone, without a Declarator. - /// - /// Only tag declspecs can stand alone. - bool isMissingDeclaratorOk(); -}; - -/// \brief Captures information about "declaration specifiers" specific to -/// Objective-C. -class ObjCDeclSpec { -public: - /// ObjCDeclQualifier - Qualifier used on types in method - /// declarations. Not all combinations are sensible. Parameters - /// can be one of { in, out, inout } with one of { bycopy, byref }. - /// Returns can either be { oneway } or not. - /// - /// This should be kept in sync with Decl::ObjCDeclQualifier. - enum ObjCDeclQualifier { - DQ_None = 0x0, - DQ_In = 0x1, - DQ_Inout = 0x2, - DQ_Out = 0x4, - DQ_Bycopy = 0x8, - DQ_Byref = 0x10, - DQ_Oneway = 0x20, - DQ_CSNullability = 0x40 - }; - - /// PropertyAttributeKind - list of property attributes. - enum ObjCPropertyAttributeKind { - DQ_PR_noattr = 0x0, - DQ_PR_readonly = 0x01, - DQ_PR_getter = 0x02, - DQ_PR_assign = 0x04, - DQ_PR_readwrite = 0x08, - DQ_PR_retain = 0x10, - DQ_PR_copy = 0x20, - DQ_PR_nonatomic = 0x40, - DQ_PR_setter = 0x80, - DQ_PR_atomic = 0x100, - DQ_PR_weak = 0x200, - DQ_PR_strong = 0x400, - DQ_PR_unsafe_unretained = 0x800, - DQ_PR_nullability = 0x1000, - DQ_PR_null_resettable = 0x2000 - }; - - ObjCDeclSpec() - : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr), - Nullability(0), GetterName(nullptr), SetterName(nullptr) { } - - ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; } - void setObjCDeclQualifier(ObjCDeclQualifier DQVal) { - objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); - } - void clearObjCDeclQualifier(ObjCDeclQualifier DQVal) { - objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal); - } - - ObjCPropertyAttributeKind getPropertyAttributes() const { - return ObjCPropertyAttributeKind(PropertyAttributes); - } - void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) { - PropertyAttributes = - (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal); - } - - NullabilityKind getNullability() const { - assert(((getObjCDeclQualifier() & DQ_CSNullability) || - (getPropertyAttributes() & DQ_PR_nullability)) && - "Objective-C declspec doesn't have nullability"); - return static_cast<NullabilityKind>(Nullability); - } - - SourceLocation getNullabilityLoc() const { - assert(((getObjCDeclQualifier() & DQ_CSNullability) || - (getPropertyAttributes() & DQ_PR_nullability)) && - "Objective-C declspec doesn't have nullability"); - return NullabilityLoc; - } - - void setNullability(SourceLocation loc, NullabilityKind kind) { - assert(((getObjCDeclQualifier() & DQ_CSNullability) || - (getPropertyAttributes() & DQ_PR_nullability)) && - "Set the nullability declspec or property attribute first"); - Nullability = static_cast<unsigned>(kind); - NullabilityLoc = loc; - } - - const IdentifierInfo *getGetterName() const { return GetterName; } - IdentifierInfo *getGetterName() { return GetterName; } - void setGetterName(IdentifierInfo *name) { GetterName = name; } - - const IdentifierInfo *getSetterName() const { return SetterName; } - IdentifierInfo *getSetterName() { return SetterName; } - void setSetterName(IdentifierInfo *name) { SetterName = name; } - -private: - // FIXME: These two are unrelated and mutually exclusive. So perhaps - // we can put them in a union to reflect their mutual exclusivity - // (space saving is negligible). - ObjCDeclQualifier objcDeclQualifier : 7; - - // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind - unsigned PropertyAttributes : 14; - - unsigned Nullability : 2; - - SourceLocation NullabilityLoc; - - IdentifierInfo *GetterName; // getter name or NULL if no getter - IdentifierInfo *SetterName; // setter name or NULL if no setter -}; - -/// \brief Represents a C++ unqualified-id that has been parsed. -class UnqualifiedId { -private: - UnqualifiedId(const UnqualifiedId &Other) = delete; - const UnqualifiedId &operator=(const UnqualifiedId &) = delete; - -public: - /// \brief Describes the kind of unqualified-id parsed. - enum IdKind { - /// \brief An identifier. - IK_Identifier, - /// \brief An overloaded operator name, e.g., operator+. - IK_OperatorFunctionId, - /// \brief A conversion function name, e.g., operator int. - IK_ConversionFunctionId, - /// \brief A user-defined literal name, e.g., operator "" _i. - IK_LiteralOperatorId, - /// \brief A constructor name. - IK_ConstructorName, - /// \brief A constructor named via a template-id. - IK_ConstructorTemplateId, - /// \brief A destructor name. - IK_DestructorName, - /// \brief A template-id, e.g., f<int>. - IK_TemplateId, - /// \brief An implicit 'self' parameter - IK_ImplicitSelfParam - } Kind; - - struct OFI { - /// \brief The kind of overloaded operator. - OverloadedOperatorKind Operator; - - /// \brief The source locations of the individual tokens that name - /// the operator, e.g., the "new", "[", and "]" tokens in - /// operator new []. - /// - /// Different operators have different numbers of tokens in their name, - /// up to three. Any remaining source locations in this array will be - /// set to an invalid value for operators with fewer than three tokens. - unsigned SymbolLocations[3]; - }; - - /// \brief Anonymous union that holds extra data associated with the - /// parsed unqualified-id. - union { - /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind - /// == IK_UserLiteralId, the identifier suffix. - IdentifierInfo *Identifier; - - /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator - /// that we parsed. - struct OFI OperatorFunctionId; - - /// \brief When Kind == IK_ConversionFunctionId, the type that the - /// conversion function names. - UnionParsedType ConversionFunctionId; - - /// \brief When Kind == IK_ConstructorName, the class-name of the type - /// whose constructor is being referenced. - UnionParsedType ConstructorName; - - /// \brief When Kind == IK_DestructorName, the type referred to by the - /// class-name. - UnionParsedType DestructorName; - - /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId, - /// the template-id annotation that contains the template name and - /// template arguments. - TemplateIdAnnotation *TemplateId; - }; - - /// \brief The location of the first token that describes this unqualified-id, - /// which will be the location of the identifier, "operator" keyword, - /// tilde (for a destructor), or the template name of a template-id. - SourceLocation StartLocation; - - /// \brief The location of the last token that describes this unqualified-id. - SourceLocation EndLocation; - - UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { } - - /// \brief Clear out this unqualified-id, setting it to default (invalid) - /// state. - void clear() { - Kind = IK_Identifier; - Identifier = nullptr; - StartLocation = SourceLocation(); - EndLocation = SourceLocation(); - } - - /// \brief Determine whether this unqualified-id refers to a valid name. - bool isValid() const { return StartLocation.isValid(); } - - /// \brief Determine whether this unqualified-id refers to an invalid name. - bool isInvalid() const { return !isValid(); } - - /// \brief Determine what kind of name we have. - IdKind getKind() const { return Kind; } - void setKind(IdKind kind) { Kind = kind; } - - /// \brief Specify that this unqualified-id was parsed as an identifier. - /// - /// \param Id the parsed identifier. - /// \param IdLoc the location of the parsed identifier. - void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) { - Kind = IK_Identifier; - Identifier = const_cast<IdentifierInfo *>(Id); - StartLocation = EndLocation = IdLoc; - } - - /// \brief Specify that this unqualified-id was parsed as an - /// operator-function-id. - /// - /// \param OperatorLoc the location of the 'operator' keyword. - /// - /// \param Op the overloaded operator. - /// - /// \param SymbolLocations the locations of the individual operator symbols - /// in the operator. - void setOperatorFunctionId(SourceLocation OperatorLoc, - OverloadedOperatorKind Op, - SourceLocation SymbolLocations[3]); - - /// \brief Specify that this unqualified-id was parsed as a - /// conversion-function-id. - /// - /// \param OperatorLoc the location of the 'operator' keyword. - /// - /// \param Ty the type to which this conversion function is converting. - /// - /// \param EndLoc the location of the last token that makes up the type name. - void setConversionFunctionId(SourceLocation OperatorLoc, - ParsedType Ty, - SourceLocation EndLoc) { - Kind = IK_ConversionFunctionId; - StartLocation = OperatorLoc; - EndLocation = EndLoc; - ConversionFunctionId = Ty; - } - - /// \brief Specific that this unqualified-id was parsed as a - /// literal-operator-id. - /// - /// \param Id the parsed identifier. - /// - /// \param OpLoc the location of the 'operator' keyword. - /// - /// \param IdLoc the location of the identifier. - void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc, - SourceLocation IdLoc) { - Kind = IK_LiteralOperatorId; - Identifier = const_cast<IdentifierInfo *>(Id); - StartLocation = OpLoc; - EndLocation = IdLoc; - } - - /// \brief Specify that this unqualified-id was parsed as a constructor name. - /// - /// \param ClassType the class type referred to by the constructor name. - /// - /// \param ClassNameLoc the location of the class name. - /// - /// \param EndLoc the location of the last token that makes up the type name. - void setConstructorName(ParsedType ClassType, - SourceLocation ClassNameLoc, - SourceLocation EndLoc) { - Kind = IK_ConstructorName; - StartLocation = ClassNameLoc; - EndLocation = EndLoc; - ConstructorName = ClassType; - } - - /// \brief Specify that this unqualified-id was parsed as a - /// template-id that names a constructor. - /// - /// \param TemplateId the template-id annotation that describes the parsed - /// template-id. This UnqualifiedId instance will take ownership of the - /// \p TemplateId and will free it on destruction. - void setConstructorTemplateId(TemplateIdAnnotation *TemplateId); - - /// \brief Specify that this unqualified-id was parsed as a destructor name. - /// - /// \param TildeLoc the location of the '~' that introduces the destructor - /// name. - /// - /// \param ClassType the name of the class referred to by the destructor name. - void setDestructorName(SourceLocation TildeLoc, - ParsedType ClassType, - SourceLocation EndLoc) { - Kind = IK_DestructorName; - StartLocation = TildeLoc; - EndLocation = EndLoc; - DestructorName = ClassType; - } - - /// \brief Specify that this unqualified-id was parsed as a template-id. - /// - /// \param TemplateId the template-id annotation that describes the parsed - /// template-id. This UnqualifiedId instance will take ownership of the - /// \p TemplateId and will free it on destruction. - void setTemplateId(TemplateIdAnnotation *TemplateId); - - /// \brief Return the source range that covers this unqualified-id. - SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(StartLocation, EndLocation); - } - SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; } - SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; } -}; - -/// \brief A set of tokens that has been cached for later parsing. -typedef SmallVector<Token, 4> CachedTokens; - -/// \brief One instance of this struct is used for each type in a -/// declarator that is parsed. -/// -/// This is intended to be a small value object. -struct DeclaratorChunk { - enum { - Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren - } Kind; - - /// Loc - The place where this type was defined. - SourceLocation Loc; - /// EndLoc - If valid, the place where this chunck ends. - SourceLocation EndLoc; - - SourceRange getSourceRange() const { - if (EndLoc.isInvalid()) - return SourceRange(Loc, Loc); - return SourceRange(Loc, EndLoc); - } - - struct TypeInfoCommon { - AttributeList *AttrList; - }; - - struct PointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict/atomic. - unsigned TypeQuals : 4; - - /// The location of the const-qualifier, if any. - unsigned ConstQualLoc; - - /// The location of the volatile-qualifier, if any. - unsigned VolatileQualLoc; - - /// The location of the restrict-qualifier, if any. - unsigned RestrictQualLoc; - - /// The location of the _Atomic-qualifier, if any. - unsigned AtomicQualLoc; - - void destroy() { - } - }; - - struct ReferenceTypeInfo : TypeInfoCommon { - /// The type qualifier: restrict. [GNU] C++ extension - bool HasRestrict : 1; - /// True if this is an lvalue reference, false if it's an rvalue reference. - bool LValueRef : 1; - void destroy() { - } - }; - - struct ArrayTypeInfo : TypeInfoCommon { - /// The type qualifiers for the array: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; - - /// True if this dimension included the 'static' keyword. - bool hasStatic : 1; - - /// True if this dimension was [*]. In this case, NumElts is null. - bool isStar : 1; - - /// This is the size of the array, or null if [] or [*] was specified. - /// Since the parser is multi-purpose, and we don't want to impose a root - /// expression class on all clients, NumElts is untyped. - Expr *NumElts; - - void destroy() {} - }; - - /// ParamInfo - An array of paraminfo objects is allocated whenever a function - /// declarator is parsed. There are two interesting styles of parameters - /// here: - /// K&R-style identifier lists and parameter type lists. K&R-style identifier - /// lists will have information about the identifier, but no type information. - /// Parameter type lists will have type info (if the actions module provides - /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'. - struct ParamInfo { - IdentifierInfo *Ident; - SourceLocation IdentLoc; - Decl *Param; - - /// DefaultArgTokens - When the parameter's default argument - /// cannot be parsed immediately (because it occurs within the - /// declaration of a member function), it will be stored here as a - /// sequence of tokens to be parsed once the class definition is - /// complete. Non-NULL indicates that there is a default argument. - CachedTokens *DefaultArgTokens; - - ParamInfo() {} - ParamInfo(IdentifierInfo *ident, SourceLocation iloc, - Decl *param, - CachedTokens *DefArgTokens = nullptr) - : Ident(ident), IdentLoc(iloc), Param(param), - DefaultArgTokens(DefArgTokens) {} - }; - - struct TypeAndRange { - ParsedType Ty; - SourceRange Range; - }; - - struct FunctionTypeInfo : TypeInfoCommon { - /// hasPrototype - This is true if the function had at least one typed - /// parameter. If the function is () or (a,b,c), then it has no prototype, - /// and is treated as a K&R-style function. - unsigned hasPrototype : 1; - - /// isVariadic - If this function has a prototype, and if that - /// proto ends with ',...)', this is true. When true, EllipsisLoc - /// contains the location of the ellipsis. - unsigned isVariadic : 1; - - /// Can this declaration be a constructor-style initializer? - unsigned isAmbiguous : 1; - - /// \brief Whether the ref-qualifier (if any) is an lvalue reference. - /// Otherwise, it's an rvalue reference. - unsigned RefQualifierIsLValueRef : 1; - - /// The type qualifiers: const/volatile/restrict. - /// The qualifier bitmask values are the same as in QualType. - unsigned TypeQuals : 3; - - /// ExceptionSpecType - An ExceptionSpecificationType value. - unsigned ExceptionSpecType : 4; - - /// DeleteParams - If this is true, we need to delete[] Params. - unsigned DeleteParams : 1; - - /// HasTrailingReturnType - If this is true, a trailing return type was - /// specified. - unsigned HasTrailingReturnType : 1; - - /// The location of the left parenthesis in the source. - unsigned LParenLoc; - - /// When isVariadic is true, the location of the ellipsis in the source. - unsigned EllipsisLoc; - - /// The location of the right parenthesis in the source. - unsigned RParenLoc; - - /// NumParams - This is the number of formal parameters specified by the - /// declarator. - unsigned NumParams; - - /// NumExceptions - This is the number of types in the dynamic-exception- - /// decl, if the function has one. - unsigned NumExceptions; - - /// \brief The location of the ref-qualifier, if any. - /// - /// If this is an invalid location, there is no ref-qualifier. - unsigned RefQualifierLoc; - - /// \brief The location of the const-qualifier, if any. - /// - /// If this is an invalid location, there is no const-qualifier. - unsigned ConstQualifierLoc; - - /// \brief The location of the volatile-qualifier, if any. - /// - /// If this is an invalid location, there is no volatile-qualifier. - unsigned VolatileQualifierLoc; - - /// \brief The location of the restrict-qualifier, if any. - /// - /// If this is an invalid location, there is no restrict-qualifier. - unsigned RestrictQualifierLoc; - - /// \brief The location of the 'mutable' qualifer in a lambda-declarator, if - /// any. - unsigned MutableLoc; - - /// \brief The beginning location of the exception specification, if any. - unsigned ExceptionSpecLocBeg; - - /// \brief The end location of the exception specification, if any. - unsigned ExceptionSpecLocEnd; - - /// Params - This is a pointer to a new[]'d array of ParamInfo objects that - /// describe the parameters specified by this function declarator. null if - /// there are no parameters specified. - ParamInfo *Params; - - union { - /// \brief Pointer to a new[]'d array of TypeAndRange objects that - /// contain the types in the function's dynamic exception specification - /// and their locations, if there is one. - TypeAndRange *Exceptions; - - /// \brief Pointer to the expression in the noexcept-specifier of this - /// function, if it has one. - Expr *NoexceptExpr; - - /// \brief Pointer to the cached tokens for an exception-specification - /// that has not yet been parsed. - CachedTokens *ExceptionSpecTokens; - }; - - /// \brief If HasTrailingReturnType is true, this is the trailing return - /// type specified. - UnionParsedType TrailingReturnType; - - /// \brief Reset the parameter list to having zero parameters. - /// - /// This is used in various places for error recovery. - void freeParams() { - for (unsigned I = 0; I < NumParams; ++I) { - delete Params[I].DefaultArgTokens; - Params[I].DefaultArgTokens = nullptr; - } - if (DeleteParams) { - delete[] Params; - DeleteParams = false; - } - NumParams = 0; - } - - void destroy() { - if (DeleteParams) - delete[] Params; - if (getExceptionSpecType() == EST_Dynamic) - delete[] Exceptions; - else if (getExceptionSpecType() == EST_Unparsed) - delete ExceptionSpecTokens; - } - - /// isKNRPrototype - Return true if this is a K&R style identifier list, - /// like "void foo(a,b,c)". In a function definition, this will be followed - /// by the parameter type definitions. - bool isKNRPrototype() const { return !hasPrototype && NumParams != 0; } - - SourceLocation getLParenLoc() const { - return SourceLocation::getFromRawEncoding(LParenLoc); - } - - SourceLocation getEllipsisLoc() const { - return SourceLocation::getFromRawEncoding(EllipsisLoc); - } - - SourceLocation getRParenLoc() const { - return SourceLocation::getFromRawEncoding(RParenLoc); - } - - SourceLocation getExceptionSpecLocBeg() const { - return SourceLocation::getFromRawEncoding(ExceptionSpecLocBeg); - } - - SourceLocation getExceptionSpecLocEnd() const { - return SourceLocation::getFromRawEncoding(ExceptionSpecLocEnd); - } - - SourceRange getExceptionSpecRange() const { - return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd()); - } - - /// \brief Retrieve the location of the ref-qualifier, if any. - SourceLocation getRefQualifierLoc() const { - return SourceLocation::getFromRawEncoding(RefQualifierLoc); - } - - /// \brief Retrieve the location of the 'const' qualifier, if any. - SourceLocation getConstQualifierLoc() const { - return SourceLocation::getFromRawEncoding(ConstQualifierLoc); - } - - /// \brief Retrieve the location of the 'volatile' qualifier, if any. - SourceLocation getVolatileQualifierLoc() const { - return SourceLocation::getFromRawEncoding(VolatileQualifierLoc); - } - - /// \brief Retrieve the location of the 'restrict' qualifier, if any. - SourceLocation getRestrictQualifierLoc() const { - return SourceLocation::getFromRawEncoding(RestrictQualifierLoc); - } - - /// \brief Retrieve the location of the 'mutable' qualifier, if any. - SourceLocation getMutableLoc() const { - return SourceLocation::getFromRawEncoding(MutableLoc); - } - - /// \brief Determine whether this function declaration contains a - /// ref-qualifier. - bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } - - /// \brief Determine whether this lambda-declarator contains a 'mutable' - /// qualifier. - bool hasMutableQualifier() const { return getMutableLoc().isValid(); } - - /// \brief Get the type of exception specification this function has. - ExceptionSpecificationType getExceptionSpecType() const { - return static_cast<ExceptionSpecificationType>(ExceptionSpecType); - } - - /// \brief Determine whether this function declarator had a - /// trailing-return-type. - bool hasTrailingReturnType() const { return HasTrailingReturnType; } - - /// \brief Get the trailing-return-type for this function declarator. - ParsedType getTrailingReturnType() const { return TrailingReturnType; } - }; - - struct BlockPointerTypeInfo : TypeInfoCommon { - /// For now, sema will catch these as invalid. - /// The type qualifiers: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; - - void destroy() { - } - }; - - struct MemberPointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; - // CXXScopeSpec has a constructor, so it can't be a direct member. - // So we need some pointer-aligned storage and a bit of trickery. - union { - void *Aligner; - char Mem[sizeof(CXXScopeSpec)]; - } ScopeMem; - CXXScopeSpec &Scope() { - return *reinterpret_cast<CXXScopeSpec*>(ScopeMem.Mem); - } - const CXXScopeSpec &Scope() const { - return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem); - } - void destroy() { - Scope().~CXXScopeSpec(); - } - }; - - union { - TypeInfoCommon Common; - PointerTypeInfo Ptr; - ReferenceTypeInfo Ref; - ArrayTypeInfo Arr; - FunctionTypeInfo Fun; - BlockPointerTypeInfo Cls; - MemberPointerTypeInfo Mem; - }; - - void destroy() { - switch (Kind) { - case DeclaratorChunk::Function: return Fun.destroy(); - case DeclaratorChunk::Pointer: return Ptr.destroy(); - case DeclaratorChunk::BlockPointer: return Cls.destroy(); - case DeclaratorChunk::Reference: return Ref.destroy(); - case DeclaratorChunk::Array: return Arr.destroy(); - case DeclaratorChunk::MemberPointer: return Mem.destroy(); - case DeclaratorChunk::Paren: return; - } - } - - /// \brief If there are attributes applied to this declaratorchunk, return - /// them. - const AttributeList *getAttrs() const { - return Common.AttrList; - } - - AttributeList *&getAttrListRef() { - return Common.AttrList; - } - - /// \brief Return a DeclaratorChunk for a pointer. - static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, - SourceLocation ConstQualLoc, - SourceLocation VolatileQualLoc, - SourceLocation RestrictQualLoc, - SourceLocation AtomicQualLoc) { - DeclaratorChunk I; - I.Kind = Pointer; - I.Loc = Loc; - I.Ptr.TypeQuals = TypeQuals; - I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding(); - I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding(); - I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding(); - I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding(); - I.Ptr.AttrList = nullptr; - return I; - } - - /// \brief Return a DeclaratorChunk for a reference. - static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, - bool lvalue) { - DeclaratorChunk I; - I.Kind = Reference; - I.Loc = Loc; - I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0; - I.Ref.LValueRef = lvalue; - I.Ref.AttrList = nullptr; - return I; - } - - /// \brief Return a DeclaratorChunk for an array. - static DeclaratorChunk getArray(unsigned TypeQuals, - bool isStatic, bool isStar, Expr *NumElts, - SourceLocation LBLoc, SourceLocation RBLoc) { - DeclaratorChunk I; - I.Kind = Array; - I.Loc = LBLoc; - I.EndLoc = RBLoc; - I.Arr.AttrList = nullptr; - I.Arr.TypeQuals = TypeQuals; - I.Arr.hasStatic = isStatic; - I.Arr.isStar = isStar; - I.Arr.NumElts = NumElts; - return I; - } - - /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. - /// "TheDeclarator" is the declarator that this will be added to. - static DeclaratorChunk getFunction(bool HasProto, - bool IsAmbiguous, - SourceLocation LParenLoc, - ParamInfo *Params, unsigned NumParams, - SourceLocation EllipsisLoc, - SourceLocation RParenLoc, - unsigned TypeQuals, - bool RefQualifierIsLvalueRef, - SourceLocation RefQualifierLoc, - SourceLocation ConstQualifierLoc, - SourceLocation VolatileQualifierLoc, - SourceLocation RestrictQualifierLoc, - SourceLocation MutableLoc, - ExceptionSpecificationType ESpecType, - SourceRange ESpecRange, - ParsedType *Exceptions, - SourceRange *ExceptionRanges, - unsigned NumExceptions, - Expr *NoexceptExpr, - CachedTokens *ExceptionSpecTokens, - SourceLocation LocalRangeBegin, - SourceLocation LocalRangeEnd, - Declarator &TheDeclarator, - TypeResult TrailingReturnType = - TypeResult()); - - /// \brief Return a DeclaratorChunk for a block. - static DeclaratorChunk getBlockPointer(unsigned TypeQuals, - SourceLocation Loc) { - DeclaratorChunk I; - I.Kind = BlockPointer; - I.Loc = Loc; - I.Cls.TypeQuals = TypeQuals; - I.Cls.AttrList = nullptr; - return I; - } - - static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, - unsigned TypeQuals, - SourceLocation Loc) { - DeclaratorChunk I; - I.Kind = MemberPointer; - I.Loc = SS.getBeginLoc(); - I.EndLoc = Loc; - I.Mem.TypeQuals = TypeQuals; - I.Mem.AttrList = nullptr; - new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS); - return I; - } - - /// \brief Return a DeclaratorChunk for a paren. - static DeclaratorChunk getParen(SourceLocation LParenLoc, - SourceLocation RParenLoc) { - DeclaratorChunk I; - I.Kind = Paren; - I.Loc = LParenLoc; - I.EndLoc = RParenLoc; - I.Common.AttrList = nullptr; - return I; - } - - bool isParen() const { - return Kind == Paren; - } -}; - -/// \brief Described the kind of function definition (if any) provided for -/// a function. -enum FunctionDefinitionKind { - FDK_Declaration, - FDK_Definition, - FDK_Defaulted, - FDK_Deleted -}; - -/// \brief Information about one declarator, including the parsed type -/// information and the identifier. -/// -/// When the declarator is fully formed, this is turned into the appropriate -/// Decl object. -/// -/// Declarators come in two types: normal declarators and abstract declarators. -/// Abstract declarators are used when parsing types, and don't have an -/// identifier. Normal declarators do have ID's. -/// -/// Instances of this class should be a transient object that lives on the -/// stack, not objects that are allocated in large quantities on the heap. -class Declarator { -public: - enum TheContext { - FileContext, // File scope declaration. - PrototypeContext, // Within a function prototype. - ObjCResultContext, // An ObjC method result type. - ObjCParameterContext,// An ObjC method parameter type. - KNRTypeListContext, // K&R type definition list for formals. - TypeNameContext, // Abstract declarator for types. - MemberContext, // Struct/Union field. - BlockContext, // Declaration within a block in a function. - ForContext, // Declaration within first part of a for loop. - ConditionContext, // Condition declaration in a C++ if/switch/while/for. - TemplateParamContext,// Within a template parameter list. - CXXNewContext, // C++ new-expression. - CXXCatchContext, // C++ catch exception-declaration - ObjCCatchContext, // Objective-C catch exception-declaration - BlockLiteralContext, // Block literal declarator. - LambdaExprContext, // Lambda-expression declarator. - LambdaExprParameterContext, // Lambda-expression parameter declarator. - ConversionIdContext, // C++ conversion-type-id. - TrailingReturnContext, // C++11 trailing-type-specifier. - TemplateTypeArgContext, // Template type argument. - AliasDeclContext, // C++11 alias-declaration. - AliasTemplateContext // C++11 alias-declaration template. - }; - -private: - const DeclSpec &DS; - CXXScopeSpec SS; - UnqualifiedId Name; - SourceRange Range; - - /// \brief Where we are parsing this declarator. - TheContext Context; - - /// DeclTypeInfo - This holds each type that the declarator includes as it is - /// parsed. This is pushed from the identifier out, which means that element - /// #0 will be the most closely bound to the identifier, and - /// DeclTypeInfo.back() will be the least closely bound. - SmallVector<DeclaratorChunk, 8> DeclTypeInfo; - - /// InvalidType - Set by Sema::GetTypeForDeclarator(). - bool InvalidType : 1; - - /// GroupingParens - Set by Parser::ParseParenDeclarator(). - bool GroupingParens : 1; - - /// FunctionDefinition - Is this Declarator for a function or member - /// definition and, if so, what kind? - /// - /// Actually a FunctionDefinitionKind. - unsigned FunctionDefinition : 2; - - /// \brief Is this Declarator a redeclaration? - bool Redeclaration : 1; - - /// Attrs - Attributes. - ParsedAttributes Attrs; - - /// \brief The asm label, if specified. - Expr *AsmLabel; - - /// InlineParams - This is a local array used for the first function decl - /// chunk to avoid going to the heap for the common case when we have one - /// function chunk in the declarator. - DeclaratorChunk::ParamInfo InlineParams[16]; - bool InlineParamsUsed; - - /// \brief true if the declaration is preceded by \c __extension__. - unsigned Extension : 1; - - /// Indicates whether this is an Objective-C instance variable. - unsigned ObjCIvar : 1; - - /// Indicates whether this is an Objective-C 'weak' property. - unsigned ObjCWeakProperty : 1; - - /// \brief If this is the second or subsequent declarator in this declaration, - /// the location of the comma before this declarator. - SourceLocation CommaLoc; - - /// \brief If provided, the source location of the ellipsis used to describe - /// this declarator as a parameter pack. - SourceLocation EllipsisLoc; - - friend struct DeclaratorChunk; - -public: - Declarator(const DeclSpec &ds, TheContext C) - : DS(ds), Range(ds.getSourceRange()), Context(C), - InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error), - GroupingParens(false), FunctionDefinition(FDK_Declaration), - Redeclaration(false), - Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr), - InlineParamsUsed(false), Extension(false), ObjCIvar(false), - ObjCWeakProperty(false) { - } - - ~Declarator() { - clear(); - } - /// getDeclSpec - Return the declaration-specifier that this declarator was - /// declared with. - const DeclSpec &getDeclSpec() const { return DS; } - - /// getMutableDeclSpec - Return a non-const version of the DeclSpec. This - /// should be used with extreme care: declspecs can often be shared between - /// multiple declarators, so mutating the DeclSpec affects all of the - /// Declarators. This should only be done when the declspec is known to not - /// be shared or when in error recovery etc. - DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); } - - AttributePool &getAttributePool() const { - return Attrs.getPool(); - } - - /// getCXXScopeSpec - Return the C++ scope specifier (global scope or - /// nested-name-specifier) that is part of the declarator-id. - const CXXScopeSpec &getCXXScopeSpec() const { return SS; } - CXXScopeSpec &getCXXScopeSpec() { return SS; } - - /// \brief Retrieve the name specified by this declarator. - UnqualifiedId &getName() { return Name; } - - TheContext getContext() const { return Context; } - - bool isPrototypeContext() const { - return (Context == PrototypeContext || - Context == ObjCParameterContext || - Context == ObjCResultContext || - Context == LambdaExprParameterContext); - } - - /// \brief Get the source range that spans this declarator. - SourceRange getSourceRange() const LLVM_READONLY { return Range; } - SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } - SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } - - void SetSourceRange(SourceRange R) { Range = R; } - /// SetRangeBegin - Set the start of the source range to Loc, unless it's - /// invalid. - void SetRangeBegin(SourceLocation Loc) { - if (!Loc.isInvalid()) - Range.setBegin(Loc); - } - /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid. - void SetRangeEnd(SourceLocation Loc) { - if (!Loc.isInvalid()) - Range.setEnd(Loc); - } - /// ExtendWithDeclSpec - Extend the declarator source range to include the - /// given declspec, unless its location is invalid. Adopts the range start if - /// the current range start is invalid. - void ExtendWithDeclSpec(const DeclSpec &DS) { - SourceRange SR = DS.getSourceRange(); - if (Range.getBegin().isInvalid()) - Range.setBegin(SR.getBegin()); - if (!SR.getEnd().isInvalid()) - Range.setEnd(SR.getEnd()); - } - - /// \brief Reset the contents of this Declarator. - void clear() { - SS.clear(); - Name.clear(); - Range = DS.getSourceRange(); - - for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) - DeclTypeInfo[i].destroy(); - DeclTypeInfo.clear(); - Attrs.clear(); - AsmLabel = nullptr; - InlineParamsUsed = false; - ObjCIvar = false; - ObjCWeakProperty = false; - CommaLoc = SourceLocation(); - EllipsisLoc = SourceLocation(); - } - - /// mayOmitIdentifier - Return true if the identifier is either optional or - /// not allowed. This is true for typenames, prototypes, and template - /// parameter lists. - bool mayOmitIdentifier() const { - switch (Context) { - case FileContext: - case KNRTypeListContext: - case MemberContext: - case BlockContext: - case ForContext: - case ConditionContext: - return false; - - case TypeNameContext: - case AliasDeclContext: - case AliasTemplateContext: - case PrototypeContext: - case LambdaExprParameterContext: - case ObjCParameterContext: - case ObjCResultContext: - case TemplateParamContext: - case CXXNewContext: - case CXXCatchContext: - case ObjCCatchContext: - case BlockLiteralContext: - case LambdaExprContext: - case ConversionIdContext: - case TemplateTypeArgContext: - case TrailingReturnContext: - return true; - } - llvm_unreachable("unknown context kind!"); - } - - /// mayHaveIdentifier - Return true if the identifier is either optional or - /// required. This is true for normal declarators and prototypes, but not - /// typenames. - bool mayHaveIdentifier() const { - switch (Context) { - case FileContext: - case KNRTypeListContext: - case MemberContext: - case BlockContext: - case ForContext: - case ConditionContext: - case PrototypeContext: - case LambdaExprParameterContext: - case TemplateParamContext: - case CXXCatchContext: - case ObjCCatchContext: - return true; - - case TypeNameContext: - case CXXNewContext: - case AliasDeclContext: - case AliasTemplateContext: - case ObjCParameterContext: - case ObjCResultContext: - case BlockLiteralContext: - case LambdaExprContext: - case ConversionIdContext: - case TemplateTypeArgContext: - case TrailingReturnContext: - return false; - } - llvm_unreachable("unknown context kind!"); - } - - /// diagnoseIdentifier - Return true if the identifier is prohibited and - /// should be diagnosed (because it cannot be anything else). - bool diagnoseIdentifier() const { - switch (Context) { - case FileContext: - case KNRTypeListContext: - case MemberContext: - case BlockContext: - case ForContext: - case ConditionContext: - case PrototypeContext: - case LambdaExprParameterContext: - case TemplateParamContext: - case CXXCatchContext: - case ObjCCatchContext: - case TypeNameContext: - case ConversionIdContext: - case ObjCParameterContext: - case ObjCResultContext: - case BlockLiteralContext: - case CXXNewContext: - case LambdaExprContext: - return false; - - case AliasDeclContext: - case AliasTemplateContext: - case TemplateTypeArgContext: - case TrailingReturnContext: - return true; - } - llvm_unreachable("unknown context kind!"); - } - - /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be - /// followed by a C++ direct initializer, e.g. "int x(1);". - bool mayBeFollowedByCXXDirectInit() const { - if (hasGroupingParens()) return false; - - if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) - return false; - - if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern && - Context != FileContext) - return false; - - // Special names can't have direct initializers. - if (Name.getKind() != UnqualifiedId::IK_Identifier) - return false; - - switch (Context) { - case FileContext: - case BlockContext: - case ForContext: - return true; - - case ConditionContext: - // This may not be followed by a direct initializer, but it can't be a - // function declaration either, and we'd prefer to perform a tentative - // parse in order to produce the right diagnostic. - return true; - - case KNRTypeListContext: - case MemberContext: - case PrototypeContext: - case LambdaExprParameterContext: - case ObjCParameterContext: - case ObjCResultContext: - case TemplateParamContext: - case CXXCatchContext: - case ObjCCatchContext: - case TypeNameContext: - case CXXNewContext: - case AliasDeclContext: - case AliasTemplateContext: - case BlockLiteralContext: - case LambdaExprContext: - case ConversionIdContext: - case TemplateTypeArgContext: - case TrailingReturnContext: - return false; - } - llvm_unreachable("unknown context kind!"); - } - - /// isPastIdentifier - Return true if we have parsed beyond the point where - /// the - bool isPastIdentifier() const { return Name.isValid(); } - - /// hasName - Whether this declarator has a name, which might be an - /// identifier (accessible via getIdentifier()) or some kind of - /// special C++ name (constructor, destructor, etc.). - bool hasName() const { - return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier; - } - - IdentifierInfo *getIdentifier() const { - if (Name.getKind() == UnqualifiedId::IK_Identifier) - return Name.Identifier; - - return nullptr; - } - SourceLocation getIdentifierLoc() const { return Name.StartLocation; } - - /// \brief Set the name of this declarator to be the given identifier. - void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) { - Name.setIdentifier(Id, IdLoc); - } - - /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to - /// EndLoc, which should be the last token of the chunk. - void AddTypeInfo(const DeclaratorChunk &TI, - ParsedAttributes &attrs, - SourceLocation EndLoc) { - DeclTypeInfo.push_back(TI); - DeclTypeInfo.back().getAttrListRef() = attrs.getList(); - getAttributePool().takeAllFrom(attrs.getPool()); - - if (!EndLoc.isInvalid()) - SetRangeEnd(EndLoc); - } - - /// \brief Add a new innermost chunk to this declarator. - void AddInnermostTypeInfo(const DeclaratorChunk &TI) { - DeclTypeInfo.insert(DeclTypeInfo.begin(), TI); - } - - /// \brief Return the number of types applied to this declarator. - unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); } - - /// Return the specified TypeInfo from this declarator. TypeInfo #0 is - /// closest to the identifier. - const DeclaratorChunk &getTypeObject(unsigned i) const { - assert(i < DeclTypeInfo.size() && "Invalid type chunk"); - return DeclTypeInfo[i]; - } - DeclaratorChunk &getTypeObject(unsigned i) { - assert(i < DeclTypeInfo.size() && "Invalid type chunk"); - return DeclTypeInfo[i]; - } - - typedef SmallVectorImpl<DeclaratorChunk>::const_iterator type_object_iterator; - typedef llvm::iterator_range<type_object_iterator> type_object_range; - - /// Returns the range of type objects, from the identifier outwards. - type_object_range type_objects() const { - return type_object_range(DeclTypeInfo.begin(), DeclTypeInfo.end()); - } - - void DropFirstTypeObject() { - assert(!DeclTypeInfo.empty() && "No type chunks to drop."); - DeclTypeInfo.front().destroy(); - DeclTypeInfo.erase(DeclTypeInfo.begin()); - } - - /// Return the innermost (closest to the declarator) chunk of this - /// declarator that is not a parens chunk, or null if there are no - /// non-parens chunks. - const DeclaratorChunk *getInnermostNonParenChunk() const { - for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { - if (!DeclTypeInfo[i].isParen()) - return &DeclTypeInfo[i]; - } - return nullptr; - } - - /// Return the outermost (furthest from the declarator) chunk of - /// this declarator that is not a parens chunk, or null if there are - /// no non-parens chunks. - const DeclaratorChunk *getOutermostNonParenChunk() const { - for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) { - if (!DeclTypeInfo[i-1].isParen()) - return &DeclTypeInfo[i-1]; - } - return nullptr; - } - - /// isArrayOfUnknownBound - This method returns true if the declarator - /// is a declarator for an array of unknown bound (looking through - /// parentheses). - bool isArrayOfUnknownBound() const { - const DeclaratorChunk *chunk = getInnermostNonParenChunk(); - return (chunk && chunk->Kind == DeclaratorChunk::Array && - !chunk->Arr.NumElts); - } - - /// isFunctionDeclarator - This method returns true if the declarator - /// is a function declarator (looking through parentheses). - /// If true is returned, then the reference type parameter idx is - /// assigned with the index of the declaration chunk. - bool isFunctionDeclarator(unsigned& idx) const { - for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { - switch (DeclTypeInfo[i].Kind) { - case DeclaratorChunk::Function: - idx = i; - return true; - case DeclaratorChunk::Paren: - continue; - case DeclaratorChunk::Pointer: - case DeclaratorChunk::Reference: - case DeclaratorChunk::Array: - case DeclaratorChunk::BlockPointer: - case DeclaratorChunk::MemberPointer: - return false; - } - llvm_unreachable("Invalid type chunk"); - } - return false; - } - - /// isFunctionDeclarator - Once this declarator is fully parsed and formed, - /// this method returns true if the identifier is a function declarator - /// (looking through parentheses). - bool isFunctionDeclarator() const { - unsigned index; - return isFunctionDeclarator(index); - } - - /// getFunctionTypeInfo - Retrieves the function type info object - /// (looking through parentheses). - DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() { - assert(isFunctionDeclarator() && "Not a function declarator!"); - unsigned index = 0; - isFunctionDeclarator(index); - return DeclTypeInfo[index].Fun; - } - - /// getFunctionTypeInfo - Retrieves the function type info object - /// (looking through parentheses). - const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const { - return const_cast<Declarator*>(this)->getFunctionTypeInfo(); - } - - /// \brief Determine whether the declaration that will be produced from - /// this declaration will be a function. - /// - /// A declaration can declare a function even if the declarator itself - /// isn't a function declarator, if the type specifier refers to a function - /// type. This routine checks for both cases. - bool isDeclarationOfFunction() const; - - /// \brief Return true if this declaration appears in a context where a - /// function declarator would be a function declaration. - bool isFunctionDeclarationContext() const { - if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) - return false; - - switch (Context) { - case FileContext: - case MemberContext: - case BlockContext: - return true; - - case ForContext: - case ConditionContext: - case KNRTypeListContext: - case TypeNameContext: - case AliasDeclContext: - case AliasTemplateContext: - case PrototypeContext: - case LambdaExprParameterContext: - case ObjCParameterContext: - case ObjCResultContext: - case TemplateParamContext: - case CXXNewContext: - case CXXCatchContext: - case ObjCCatchContext: - case BlockLiteralContext: - case LambdaExprContext: - case ConversionIdContext: - case TemplateTypeArgContext: - case TrailingReturnContext: - return false; - } - llvm_unreachable("unknown context kind!"); - } - - /// \brief Return true if a function declarator at this position would be a - /// function declaration. - bool isFunctionDeclaratorAFunctionDeclaration() const { - if (!isFunctionDeclarationContext()) - return false; - - for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I) - if (getTypeObject(I).Kind != DeclaratorChunk::Paren) - return false; - - return true; - } - - /// takeAttributes - Takes attributes from the given parsed-attributes - /// set and add them to this declarator. - /// - /// These examples both add 3 attributes to "var": - /// short int var __attribute__((aligned(16),common,deprecated)); - /// short int x, __attribute__((aligned(16)) var - /// __attribute__((common,deprecated)); - /// - /// Also extends the range of the declarator. - void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) { - Attrs.takeAllFrom(attrs); - - if (!lastLoc.isInvalid()) - SetRangeEnd(lastLoc); - } - - const AttributeList *getAttributes() const { return Attrs.getList(); } - AttributeList *getAttributes() { return Attrs.getList(); } - - AttributeList *&getAttrListRef() { return Attrs.getListRef(); } - - /// hasAttributes - do we contain any attributes? - bool hasAttributes() const { - if (getAttributes() || getDeclSpec().hasAttributes()) return true; - for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i) - if (getTypeObject(i).getAttrs()) - return true; - return false; - } - - /// \brief Return a source range list of C++11 attributes associated - /// with the declarator. - void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { - AttributeList *AttrList = Attrs.getList(); - while (AttrList) { - if (AttrList->isCXX11Attribute()) - Ranges.push_back(AttrList->getRange()); - AttrList = AttrList->getNext(); - } - } - - void setAsmLabel(Expr *E) { AsmLabel = E; } - Expr *getAsmLabel() const { return AsmLabel; } - - void setExtension(bool Val = true) { Extension = Val; } - bool getExtension() const { return Extension; } - - void setObjCIvar(bool Val = true) { ObjCIvar = Val; } - bool isObjCIvar() const { return ObjCIvar; } - - void setObjCWeakProperty(bool Val = true) { ObjCWeakProperty = Val; } - bool isObjCWeakProperty() const { return ObjCWeakProperty; } - - void setInvalidType(bool Val = true) { InvalidType = Val; } - bool isInvalidType() const { - return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error; - } - - void setGroupingParens(bool flag) { GroupingParens = flag; } - bool hasGroupingParens() const { return GroupingParens; } - - bool isFirstDeclarator() const { return !CommaLoc.isValid(); } - SourceLocation getCommaLoc() const { return CommaLoc; } - void setCommaLoc(SourceLocation CL) { CommaLoc = CL; } - - bool hasEllipsis() const { return EllipsisLoc.isValid(); } - SourceLocation getEllipsisLoc() const { return EllipsisLoc; } - void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; } - - void setFunctionDefinitionKind(FunctionDefinitionKind Val) { - FunctionDefinition = Val; - } - - bool isFunctionDefinition() const { - return getFunctionDefinitionKind() != FDK_Declaration; - } - - FunctionDefinitionKind getFunctionDefinitionKind() const { - return (FunctionDefinitionKind)FunctionDefinition; - } - - /// Returns true if this declares a real member and not a friend. - bool isFirstDeclarationOfMember() { - return getContext() == MemberContext && !getDeclSpec().isFriendSpecified(); - } - - /// Returns true if this declares a static member. This cannot be called on a - /// declarator outside of a MemberContext because we won't know until - /// redeclaration time if the decl is static. - bool isStaticMember(); - - /// Returns true if this declares a constructor or a destructor. - bool isCtorOrDtor(); - - void setRedeclaration(bool Val) { Redeclaration = Val; } - bool isRedeclaration() const { return Redeclaration; } -}; - -/// \brief This little struct is used to capture information about -/// structure field declarators, which is basically just a bitfield size. -struct FieldDeclarator { - Declarator D; - Expr *BitfieldSize; - explicit FieldDeclarator(const DeclSpec &DS) - : D(DS, Declarator::MemberContext), BitfieldSize(nullptr) { } -}; - -/// \brief Represents a C++11 virt-specifier-seq. -class VirtSpecifiers { -public: - enum Specifier { - VS_None = 0, - VS_Override = 1, - VS_Final = 2, - VS_Sealed = 4 - }; - - VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { } - - bool SetSpecifier(Specifier VS, SourceLocation Loc, - const char *&PrevSpec); - - bool isUnset() const { return Specifiers == 0; } - - bool isOverrideSpecified() const { return Specifiers & VS_Override; } - SourceLocation getOverrideLoc() const { return VS_overrideLoc; } - - bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed); } - bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; } - SourceLocation getFinalLoc() const { return VS_finalLoc; } - - void clear() { Specifiers = 0; } - - static const char *getSpecifierName(Specifier VS); - - SourceLocation getFirstLocation() const { return FirstLocation; } - SourceLocation getLastLocation() const { return LastLocation; } - Specifier getLastSpecifier() const { return LastSpecifier; } - -private: - unsigned Specifiers; - Specifier LastSpecifier; - - SourceLocation VS_overrideLoc, VS_finalLoc; - SourceLocation FirstLocation; - SourceLocation LastLocation; -}; - -enum class LambdaCaptureInitKind { - NoInit, //!< [a] - CopyInit, //!< [a = b], [a = {b}] - DirectInit, //!< [a(b)] - ListInit //!< [a{b}] -}; - -/// \brief Represents a complete lambda introducer. -struct LambdaIntroducer { - /// \brief An individual capture in a lambda introducer. - struct LambdaCapture { - LambdaCaptureKind Kind; - SourceLocation Loc; - IdentifierInfo *Id; - SourceLocation EllipsisLoc; - LambdaCaptureInitKind InitKind; - ExprResult Init; - ParsedType InitCaptureType; - LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, - IdentifierInfo *Id, SourceLocation EllipsisLoc, - LambdaCaptureInitKind InitKind, ExprResult Init, - ParsedType InitCaptureType) - : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), - InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType) {} - }; - - SourceRange Range; - SourceLocation DefaultLoc; - LambdaCaptureDefault Default; - SmallVector<LambdaCapture, 4> Captures; - - LambdaIntroducer() - : Default(LCD_None) {} - - /// \brief Append a capture in a lambda introducer. - void addCapture(LambdaCaptureKind Kind, - SourceLocation Loc, - IdentifierInfo* Id, - SourceLocation EllipsisLoc, - LambdaCaptureInitKind InitKind, - ExprResult Init, - ParsedType InitCaptureType) { - Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, - InitCaptureType)); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h deleted file mode 100644 index 155b3aa..0000000 --- a/include/clang/Sema/DelayedDiagnostic.h +++ /dev/null @@ -1,305 +0,0 @@ -//===--- DelayedDiagnostic.h - Delayed declarator diagnostics ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Defines the classes clang::DelayedDiagnostic and -/// clang::AccessedEntity. -/// -/// DelayedDiangostic is used to record diagnostics that are being -/// conditionally produced during declarator parsing. Certain kinds of -/// diagnostics -- notably deprecation and access control -- are suppressed -/// based on semantic properties of the parsed declaration that aren't known -/// until it is fully parsed. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H -#define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H - -#include "clang/Sema/Sema.h" - -namespace clang { -namespace sema { - -/// A declaration being accessed, together with information about how -/// it was accessed. -class AccessedEntity { -public: - /// A member declaration found through lookup. The target is the - /// member. - enum MemberNonce { Member }; - - /// A hierarchy (base-to-derived or derived-to-base) conversion. - /// The target is the base class. - enum BaseNonce { Base }; - - bool isMemberAccess() const { return IsMember; } - - AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator, - MemberNonce _, - CXXRecordDecl *NamingClass, - DeclAccessPair FoundDecl, - QualType BaseObjectType) - : Access(FoundDecl.getAccess()), IsMember(true), - Target(FoundDecl.getDecl()), NamingClass(NamingClass), - BaseObjectType(BaseObjectType), Diag(0, Allocator) { - } - - AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator, - BaseNonce _, - CXXRecordDecl *BaseClass, - CXXRecordDecl *DerivedClass, - AccessSpecifier Access) - : Access(Access), IsMember(false), - Target(BaseClass), - NamingClass(DerivedClass), - Diag(0, Allocator) { - } - - bool isQuiet() const { return Diag.getDiagID() == 0; } - - AccessSpecifier getAccess() const { return AccessSpecifier(Access); } - - // These apply to member decls... - NamedDecl *getTargetDecl() const { return Target; } - CXXRecordDecl *getNamingClass() const { return NamingClass; } - - // ...and these apply to hierarchy conversions. - CXXRecordDecl *getBaseClass() const { - assert(!IsMember); return cast<CXXRecordDecl>(Target); - } - CXXRecordDecl *getDerivedClass() const { return NamingClass; } - - /// Retrieves the base object type, important when accessing - /// an instance member. - QualType getBaseObjectType() const { return BaseObjectType; } - - /// Sets a diagnostic to be performed. The diagnostic is given - /// four (additional) arguments: - /// %0 - 0 if the entity was private, 1 if protected - /// %1 - the DeclarationName of the entity - /// %2 - the TypeDecl type of the naming class - /// %3 - the TypeDecl type of the declaring class - void setDiag(const PartialDiagnostic &PDiag) { - assert(isQuiet() && "partial diagnostic already defined"); - Diag = PDiag; - } - PartialDiagnostic &setDiag(unsigned DiagID) { - assert(isQuiet() && "partial diagnostic already defined"); - assert(DiagID && "creating null diagnostic"); - Diag.Reset(DiagID); - return Diag; - } - const PartialDiagnostic &getDiag() const { - return Diag; - } - -private: - unsigned Access : 2; - unsigned IsMember : 1; - NamedDecl *Target; - CXXRecordDecl *NamingClass; - QualType BaseObjectType; - PartialDiagnostic Diag; -}; - -/// A diagnostic message which has been conditionally emitted pending -/// the complete parsing of the current declaration. -class DelayedDiagnostic { -public: - enum DDKind { Deprecation, Unavailable, Access, ForbiddenType }; - - unsigned char Kind; // actually a DDKind - bool Triggered; - - SourceLocation Loc; - - void Destroy(); - - static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD, - SourceLocation Loc, - const NamedDecl *D, - const ObjCInterfaceDecl *UnknownObjCClass, - const ObjCPropertyDecl *ObjCProperty, - StringRef Msg, - bool ObjCPropertyAccess); - - - static DelayedDiagnostic makeAccess(SourceLocation Loc, - const AccessedEntity &Entity) { - DelayedDiagnostic DD; - DD.Kind = Access; - DD.Triggered = false; - DD.Loc = Loc; - new (&DD.getAccessData()) AccessedEntity(Entity); - return DD; - } - - static DelayedDiagnostic makeForbiddenType(SourceLocation loc, - unsigned diagnostic, - QualType type, - unsigned argument) { - DelayedDiagnostic DD; - DD.Kind = ForbiddenType; - DD.Triggered = false; - DD.Loc = loc; - DD.ForbiddenTypeData.Diagnostic = diagnostic; - DD.ForbiddenTypeData.OperandType = type.getAsOpaquePtr(); - DD.ForbiddenTypeData.Argument = argument; - return DD; - } - - AccessedEntity &getAccessData() { - assert(Kind == Access && "Not an access diagnostic."); - return *reinterpret_cast<AccessedEntity*>(AccessData); - } - const AccessedEntity &getAccessData() const { - assert(Kind == Access && "Not an access diagnostic."); - return *reinterpret_cast<const AccessedEntity*>(AccessData); - } - - const NamedDecl *getDeprecationDecl() const { - assert((Kind == Deprecation || Kind == Unavailable) && - "Not a deprecation diagnostic."); - return DeprecationData.Decl; - } - - StringRef getDeprecationMessage() const { - assert((Kind == Deprecation || Kind == Unavailable) && - "Not a deprecation diagnostic."); - return StringRef(DeprecationData.Message, - DeprecationData.MessageLen); - } - - /// The diagnostic ID to emit. Used like so: - /// Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) - /// << diag.getForbiddenTypeOperand() - /// << diag.getForbiddenTypeArgument(); - unsigned getForbiddenTypeDiagnostic() const { - assert(Kind == ForbiddenType && "not a forbidden-type diagnostic"); - return ForbiddenTypeData.Diagnostic; - } - - unsigned getForbiddenTypeArgument() const { - assert(Kind == ForbiddenType && "not a forbidden-type diagnostic"); - return ForbiddenTypeData.Argument; - } - - QualType getForbiddenTypeOperand() const { - assert(Kind == ForbiddenType && "not a forbidden-type diagnostic"); - return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType); - } - - const ObjCInterfaceDecl *getUnknownObjCClass() const { - return DeprecationData.UnknownObjCClass; - } - - const ObjCPropertyDecl *getObjCProperty() const { - return DeprecationData.ObjCProperty; - } - - bool getObjCPropertyAccess() const { - return DeprecationData.ObjCPropertyAccess; - } - -private: - - struct DD { - const NamedDecl *Decl; - const ObjCInterfaceDecl *UnknownObjCClass; - const ObjCPropertyDecl *ObjCProperty; - const char *Message; - size_t MessageLen; - bool ObjCPropertyAccess; - }; - - struct FTD { - unsigned Diagnostic; - unsigned Argument; - void *OperandType; - }; - - union { - /// Deprecation - struct DD DeprecationData; - struct FTD ForbiddenTypeData; - - /// Access control. - char AccessData[sizeof(AccessedEntity)]; - }; -}; - -/// \brief A collection of diagnostics which were delayed. -class DelayedDiagnosticPool { - const DelayedDiagnosticPool *Parent; - SmallVector<DelayedDiagnostic, 4> Diagnostics; - - DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete; - void operator=(const DelayedDiagnosticPool &) = delete; -public: - DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {} - ~DelayedDiagnosticPool() { - for (SmallVectorImpl<DelayedDiagnostic>::iterator - i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i) - i->Destroy(); - } - - DelayedDiagnosticPool(DelayedDiagnosticPool &&Other) - : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) { - Other.Diagnostics.clear(); - } - DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) { - Parent = Other.Parent; - Diagnostics = std::move(Other.Diagnostics); - Other.Diagnostics.clear(); - return *this; - } - - const DelayedDiagnosticPool *getParent() const { return Parent; } - - /// Does this pool, or any of its ancestors, contain any diagnostics? - bool empty() const { - return (Diagnostics.empty() && (!Parent || Parent->empty())); - } - - /// Add a diagnostic to this pool. - void add(const DelayedDiagnostic &diag) { - Diagnostics.push_back(diag); - } - - /// Steal the diagnostics from the given pool. - void steal(DelayedDiagnosticPool &pool) { - if (pool.Diagnostics.empty()) return; - - if (Diagnostics.empty()) { - Diagnostics = std::move(pool.Diagnostics); - } else { - Diagnostics.append(pool.pool_begin(), pool.pool_end()); - } - pool.Diagnostics.clear(); - } - - typedef SmallVectorImpl<DelayedDiagnostic>::const_iterator pool_iterator; - pool_iterator pool_begin() const { return Diagnostics.begin(); } - pool_iterator pool_end() const { return Diagnostics.end(); } - bool pool_empty() const { return Diagnostics.empty(); } -}; - -} - -/// Add a diagnostic to the current delay pool. -inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) { - assert(shouldDelayDiagnostics() && "trying to delay without pool"); - CurPool->add(diag); -} - - -} - -#endif diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h deleted file mode 100644 index 55603fe..0000000 --- a/include/clang/Sema/Designator.h +++ /dev/null @@ -1,210 +0,0 @@ -//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines interfaces used to represent designators (a la -// C99 designated initializers) during parsing. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H -#define LLVM_CLANG_SEMA_DESIGNATOR_H - -#include "clang/Basic/SourceLocation.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -class Expr; -class IdentifierInfo; -class Sema; - -/// Designator - A designator in a C99 designated initializer. -/// -/// This class is a discriminated union which holds the various -/// different sorts of designators possible. A Designation is an array of -/// these. An example of a designator are things like this: -/// [8] .field [47] // C99 designation: 3 designators -/// [8 ... 47] field: // GNU extensions: 2 designators -/// These occur in initializers, e.g.: -/// int a[10] = {2, 4, [8]=9, 10}; -/// -class Designator { -public: - enum DesignatorKind { - FieldDesignator, ArrayDesignator, ArrayRangeDesignator - }; -private: - DesignatorKind Kind; - - struct FieldDesignatorInfo { - const IdentifierInfo *II; - unsigned DotLoc; - unsigned NameLoc; - }; - struct ArrayDesignatorInfo { - Expr *Index; - unsigned LBracketLoc; - mutable unsigned RBracketLoc; - }; - struct ArrayRangeDesignatorInfo { - Expr *Start, *End; - unsigned LBracketLoc, EllipsisLoc; - mutable unsigned RBracketLoc; - }; - - union { - FieldDesignatorInfo FieldInfo; - ArrayDesignatorInfo ArrayInfo; - ArrayRangeDesignatorInfo ArrayRangeInfo; - }; - -public: - - DesignatorKind getKind() const { return Kind; } - bool isFieldDesignator() const { return Kind == FieldDesignator; } - bool isArrayDesignator() const { return Kind == ArrayDesignator; } - bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; } - - const IdentifierInfo *getField() const { - assert(isFieldDesignator() && "Invalid accessor"); - return FieldInfo.II; - } - - SourceLocation getDotLoc() const { - assert(isFieldDesignator() && "Invalid accessor"); - return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc); - } - - SourceLocation getFieldLoc() const { - assert(isFieldDesignator() && "Invalid accessor"); - return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc); - } - - Expr *getArrayIndex() const { - assert(isArrayDesignator() && "Invalid accessor"); - return ArrayInfo.Index; - } - - Expr *getArrayRangeStart() const { - assert(isArrayRangeDesignator() && "Invalid accessor"); - return ArrayRangeInfo.Start; - } - Expr *getArrayRangeEnd() const { - assert(isArrayRangeDesignator() && "Invalid accessor"); - return ArrayRangeInfo.End; - } - - SourceLocation getLBracketLoc() const { - assert((isArrayDesignator() || isArrayRangeDesignator()) && - "Invalid accessor"); - if (isArrayDesignator()) - return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc); - else - return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc); - } - - SourceLocation getRBracketLoc() const { - assert((isArrayDesignator() || isArrayRangeDesignator()) && - "Invalid accessor"); - if (isArrayDesignator()) - return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc); - else - return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc); - } - - SourceLocation getEllipsisLoc() const { - assert(isArrayRangeDesignator() && "Invalid accessor"); - return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc); - } - - static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc, - SourceLocation NameLoc) { - Designator D; - D.Kind = FieldDesignator; - D.FieldInfo.II = II; - D.FieldInfo.DotLoc = DotLoc.getRawEncoding(); - D.FieldInfo.NameLoc = NameLoc.getRawEncoding(); - return D; - } - - static Designator getArray(Expr *Index, - SourceLocation LBracketLoc) { - Designator D; - D.Kind = ArrayDesignator; - D.ArrayInfo.Index = Index; - D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding(); - D.ArrayInfo.RBracketLoc = 0; - return D; - } - - static Designator getArrayRange(Expr *Start, - Expr *End, - SourceLocation LBracketLoc, - SourceLocation EllipsisLoc) { - Designator D; - D.Kind = ArrayRangeDesignator; - D.ArrayRangeInfo.Start = Start; - D.ArrayRangeInfo.End = End; - D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding(); - D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding(); - D.ArrayRangeInfo.RBracketLoc = 0; - return D; - } - - void setRBracketLoc(SourceLocation RBracketLoc) const { - assert((isArrayDesignator() || isArrayRangeDesignator()) && - "Invalid accessor"); - if (isArrayDesignator()) - ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding(); - else - ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding(); - } - - /// ClearExprs - Null out any expression references, which prevents - /// them from being 'delete'd later. - void ClearExprs(Sema &Actions) {} - - /// FreeExprs - Release any unclaimed memory for the expressions in - /// this designator. - void FreeExprs(Sema &Actions) {} -}; - - -/// Designation - Represent a full designation, which is a sequence of -/// designators. This class is mostly a helper for InitListDesignations. -class Designation { - /// Designators - The actual designators for this initializer. - SmallVector<Designator, 2> Designators; - -public: - /// AddDesignator - Add a designator to the end of this list. - void AddDesignator(Designator D) { - Designators.push_back(D); - } - - bool empty() const { return Designators.empty(); } - - unsigned getNumDesignators() const { return Designators.size(); } - const Designator &getDesignator(unsigned Idx) const { - assert(Idx < Designators.size()); - return Designators[Idx]; - } - - /// ClearExprs - Null out any expression references, which prevents them from - /// being 'delete'd later. - void ClearExprs(Sema &Actions) {} - - /// FreeExprs - Release any unclaimed memory for the expressions in this - /// designation. - void FreeExprs(Sema &Actions) {} -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h deleted file mode 100644 index 97f78f4..0000000 --- a/include/clang/Sema/ExternalSemaSource.h +++ /dev/null @@ -1,229 +0,0 @@ -//===--- ExternalSemaSource.h - External Sema Interface ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ExternalSemaSource interface. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H -#define LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H - -#include "clang/AST/ExternalASTSource.h" -#include "clang/AST/Type.h" -#include "clang/Sema/TypoCorrection.h" -#include "clang/Sema/Weak.h" -#include "llvm/ADT/MapVector.h" -#include <utility> - -namespace llvm { -template <class T, unsigned n> class SmallSetVector; -} - -namespace clang { - -class CXXConstructorDecl; -class CXXDeleteExpr; -class CXXRecordDecl; -class DeclaratorDecl; -class LookupResult; -struct ObjCMethodList; -class Scope; -class Sema; -class TypedefNameDecl; -class ValueDecl; -class VarDecl; -struct LateParsedTemplate; - -/// \brief A simple structure that captures a vtable use for the purposes of -/// the \c ExternalSemaSource. -struct ExternalVTableUse { - CXXRecordDecl *Record; - SourceLocation Location; - bool DefinitionRequired; -}; - -/// \brief An abstract interface that should be implemented by -/// external AST sources that also provide information for semantic -/// analysis. -class ExternalSemaSource : public ExternalASTSource { -public: - ExternalSemaSource() { - ExternalASTSource::SemaSource = true; - } - - ~ExternalSemaSource() override; - - /// \brief Initialize the semantic source with the Sema instance - /// being used to perform semantic analysis on the abstract syntax - /// tree. - virtual void InitializeSema(Sema &S) {} - - /// \brief Inform the semantic consumer that Sema is no longer available. - virtual void ForgetSema() {} - - /// \brief Load the contents of the global method pool for a given - /// selector. - virtual void ReadMethodPool(Selector Sel); - - /// \brief Load the set of namespaces that are known to the external source, - /// which will be used during typo correction. - virtual void ReadKnownNamespaces( - SmallVectorImpl<NamespaceDecl *> &Namespaces); - - /// \brief Load the set of used but not defined functions or variables with - /// internal linkage, or used but not defined internal functions. - virtual void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined); - - virtual void ReadMismatchingDeleteExpressions(llvm::MapVector< - FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &); - - /// \brief Do last resort, unqualified lookup on a LookupResult that - /// Sema cannot find. - /// - /// \param R a LookupResult that is being recovered. - /// - /// \param S the Scope of the identifier occurrence. - /// - /// \return true to tell Sema to recover using the LookupResult. - virtual bool LookupUnqualified(LookupResult &R, Scope *S) { return false; } - - /// \brief Read the set of tentative definitions known to the external Sema - /// source. - /// - /// The external source should append its own tentative definitions to the - /// given vector of tentative definitions. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - virtual void ReadTentativeDefinitions( - SmallVectorImpl<VarDecl *> &TentativeDefs) {} - - /// \brief Read the set of unused file-scope declarations known to the - /// external Sema source. - /// - /// The external source should append its own unused, filed-scope to the - /// given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - virtual void ReadUnusedFileScopedDecls( - SmallVectorImpl<const DeclaratorDecl *> &Decls) {} - - /// \brief Read the set of delegating constructors known to the - /// external Sema source. - /// - /// The external source should append its own delegating constructors to the - /// given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - virtual void ReadDelegatingConstructors( - SmallVectorImpl<CXXConstructorDecl *> &Decls) {} - - /// \brief Read the set of ext_vector type declarations known to the - /// external Sema source. - /// - /// The external source should append its own ext_vector type declarations to - /// the given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {} - - /// \brief Read the set of potentially unused typedefs known to the source. - /// - /// The external source should append its own potentially unused local - /// typedefs to the given vector of declarations. Note that this routine may - /// be invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - virtual void ReadUnusedLocalTypedefNameCandidates( - llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {} - - /// \brief Read the set of referenced selectors known to the - /// external Sema source. - /// - /// The external source should append its own referenced selectors to the - /// given vector of selectors. Note that this routine - /// may be invoked multiple times; the external source should take care not - /// to introduce the same selectors repeatedly. - virtual void ReadReferencedSelectors( - SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) {} - - /// \brief Read the set of weak, undeclared identifiers known to the - /// external Sema source. - /// - /// The external source should append its own weak, undeclared identifiers to - /// the given vector. Note that this routine may be invoked multiple times; - /// the external source should take care not to introduce the same identifiers - /// repeatedly. - virtual void ReadWeakUndeclaredIdentifiers( - SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) {} - - /// \brief Read the set of used vtables known to the external Sema source. - /// - /// The external source should append its own used vtables to the given - /// vector. Note that this routine may be invoked multiple times; the external - /// source should take care not to introduce the same vtables repeatedly. - virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) {} - - /// \brief Read the set of pending instantiations known to the external - /// Sema source. - /// - /// The external source should append its own pending instantiations to the - /// given vector. Note that this routine may be invoked multiple times; the - /// external source should take care not to introduce the same instantiations - /// repeatedly. - virtual void ReadPendingInstantiations( - SmallVectorImpl<std::pair<ValueDecl *, - SourceLocation> > &Pending) {} - - /// \brief Read the set of late parsed template functions for this source. - /// - /// The external source should insert its own late parsed template functions - /// into the map. Note that this routine may be invoked multiple times; the - /// external source should take care not to introduce the same map entries - /// repeatedly. - virtual void ReadLateParsedTemplates( - llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {} - - /// \copydoc Sema::CorrectTypo - /// \note LookupKind must correspond to a valid Sema::LookupNameKind - /// - /// ExternalSemaSource::CorrectTypo is always given the first chance to - /// correct a typo (really, to offer suggestions to repair a failed lookup). - /// It will even be called when SpellChecking is turned off or after a - /// fatal error has already been detected. - virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, - int LookupKind, Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, - DeclContext *MemberContext, - bool EnteringContext, - const ObjCObjectPointerType *OPT) { - return TypoCorrection(); - } - - /// \brief Produces a diagnostic note if the external source contains a - /// complete definition for \p T. - /// - /// \param Loc the location at which a complete type was required but not - /// provided - /// - /// \param T the \c QualType that should have been complete at \p Loc - /// - /// \return true if a diagnostic was produced, false otherwise. - virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, - QualType T) { - return false; - } - - // isa/cast/dyn_cast support - static bool classof(const ExternalASTSource *Source) { - return Source->SemaSource; - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h deleted file mode 100644 index a07834f..0000000 --- a/include/clang/Sema/IdentifierResolver.h +++ /dev/null @@ -1,213 +0,0 @@ -//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the IdentifierResolver class, which is used for lexical -// scoped lookup, based on declaration names. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H -#define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H - -#include "clang/Basic/IdentifierTable.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -class ASTContext; -class Decl; -class DeclContext; -class DeclarationName; -class ExternalPreprocessorSource; -class NamedDecl; -class Preprocessor; -class Scope; - -/// IdentifierResolver - Keeps track of shadowed decls on enclosing -/// scopes. It manages the shadowing chains of declaration names and -/// implements efficient decl lookup based on a declaration name. -class IdentifierResolver { - - /// IdDeclInfo - Keeps track of information about decls associated - /// to a particular declaration name. IdDeclInfos are lazily - /// constructed and assigned to a declaration name the first time a - /// decl with that declaration name is shadowed in some scope. - class IdDeclInfo { - public: - typedef SmallVector<NamedDecl*, 2> DeclsTy; - - inline DeclsTy::iterator decls_begin() { return Decls.begin(); } - inline DeclsTy::iterator decls_end() { return Decls.end(); } - - void AddDecl(NamedDecl *D) { Decls.push_back(D); } - - /// RemoveDecl - Remove the decl from the scope chain. - /// The decl must already be part of the decl chain. - void RemoveDecl(NamedDecl *D); - - /// \brief Insert the given declaration at the given position in the list. - void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { - Decls.insert(Pos, D); - } - - private: - DeclsTy Decls; - }; - -public: - - /// iterator - Iterate over the decls of a specified declaration name. - /// It will walk or not the parent declaration contexts depending on how - /// it was instantiated. - class iterator { - public: - typedef NamedDecl * value_type; - typedef NamedDecl * reference; - typedef NamedDecl * pointer; - typedef std::input_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; - - /// Ptr - There are 3 forms that 'Ptr' represents: - /// 1) A single NamedDecl. (Ptr & 0x1 == 0) - /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the - /// same declaration context. (Ptr & 0x3 == 0x1) - /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent - /// declaration contexts too. (Ptr & 0x3 == 0x3) - uintptr_t Ptr; - typedef IdDeclInfo::DeclsTy::iterator BaseIter; - - /// A single NamedDecl. (Ptr & 0x1 == 0) - iterator(NamedDecl *D) { - Ptr = reinterpret_cast<uintptr_t>(D); - assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); - } - /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration - /// contexts depending on 'LookInParentCtx'. - iterator(BaseIter I) { - Ptr = reinterpret_cast<uintptr_t>(I) | 0x1; - } - - bool isIterator() const { return (Ptr & 0x1); } - - BaseIter getIterator() const { - assert(isIterator() && "Ptr not an iterator!"); - return reinterpret_cast<BaseIter>(Ptr & ~0x3); - } - - friend class IdentifierResolver; - - void incrementSlowCase(); - public: - iterator() : Ptr(0) {} - - NamedDecl *operator*() const { - if (isIterator()) - return *getIterator(); - else - return reinterpret_cast<NamedDecl*>(Ptr); - } - - bool operator==(const iterator &RHS) const { - return Ptr == RHS.Ptr; - } - bool operator!=(const iterator &RHS) const { - return Ptr != RHS.Ptr; - } - - // Preincrement. - iterator& operator++() { - if (!isIterator()) // common case. - Ptr = 0; - else - incrementSlowCase(); - return *this; - } - - uintptr_t getAsOpaqueValue() const { return Ptr; } - - static iterator getFromOpaqueValue(uintptr_t P) { - iterator Result; - Result.Ptr = P; - return Result; - } - }; - - /// begin - Returns an iterator for decls with the name 'Name'. - iterator begin(DeclarationName Name); - - /// end - Returns an iterator that has 'finished'. - iterator end() { - return iterator(); - } - - /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true - /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns - /// true if 'D' belongs to the given declaration context. - /// - /// \param AllowInlineNamespace If \c true, we are checking whether a prior - /// declaration is in scope in a declaration that requires a prior - /// declaration (because it is either explicitly qualified or is a - /// template instantiation or specialization). In this case, a - /// declaration is in scope if it's in the inline namespace set of the - /// context. - bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr, - bool AllowInlineNamespace = false) const; - - /// AddDecl - Link the decl to its shadowed decl chain. - void AddDecl(NamedDecl *D); - - /// RemoveDecl - Unlink the decl from its shadowed decl chain. - /// The decl must already be part of the decl chain. - void RemoveDecl(NamedDecl *D); - - /// \brief Insert the given declaration after the given iterator - /// position. - void InsertDeclAfter(iterator Pos, NamedDecl *D); - - /// \brief Try to add the given declaration to the top level scope, if it - /// (or a redeclaration of it) hasn't already been added. - /// - /// \param D The externally-produced declaration to add. - /// - /// \param Name The name of the externally-produced declaration. - /// - /// \returns true if the declaration was added, false otherwise. - bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name); - - explicit IdentifierResolver(Preprocessor &PP); - ~IdentifierResolver(); - -private: - const LangOptions &LangOpt; - Preprocessor &PP; - - class IdDeclInfoMap; - IdDeclInfoMap *IdDeclInfos; - - void updatingIdentifier(IdentifierInfo &II); - void readingIdentifier(IdentifierInfo &II); - - /// FETokenInfo contains a Decl pointer if lower bit == 0. - static inline bool isDeclPtr(void *Ptr) { - return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0; - } - - /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1. - static inline IdDeclInfo *toIdDeclInfo(void *Ptr) { - assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1 - && "Ptr not a IdDeclInfo* !"); - return reinterpret_cast<IdDeclInfo*>( - reinterpret_cast<uintptr_t>(Ptr) & ~0x1 - ); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h deleted file mode 100644 index d4f57b7..0000000 --- a/include/clang/Sema/Initialization.h +++ /dev/null @@ -1,1145 +0,0 @@ -//===--- Initialization.h - Semantic Analysis for Initializers --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides supporting data types for initialization of objects. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_INITIALIZATION_H -#define LLVM_CLANG_SEMA_INITIALIZATION_H - -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/AST/Type.h" -#include "clang/AST/UnresolvedSet.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Sema/Overload.h" -#include "clang/Sema/Ownership.h" -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/SmallVector.h" -#include <cassert> - -namespace clang { - -class CXXBaseSpecifier; -class DeclaratorDecl; -class DeclaratorInfo; -class FieldDecl; -class FunctionDecl; -class ParmVarDecl; -class Sema; -class TypeLoc; -class VarDecl; -class ObjCMethodDecl; - -/// \brief Describes an entity that is being initialized. -class InitializedEntity { -public: - /// \brief Specifies the kind of entity being initialized. - enum EntityKind { - /// \brief The entity being initialized is a variable. - EK_Variable, - /// \brief The entity being initialized is a function parameter. - EK_Parameter, - /// \brief The entity being initialized is the result of a function call. - EK_Result, - /// \brief The entity being initialized is an exception object that - /// is being thrown. - EK_Exception, - /// \brief The entity being initialized is a non-static data member - /// subobject. - EK_Member, - /// \brief The entity being initialized is an element of an array. - EK_ArrayElement, - /// \brief The entity being initialized is an object (or array of - /// objects) allocated via new. - EK_New, - /// \brief The entity being initialized is a temporary object. - EK_Temporary, - /// \brief The entity being initialized is a base member subobject. - EK_Base, - /// \brief The initialization is being done by a delegating constructor. - EK_Delegating, - /// \brief The entity being initialized is an element of a vector. - /// or vector. - EK_VectorElement, - /// \brief The entity being initialized is a field of block descriptor for - /// the copied-in c++ object. - EK_BlockElement, - /// \brief The entity being initialized is the real or imaginary part of a - /// complex number. - EK_ComplexElement, - /// \brief The entity being initialized is the field that captures a - /// variable in a lambda. - EK_LambdaCapture, - /// \brief The entity being initialized is the initializer for a compound - /// literal. - EK_CompoundLiteralInit, - /// \brief The entity being implicitly initialized back to the formal - /// result type. - EK_RelatedResult, - /// \brief The entity being initialized is a function parameter; function - /// is member of group of audited CF APIs. - EK_Parameter_CF_Audited - - // Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this - // enum as an index for its first %select. When modifying this list, - // that diagnostic text needs to be updated as well. - }; - -private: - /// \brief The kind of entity being initialized. - EntityKind Kind; - - /// \brief If non-NULL, the parent entity in which this - /// initialization occurs. - const InitializedEntity *Parent; - - /// \brief The type of the object or reference being initialized. - QualType Type; - - /// \brief The mangling number for the next reference temporary to be created. - mutable unsigned ManglingNumber; - - struct LN { - /// \brief When Kind == EK_Result, EK_Exception, EK_New, the - /// location of the 'return', 'throw', or 'new' keyword, - /// respectively. When Kind == EK_Temporary, the location where - /// the temporary is being created. - unsigned Location; - - /// \brief Whether the entity being initialized may end up using the - /// named return value optimization (NRVO). - bool NRVO; - }; - - struct C { - /// \brief The name of the variable being captured by an EK_LambdaCapture. - IdentifierInfo *VarID; - - /// \brief The source location at which the capture occurs. - unsigned Location; - }; - - union { - /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or - /// FieldDecl, respectively. - DeclaratorDecl *VariableOrMember; - - /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where - /// result type was implicitly changed to accommodate ARC semantics. - ObjCMethodDecl *MethodDecl; - - /// \brief When Kind == EK_Parameter, the ParmVarDecl, with the - /// low bit indicating whether the parameter is "consumed". - uintptr_t Parameter; - - /// \brief When Kind == EK_Temporary or EK_CompoundLiteralInit, the type - /// source information for the temporary. - TypeSourceInfo *TypeInfo; - - struct LN LocAndNRVO; - - /// \brief When Kind == EK_Base, the base specifier that provides the - /// base class. The lower bit specifies whether the base is an inherited - /// virtual base. - uintptr_t Base; - - /// \brief When Kind == EK_ArrayElement, EK_VectorElement, or - /// EK_ComplexElement, the index of the array or vector element being - /// initialized. - unsigned Index; - - struct C Capture; - }; - - InitializedEntity() : ManglingNumber(0) {} - - /// \brief Create the initialization entity for a variable. - InitializedEntity(VarDecl *Var) - : Kind(EK_Variable), Parent(nullptr), Type(Var->getType()), - ManglingNumber(0), VariableOrMember(Var) { } - - /// \brief Create the initialization entity for the result of a - /// function, throwing an object, performing an explicit cast, or - /// initializing a parameter for which there is no declaration. - InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type, - bool NRVO = false) - : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0) - { - LocAndNRVO.Location = Loc.getRawEncoding(); - LocAndNRVO.NRVO = NRVO; - } - - /// \brief Create the initialization entity for a member subobject. - InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) - : Kind(EK_Member), Parent(Parent), Type(Member->getType()), - ManglingNumber(0), VariableOrMember(Member) { } - - /// \brief Create the initialization entity for an array element. - InitializedEntity(ASTContext &Context, unsigned Index, - const InitializedEntity &Parent); - - /// \brief Create the initialization entity for a lambda capture. - InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) - : Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType), - ManglingNumber(0) - { - Capture.VarID = VarID; - Capture.Location = Loc.getRawEncoding(); - } - -public: - /// \brief Create the initialization entity for a variable. - static InitializedEntity InitializeVariable(VarDecl *Var) { - return InitializedEntity(Var); - } - - /// \brief Create the initialization entity for a parameter. - static InitializedEntity InitializeParameter(ASTContext &Context, - ParmVarDecl *Parm) { - return InitializeParameter(Context, Parm, Parm->getType()); - } - - /// \brief Create the initialization entity for a parameter, but use - /// another type. - static InitializedEntity InitializeParameter(ASTContext &Context, - ParmVarDecl *Parm, - QualType Type) { - bool Consumed = (Context.getLangOpts().ObjCAutoRefCount && - Parm->hasAttr<NSConsumedAttr>()); - - InitializedEntity Entity; - Entity.Kind = EK_Parameter; - Entity.Type = - Context.getVariableArrayDecayedType(Type.getUnqualifiedType()); - Entity.Parent = nullptr; - Entity.Parameter - = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm)); - return Entity; - } - - /// \brief Create the initialization entity for a parameter that is - /// only known by its type. - static InitializedEntity InitializeParameter(ASTContext &Context, - QualType Type, - bool Consumed) { - InitializedEntity Entity; - Entity.Kind = EK_Parameter; - Entity.Type = Context.getVariableArrayDecayedType(Type); - Entity.Parent = nullptr; - Entity.Parameter = (Consumed); - return Entity; - } - - /// \brief Create the initialization entity for the result of a function. - static InitializedEntity InitializeResult(SourceLocation ReturnLoc, - QualType Type, bool NRVO) { - return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO); - } - - static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc, - QualType Type, bool NRVO) { - return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO); - } - - /// \brief Create the initialization entity for an exception object. - static InitializedEntity InitializeException(SourceLocation ThrowLoc, - QualType Type, bool NRVO) { - return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO); - } - - /// \brief Create the initialization entity for an object allocated via new. - static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) { - return InitializedEntity(EK_New, NewLoc, Type); - } - - /// \brief Create the initialization entity for a temporary. - static InitializedEntity InitializeTemporary(QualType Type) { - InitializedEntity Result(EK_Temporary, SourceLocation(), Type); - Result.TypeInfo = nullptr; - return Result; - } - - /// \brief Create the initialization entity for a temporary. - static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) { - InitializedEntity Result(EK_Temporary, SourceLocation(), - TypeInfo->getType()); - Result.TypeInfo = TypeInfo; - return Result; - } - - /// \brief Create the initialization entity for a related result. - static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, - QualType Type) { - InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type); - Result.MethodDecl = MD; - return Result; - } - - - /// \brief Create the initialization entity for a base class subobject. - static InitializedEntity InitializeBase(ASTContext &Context, - const CXXBaseSpecifier *Base, - bool IsInheritedVirtualBase); - - /// \brief Create the initialization entity for a delegated constructor. - static InitializedEntity InitializeDelegation(QualType Type) { - return InitializedEntity(EK_Delegating, SourceLocation(), Type); - } - - /// \brief Create the initialization entity for a member subobject. - static InitializedEntity - InitializeMember(FieldDecl *Member, - const InitializedEntity *Parent = nullptr) { - return InitializedEntity(Member, Parent); - } - - /// \brief Create the initialization entity for a member subobject. - static InitializedEntity - InitializeMember(IndirectFieldDecl *Member, - const InitializedEntity *Parent = nullptr) { - return InitializedEntity(Member->getAnonField(), Parent); - } - - /// \brief Create the initialization entity for an array element. - static InitializedEntity InitializeElement(ASTContext &Context, - unsigned Index, - const InitializedEntity &Parent) { - return InitializedEntity(Context, Index, Parent); - } - - /// \brief Create the initialization entity for a lambda capture. - static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID, - QualType FieldType, - SourceLocation Loc) { - return InitializedEntity(VarID, FieldType, Loc); - } - - /// \brief Create the entity for a compound literal initializer. - static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) { - InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(), - TSI->getType()); - Result.TypeInfo = TSI; - return Result; - } - - - /// \brief Determine the kind of initialization. - EntityKind getKind() const { return Kind; } - - /// \brief Retrieve the parent of the entity being initialized, when - /// the initialization itself is occurring within the context of a - /// larger initialization. - const InitializedEntity *getParent() const { return Parent; } - - /// \brief Retrieve type being initialized. - QualType getType() const { return Type; } - - /// \brief Retrieve complete type-source information for the object being - /// constructed, if known. - TypeSourceInfo *getTypeSourceInfo() const { - if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit) - return TypeInfo; - - return nullptr; - } - - /// \brief Retrieve the name of the entity being initialized. - DeclarationName getName() const; - - /// \brief Retrieve the variable, parameter, or field being - /// initialized. - DeclaratorDecl *getDecl() const; - - /// \brief Retrieve the ObjectiveC method being initialized. - ObjCMethodDecl *getMethodDecl() const { return MethodDecl; } - - /// \brief Determine whether this initialization allows the named return - /// value optimization, which also applies to thrown objects. - bool allowsNRVO() const; - - bool isParameterKind() const { - return (getKind() == EK_Parameter || - getKind() == EK_Parameter_CF_Audited); - } - /// \brief Determine whether this initialization consumes the - /// parameter. - bool isParameterConsumed() const { - assert(isParameterKind() && "Not a parameter"); - return (Parameter & 1); - } - - /// \brief Retrieve the base specifier. - const CXXBaseSpecifier *getBaseSpecifier() const { - assert(getKind() == EK_Base && "Not a base specifier"); - return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1); - } - - /// \brief Return whether the base is an inherited virtual base. - bool isInheritedVirtualBase() const { - assert(getKind() == EK_Base && "Not a base specifier"); - return Base & 0x1; - } - - /// \brief Determine the location of the 'return' keyword when initializing - /// the result of a function call. - SourceLocation getReturnLoc() const { - assert(getKind() == EK_Result && "No 'return' location!"); - return SourceLocation::getFromRawEncoding(LocAndNRVO.Location); - } - - /// \brief Determine the location of the 'throw' keyword when initializing - /// an exception object. - SourceLocation getThrowLoc() const { - assert(getKind() == EK_Exception && "No 'throw' location!"); - return SourceLocation::getFromRawEncoding(LocAndNRVO.Location); - } - - /// \brief If this is an array, vector, or complex number element, get the - /// element's index. - unsigned getElementIndex() const { - assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement || - getKind() == EK_ComplexElement); - return Index; - } - /// \brief If this is already the initializer for an array or vector - /// element, sets the element index. - void setElementIndex(unsigned Index) { - assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement || - getKind() == EK_ComplexElement); - this->Index = Index; - } - /// \brief For a lambda capture, return the capture's name. - StringRef getCapturedVarName() const { - assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); - return Capture.VarID->getName(); - } - /// \brief Determine the location of the capture when initializing - /// field from a captured variable in a lambda. - SourceLocation getCaptureLoc() const { - assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); - return SourceLocation::getFromRawEncoding(Capture.Location); - } - - void setParameterCFAudited() { - Kind = EK_Parameter_CF_Audited; - } - - unsigned allocateManglingNumber() const { return ++ManglingNumber; } - - /// Dump a representation of the initialized entity to standard error, - /// for debugging purposes. - void dump() const; - -private: - unsigned dumpImpl(raw_ostream &OS) const; -}; - -/// \brief Describes the kind of initialization being performed, along with -/// location information for tokens related to the initialization (equal sign, -/// parentheses). -class InitializationKind { -public: - /// \brief The kind of initialization being performed. - enum InitKind { - IK_Direct, ///< Direct initialization - IK_DirectList, ///< Direct list-initialization - IK_Copy, ///< Copy initialization - IK_Default, ///< Default initialization - IK_Value ///< Value initialization - }; - -private: - /// \brief The context of the initialization. - enum InitContext { - IC_Normal, ///< Normal context - IC_ExplicitConvs, ///< Normal context, but allows explicit conversion funcs - IC_Implicit, ///< Implicit context (value initialization) - IC_StaticCast, ///< Static cast context - IC_CStyleCast, ///< C-style cast context - IC_FunctionalCast ///< Functional cast context - }; - - /// \brief The kind of initialization being performed. - InitKind Kind : 8; - - /// \brief The context of the initialization. - InitContext Context : 8; - - /// \brief The source locations involved in the initialization. - SourceLocation Locations[3]; - - InitializationKind(InitKind Kind, InitContext Context, SourceLocation Loc1, - SourceLocation Loc2, SourceLocation Loc3) - : Kind(Kind), Context(Context) - { - Locations[0] = Loc1; - Locations[1] = Loc2; - Locations[2] = Loc3; - } - -public: - /// \brief Create a direct initialization. - static InitializationKind CreateDirect(SourceLocation InitLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc) { - return InitializationKind(IK_Direct, IC_Normal, - InitLoc, LParenLoc, RParenLoc); - } - - static InitializationKind CreateDirectList(SourceLocation InitLoc) { - return InitializationKind(IK_DirectList, IC_Normal, - InitLoc, InitLoc, InitLoc); - } - - /// \brief Create a direct initialization due to a cast that isn't a C-style - /// or functional cast. - static InitializationKind CreateCast(SourceRange TypeRange) { - return InitializationKind(IK_Direct, IC_StaticCast, TypeRange.getBegin(), - TypeRange.getBegin(), TypeRange.getEnd()); - } - - /// \brief Create a direct initialization for a C-style cast. - static InitializationKind CreateCStyleCast(SourceLocation StartLoc, - SourceRange TypeRange, - bool InitList) { - // C++ cast syntax doesn't permit init lists, but C compound literals are - // exactly that. - return InitializationKind(InitList ? IK_DirectList : IK_Direct, - IC_CStyleCast, StartLoc, TypeRange.getBegin(), - TypeRange.getEnd()); - } - - /// \brief Create a direct initialization for a functional cast. - static InitializationKind CreateFunctionalCast(SourceRange TypeRange, - bool InitList) { - return InitializationKind(InitList ? IK_DirectList : IK_Direct, - IC_FunctionalCast, TypeRange.getBegin(), - TypeRange.getBegin(), TypeRange.getEnd()); - } - - /// \brief Create a copy initialization. - static InitializationKind CreateCopy(SourceLocation InitLoc, - SourceLocation EqualLoc, - bool AllowExplicitConvs = false) { - return InitializationKind(IK_Copy, - AllowExplicitConvs? IC_ExplicitConvs : IC_Normal, - InitLoc, EqualLoc, EqualLoc); - } - - /// \brief Create a default initialization. - static InitializationKind CreateDefault(SourceLocation InitLoc) { - return InitializationKind(IK_Default, IC_Normal, InitLoc, InitLoc, InitLoc); - } - - /// \brief Create a value initialization. - static InitializationKind CreateValue(SourceLocation InitLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc, - bool isImplicit = false) { - return InitializationKind(IK_Value, isImplicit ? IC_Implicit : IC_Normal, - InitLoc, LParenLoc, RParenLoc); - } - - /// \brief Determine the initialization kind. - InitKind getKind() const { - return Kind; - } - - /// \brief Determine whether this initialization is an explicit cast. - bool isExplicitCast() const { - return Context >= IC_StaticCast; - } - - /// \brief Determine whether this initialization is a C-style cast. - bool isCStyleOrFunctionalCast() const { - return Context >= IC_CStyleCast; - } - - /// \brief Determine whether this is a C-style cast. - bool isCStyleCast() const { - return Context == IC_CStyleCast; - } - - /// \brief Determine whether this is a functional-style cast. - bool isFunctionalCast() const { - return Context == IC_FunctionalCast; - } - - /// \brief Determine whether this initialization is an implicit - /// value-initialization, e.g., as occurs during aggregate - /// initialization. - bool isImplicitValueInit() const { return Context == IC_Implicit; } - - /// \brief Retrieve the location at which initialization is occurring. - SourceLocation getLocation() const { return Locations[0]; } - - /// \brief Retrieve the source range that covers the initialization. - SourceRange getRange() const { - return SourceRange(Locations[0], Locations[2]); - } - - /// \brief Retrieve the location of the equal sign for copy initialization - /// (if present). - SourceLocation getEqualLoc() const { - assert(Kind == IK_Copy && "Only copy initialization has an '='"); - return Locations[1]; - } - - bool isCopyInit() const { return Kind == IK_Copy; } - - /// \brief Retrieve whether this initialization allows the use of explicit - /// constructors. - bool AllowExplicit() const { return !isCopyInit(); } - - /// \brief Retrieve whether this initialization allows the use of explicit - /// conversion functions when binding a reference. If the reference is the - /// first parameter in a copy or move constructor, such conversions are - /// permitted even though we are performing copy-initialization. - bool allowExplicitConversionFunctionsInRefBinding() const { - return !isCopyInit() || Context == IC_ExplicitConvs; - } - - /// \brief Retrieve the source range containing the locations of the open - /// and closing parentheses for value and direct initializations. - SourceRange getParenRange() const { - assert((Kind == IK_Direct || Kind == IK_Value) && - "Only direct- and value-initialization have parentheses"); - return SourceRange(Locations[1], Locations[2]); - } -}; - -/// \brief Describes the sequence of initializations required to initialize -/// a given object or reference with a set of arguments. -class InitializationSequence { -public: - /// \brief Describes the kind of initialization sequence computed. - enum SequenceKind { - /// \brief A failed initialization sequence. The failure kind tells what - /// happened. - FailedSequence = 0, - - /// \brief A dependent initialization, which could not be - /// type-checked due to the presence of dependent types or - /// dependently-typed expressions. - DependentSequence, - - /// \brief A normal sequence. - NormalSequence - }; - - /// \brief Describes the kind of a particular step in an initialization - /// sequence. - enum StepKind { - /// \brief Resolve the address of an overloaded function to a specific - /// function declaration. - SK_ResolveAddressOfOverloadedFunction, - /// \brief Perform a derived-to-base cast, producing an rvalue. - SK_CastDerivedToBaseRValue, - /// \brief Perform a derived-to-base cast, producing an xvalue. - SK_CastDerivedToBaseXValue, - /// \brief Perform a derived-to-base cast, producing an lvalue. - SK_CastDerivedToBaseLValue, - /// \brief Reference binding to an lvalue. - SK_BindReference, - /// \brief Reference binding to a temporary. - SK_BindReferenceToTemporary, - /// \brief An optional copy of a temporary object to another - /// temporary object, which is permitted (but not required) by - /// C++98/03 but not C++0x. - SK_ExtraneousCopyToTemporary, - /// \brief Perform a user-defined conversion, either via a conversion - /// function or via a constructor. - SK_UserConversion, - /// \brief Perform a qualification conversion, producing an rvalue. - SK_QualificationConversionRValue, - /// \brief Perform a qualification conversion, producing an xvalue. - SK_QualificationConversionXValue, - /// \brief Perform a qualification conversion, producing an lvalue. - SK_QualificationConversionLValue, - /// \brief Perform a conversion adding _Atomic to a type. - SK_AtomicConversion, - /// \brief Perform a load from a glvalue, producing an rvalue. - SK_LValueToRValue, - /// \brief Perform an implicit conversion sequence. - SK_ConversionSequence, - /// \brief Perform an implicit conversion sequence without narrowing. - SK_ConversionSequenceNoNarrowing, - /// \brief Perform list-initialization without a constructor. - SK_ListInitialization, - /// \brief Unwrap the single-element initializer list for a reference. - SK_UnwrapInitList, - /// \brief Rewrap the single-element initializer list for a reference. - SK_RewrapInitList, - /// \brief Perform initialization via a constructor. - SK_ConstructorInitialization, - /// \brief Perform initialization via a constructor, taking arguments from - /// a single InitListExpr. - SK_ConstructorInitializationFromList, - /// \brief Zero-initialize the object - SK_ZeroInitialization, - /// \brief C assignment - SK_CAssignment, - /// \brief Initialization by string - SK_StringInit, - /// \brief An initialization that "converts" an Objective-C object - /// (not a point to an object) to another Objective-C object type. - SK_ObjCObjectConversion, - /// \brief Array initialization (from an array rvalue). - /// This is a GNU C extension. - SK_ArrayInit, - /// \brief Array initialization from a parenthesized initializer list. - /// This is a GNU C++ extension. - SK_ParenthesizedArrayInit, - /// \brief Pass an object by indirect copy-and-restore. - SK_PassByIndirectCopyRestore, - /// \brief Pass an object by indirect restore. - SK_PassByIndirectRestore, - /// \brief Produce an Objective-C object pointer. - SK_ProduceObjCObject, - /// \brief Construct a std::initializer_list from an initializer list. - SK_StdInitializerList, - /// \brief Perform initialization via a constructor taking a single - /// std::initializer_list argument. - SK_StdInitializerListConstructorCall, - /// \brief Initialize an OpenCL sampler from an integer. - SK_OCLSamplerInit, - /// \brief Passing zero to a function where OpenCL event_t is expected. - SK_OCLZeroEvent - }; - - /// \brief A single step in the initialization sequence. - class Step { - public: - /// \brief The kind of conversion or initialization step we are taking. - StepKind Kind; - - // \brief The type that results from this initialization. - QualType Type; - - struct F { - bool HadMultipleCandidates; - FunctionDecl *Function; - DeclAccessPair FoundDecl; - }; - - union { - /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind == - /// SK_UserConversion, the function that the expression should be - /// resolved to or the conversion function to call, respectively. - /// When Kind == SK_ConstructorInitialization or SK_ListConstruction, - /// the constructor to be called. - /// - /// Always a FunctionDecl, plus a Boolean flag telling if it was - /// selected from an overloaded set having size greater than 1. - /// For conversion decls, the naming class is the source type. - /// For construct decls, the naming class is the target type. - struct F Function; - - /// \brief When Kind = SK_ConversionSequence, the implicit conversion - /// sequence. - ImplicitConversionSequence *ICS; - - /// \brief When Kind = SK_RewrapInitList, the syntactic form of the - /// wrapping list. - InitListExpr *WrappingSyntacticList; - }; - - void Destroy(); - }; - -private: - /// \brief The kind of initialization sequence computed. - enum SequenceKind SequenceKind; - - /// \brief Steps taken by this initialization. - SmallVector<Step, 4> Steps; - -public: - /// \brief Describes why initialization failed. - enum FailureKind { - /// \brief Too many initializers provided for a reference. - FK_TooManyInitsForReference, - /// \brief Array must be initialized with an initializer list. - FK_ArrayNeedsInitList, - /// \brief Array must be initialized with an initializer list or a - /// string literal. - FK_ArrayNeedsInitListOrStringLiteral, - /// \brief Array must be initialized with an initializer list or a - /// wide string literal. - FK_ArrayNeedsInitListOrWideStringLiteral, - /// \brief Initializing a wide char array with narrow string literal. - FK_NarrowStringIntoWideCharArray, - /// \brief Initializing char array with wide string literal. - FK_WideStringIntoCharArray, - /// \brief Initializing wide char array with incompatible wide string - /// literal. - FK_IncompatWideStringIntoWideChar, - /// \brief Array type mismatch. - FK_ArrayTypeMismatch, - /// \brief Non-constant array initializer - FK_NonConstantArrayInit, - /// \brief Cannot resolve the address of an overloaded function. - FK_AddressOfOverloadFailed, - /// \brief Overloading due to reference initialization failed. - FK_ReferenceInitOverloadFailed, - /// \brief Non-const lvalue reference binding to a temporary. - FK_NonConstLValueReferenceBindingToTemporary, - /// \brief Non-const lvalue reference binding to an lvalue of unrelated - /// type. - FK_NonConstLValueReferenceBindingToUnrelated, - /// \brief Rvalue reference binding to an lvalue. - FK_RValueReferenceBindingToLValue, - /// \brief Reference binding drops qualifiers. - FK_ReferenceInitDropsQualifiers, - /// \brief Reference binding failed. - FK_ReferenceInitFailed, - /// \brief Implicit conversion failed. - FK_ConversionFailed, - /// \brief Implicit conversion failed. - FK_ConversionFromPropertyFailed, - /// \brief Too many initializers for scalar - FK_TooManyInitsForScalar, - /// \brief Reference initialization from an initializer list - FK_ReferenceBindingToInitList, - /// \brief Initialization of some unused destination type with an - /// initializer list. - FK_InitListBadDestinationType, - /// \brief Overloading for a user-defined conversion failed. - FK_UserConversionOverloadFailed, - /// \brief Overloading for initialization by constructor failed. - FK_ConstructorOverloadFailed, - /// \brief Overloading for list-initialization by constructor failed. - FK_ListConstructorOverloadFailed, - /// \brief Default-initialization of a 'const' object. - FK_DefaultInitOfConst, - /// \brief Initialization of an incomplete type. - FK_Incomplete, - /// \brief Variable-length array must not have an initializer. - FK_VariableLengthArrayHasInitializer, - /// \brief List initialization failed at some point. - FK_ListInitializationFailed, - /// \brief Initializer has a placeholder type which cannot be - /// resolved by initialization. - FK_PlaceholderType, - /// \brief Trying to take the address of a function that doesn't support - /// having its address taken. - FK_AddressOfUnaddressableFunction, - /// \brief List-copy-initialization chose an explicit constructor. - FK_ExplicitConstructor - }; - -private: - /// \brief The reason why initialization failed. - FailureKind Failure; - - /// \brief The failed result of overload resolution. - OverloadingResult FailedOverloadResult; - - /// \brief The candidate set created when initialization failed. - OverloadCandidateSet FailedCandidateSet; - - /// \brief The incomplete type that caused a failure. - QualType FailedIncompleteType; - - /// \brief The fixit that needs to be applied to make this initialization - /// succeed. - std::string ZeroInitializationFixit; - SourceLocation ZeroInitializationFixitLoc; - -public: - /// \brief Call for initializations are invalid but that would be valid - /// zero initialzations if Fixit was applied. - void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) { - ZeroInitializationFixit = Fixit; - ZeroInitializationFixitLoc = L; - } - -private: - - /// \brief Prints a follow-up note that highlights the location of - /// the initialized entity, if it's remote. - void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity); - -public: - /// \brief Try to perform initialization of the given entity, creating a - /// record of the steps required to perform the initialization. - /// - /// The generated initialization sequence will either contain enough - /// information to diagnose - /// - /// \param S the semantic analysis object. - /// - /// \param Entity the entity being initialized. - /// - /// \param Kind the kind of initialization being performed. - /// - /// \param Args the argument(s) provided for initialization. - /// - /// \param TopLevelOfInitList true if we are initializing from an expression - /// at the top level inside an initializer list. This disallows - /// narrowing conversions in C++11 onwards. - InitializationSequence(Sema &S, - const InitializedEntity &Entity, - const InitializationKind &Kind, - MultiExprArg Args, - bool TopLevelOfInitList = false); - void InitializeFrom(Sema &S, const InitializedEntity &Entity, - const InitializationKind &Kind, MultiExprArg Args, - bool TopLevelOfInitList); - - ~InitializationSequence(); - - /// \brief Perform the actual initialization of the given entity based on - /// the computed initialization sequence. - /// - /// \param S the semantic analysis object. - /// - /// \param Entity the entity being initialized. - /// - /// \param Kind the kind of initialization being performed. - /// - /// \param Args the argument(s) provided for initialization, ownership of - /// which is transferred into the routine. - /// - /// \param ResultType if non-NULL, will be set to the type of the - /// initialized object, which is the type of the declaration in most - /// cases. However, when the initialized object is a variable of - /// incomplete array type and the initializer is an initializer - /// list, this type will be set to the completed array type. - /// - /// \returns an expression that performs the actual object initialization, if - /// the initialization is well-formed. Otherwise, emits diagnostics - /// and returns an invalid expression. - ExprResult Perform(Sema &S, - const InitializedEntity &Entity, - const InitializationKind &Kind, - MultiExprArg Args, - QualType *ResultType = nullptr); - - /// \brief Diagnose an potentially-invalid initialization sequence. - /// - /// \returns true if the initialization sequence was ill-formed, - /// false otherwise. - bool Diagnose(Sema &S, - const InitializedEntity &Entity, - const InitializationKind &Kind, - ArrayRef<Expr *> Args); - - /// \brief Determine the kind of initialization sequence computed. - enum SequenceKind getKind() const { return SequenceKind; } - - /// \brief Set the kind of sequence computed. - void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } - - /// \brief Determine whether the initialization sequence is valid. - explicit operator bool() const { return !Failed(); } - - /// \brief Determine whether the initialization sequence is invalid. - bool Failed() const { return SequenceKind == FailedSequence; } - - typedef SmallVectorImpl<Step>::const_iterator step_iterator; - step_iterator step_begin() const { return Steps.begin(); } - step_iterator step_end() const { return Steps.end(); } - - /// \brief Determine whether this initialization is a direct reference - /// binding (C++ [dcl.init.ref]). - bool isDirectReferenceBinding() const; - - /// \brief Determine whether this initialization failed due to an ambiguity. - bool isAmbiguous() const; - - /// \brief Determine whether this initialization is direct call to a - /// constructor. - bool isConstructorInitialization() const; - - /// \brief Returns whether the last step in this initialization sequence is a - /// narrowing conversion, defined by C++0x [dcl.init.list]p7. - /// - /// If this function returns true, *isInitializerConstant will be set to - /// describe whether *Initializer was a constant expression. If - /// *isInitializerConstant is set to true, *ConstantValue will be set to the - /// evaluated value of *Initializer. - bool endsWithNarrowing(ASTContext &Ctx, const Expr *Initializer, - bool *isInitializerConstant, - APValue *ConstantValue) const; - - /// \brief Add a new step in the initialization that resolves the address - /// of an overloaded function to a specific function declaration. - /// - /// \param Function the function to which the overloaded function reference - /// resolves. - void AddAddressOverloadResolutionStep(FunctionDecl *Function, - DeclAccessPair Found, - bool HadMultipleCandidates); - - /// \brief Add a new step in the initialization that performs a derived-to- - /// base cast. - /// - /// \param BaseType the base type to which we will be casting. - /// - /// \param Category Indicates whether the result will be treated as an - /// rvalue, an xvalue, or an lvalue. - void AddDerivedToBaseCastStep(QualType BaseType, - ExprValueKind Category); - - /// \brief Add a new step binding a reference to an object. - /// - /// \param BindingTemporary True if we are binding a reference to a temporary - /// object (thereby extending its lifetime); false if we are binding to an - /// lvalue or an lvalue treated as an rvalue. - void AddReferenceBindingStep(QualType T, bool BindingTemporary); - - /// \brief Add a new step that makes an extraneous copy of the input - /// to a temporary of the same class type. - /// - /// This extraneous copy only occurs during reference binding in - /// C++98/03, where we are permitted (but not required) to introduce - /// an extra copy. At a bare minimum, we must check that we could - /// call the copy constructor, and produce a diagnostic if the copy - /// constructor is inaccessible or no copy constructor matches. - // - /// \param T The type of the temporary being created. - void AddExtraneousCopyToTemporary(QualType T); - - /// \brief Add a new step invoking a conversion function, which is either - /// a constructor or a conversion function. - void AddUserConversionStep(FunctionDecl *Function, - DeclAccessPair FoundDecl, - QualType T, - bool HadMultipleCandidates); - - /// \brief Add a new step that performs a qualification conversion to the - /// given type. - void AddQualificationConversionStep(QualType Ty, - ExprValueKind Category); - - /// \brief Add a new step that performs conversion from non-atomic to atomic - /// type. - void AddAtomicConversionStep(QualType Ty); - - /// \brief Add a new step that performs a load of the given type. - /// - /// Although the term "LValueToRValue" is conventional, this applies to both - /// lvalues and xvalues. - void AddLValueToRValueStep(QualType Ty); - - /// \brief Add a new step that applies an implicit conversion sequence. - void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, - QualType T, bool TopLevelOfInitList = false); - - /// \brief Add a list-initialization step. - void AddListInitializationStep(QualType T); - - /// \brief Add a constructor-initialization step. - /// - /// \param FromInitList The constructor call is syntactically an initializer - /// list. - /// \param AsInitList The constructor is called as an init list constructor. - void AddConstructorInitializationStep(CXXConstructorDecl *Constructor, - AccessSpecifier Access, - QualType T, - bool HadMultipleCandidates, - bool FromInitList, bool AsInitList); - - /// \brief Add a zero-initialization step. - void AddZeroInitializationStep(QualType T); - - /// \brief Add a C assignment step. - // - // FIXME: It isn't clear whether this should ever be needed; - // ideally, we would handle everything needed in C in the common - // path. However, that isn't the case yet. - void AddCAssignmentStep(QualType T); - - /// \brief Add a string init step. - void AddStringInitStep(QualType T); - - /// \brief Add an Objective-C object conversion step, which is - /// always a no-op. - void AddObjCObjectConversionStep(QualType T); - - /// \brief Add an array initialization step. - void AddArrayInitStep(QualType T); - - /// \brief Add a parenthesized array initialization step. - void AddParenthesizedArrayInitStep(QualType T); - - /// \brief Add a step to pass an object by indirect copy-restore. - void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy); - - /// \brief Add a step to "produce" an Objective-C object (by - /// retaining it). - void AddProduceObjCObjectStep(QualType T); - - /// \brief Add a step to construct a std::initializer_list object from an - /// initializer list. - void AddStdInitializerListConstructionStep(QualType T); - - /// \brief Add a step to initialize an OpenCL sampler from an integer - /// constant. - void AddOCLSamplerInitStep(QualType T); - - /// \brief Add a step to initialize an OpenCL event_t from a NULL - /// constant. - void AddOCLZeroEventStep(QualType T); - - /// \brief Add steps to unwrap a initializer list for a reference around a - /// single element and rewrap it at the end. - void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic); - - /// \brief Note that this initialization sequence failed. - void SetFailed(FailureKind Failure) { - SequenceKind = FailedSequence; - this->Failure = Failure; - assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) && - "Incomplete type failure requires a type!"); - } - - /// \brief Note that this initialization sequence failed due to failed - /// overload resolution. - void SetOverloadFailure(FailureKind Failure, OverloadingResult Result); - - /// \brief Retrieve a reference to the candidate set when overload - /// resolution fails. - OverloadCandidateSet &getFailedCandidateSet() { - return FailedCandidateSet; - } - - /// \brief Get the overloading result, for when the initialization - /// sequence failed due to a bad overload. - OverloadingResult getFailedOverloadResult() const { - return FailedOverloadResult; - } - - /// \brief Note that this initialization sequence failed due to an - /// incomplete type. - void setIncompleteTypeFailure(QualType IncompleteType) { - FailedIncompleteType = IncompleteType; - SetFailed(FK_Incomplete); - } - - /// \brief Determine why initialization failed. - FailureKind getFailureKind() const { - assert(Failed() && "Not an initialization failure!"); - return Failure; - } - - /// \brief Dump a representation of this initialization sequence to - /// the given stream, for debugging purposes. - void dump(raw_ostream &OS) const; - - /// \brief Dump a representation of this initialization sequence to - /// standard error, for debugging purposes. - void dump() const; -}; - -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_INITIALIZATION_H diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/Sema/LocInfoType.h deleted file mode 100644 index 63dfa72..0000000 --- a/include/clang/Sema/LocInfoType.h +++ /dev/null @@ -1,62 +0,0 @@ -//===--- LocInfoType.h - Parsed Type with Location Information---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the LocInfoType class, which holds a type and its -// source-location information. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H -#define LLVM_CLANG_SEMA_LOCINFOTYPE_H - -#include "clang/AST/Type.h" - -namespace clang { - -class TypeSourceInfo; - -/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator -/// parsing. -/// -/// LocInfoType is a "transient" type, only needed for passing to/from Parser -/// and Sema, when we want to preserve type source info for a parsed type. -/// It will not participate in the type system semantics in any way. -class LocInfoType : public Type { - enum { - // The last number that can fit in Type's TC. - // Avoids conflict with an existing Type class. - LocInfo = Type::TypeLast + 1 - }; - - TypeSourceInfo *DeclInfo; - - LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isInstantiationDependentType(), - ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { - assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); - } - friend class Sema; - -public: - QualType getType() const { return getCanonicalTypeInternal(); } - TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; } - - void getAsStringInternal(std::string &Str, - const PrintingPolicy &Policy) const; - - static bool classof(const Type *T) { - return T->getTypeClass() == (TypeClass)LocInfo; - } -}; - -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h deleted file mode 100644 index 87c40f0..0000000 --- a/include/clang/Sema/Lookup.h +++ /dev/null @@ -1,760 +0,0 @@ -//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the LookupResult class, which is integral to -// Sema's name-lookup subsystem. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_LOOKUP_H -#define LLVM_CLANG_SEMA_LOOKUP_H - -#include "clang/AST/DeclCXX.h" -#include "clang/Sema/Sema.h" - -namespace clang { - -/// @brief Represents the results of name lookup. -/// -/// An instance of the LookupResult class captures the results of a -/// single name lookup, which can return no result (nothing found), -/// a single declaration, a set of overloaded functions, or an -/// ambiguity. Use the getKind() method to determine which of these -/// results occurred for a given lookup. -class LookupResult { -public: - enum LookupResultKind { - /// @brief No entity found met the criteria. - NotFound = 0, - - /// @brief No entity found met the criteria within the current - /// instantiation,, but there were dependent base classes of the - /// current instantiation that could not be searched. - NotFoundInCurrentInstantiation, - - /// @brief Name lookup found a single declaration that met the - /// criteria. getFoundDecl() will return this declaration. - Found, - - /// @brief Name lookup found a set of overloaded functions that - /// met the criteria. - FoundOverloaded, - - /// @brief Name lookup found an unresolvable value declaration - /// and cannot yet complete. This only happens in C++ dependent - /// contexts with dependent using declarations. - FoundUnresolvedValue, - - /// @brief Name lookup results in an ambiguity; use - /// getAmbiguityKind to figure out what kind of ambiguity - /// we have. - Ambiguous - }; - - enum AmbiguityKind { - /// Name lookup results in an ambiguity because multiple - /// entities that meet the lookup criteria were found in - /// subobjects of different types. For example: - /// @code - /// struct A { void f(int); } - /// struct B { void f(double); } - /// struct C : A, B { }; - /// void test(C c) { - /// c.f(0); // error: A::f and B::f come from subobjects of different - /// // types. overload resolution is not performed. - /// } - /// @endcode - AmbiguousBaseSubobjectTypes, - - /// Name lookup results in an ambiguity because multiple - /// nonstatic entities that meet the lookup criteria were found - /// in different subobjects of the same type. For example: - /// @code - /// struct A { int x; }; - /// struct B : A { }; - /// struct C : A { }; - /// struct D : B, C { }; - /// int test(D d) { - /// return d.x; // error: 'x' is found in two A subobjects (of B and C) - /// } - /// @endcode - AmbiguousBaseSubobjects, - - /// Name lookup results in an ambiguity because multiple definitions - /// of entity that meet the lookup criteria were found in different - /// declaration contexts. - /// @code - /// namespace A { - /// int i; - /// namespace B { int i; } - /// int test() { - /// using namespace B; - /// return i; // error 'i' is found in namespace A and A::B - /// } - /// } - /// @endcode - AmbiguousReference, - - /// Name lookup results in an ambiguity because an entity with a - /// tag name was hidden by an entity with an ordinary name from - /// a different context. - /// @code - /// namespace A { struct Foo {}; } - /// namespace B { void Foo(); } - /// namespace C { - /// using namespace A; - /// using namespace B; - /// } - /// void test() { - /// C::Foo(); // error: tag 'A::Foo' is hidden by an object in a - /// // different namespace - /// } - /// @endcode - AmbiguousTagHiding - }; - - /// A little identifier for flagging temporary lookup results. - enum TemporaryToken { - Temporary - }; - - typedef UnresolvedSetImpl::iterator iterator; - - LookupResult(Sema &SemaRef, const DeclarationNameInfo &NameInfo, - Sema::LookupNameKind LookupKind, - Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) - : ResultKind(NotFound), - Paths(nullptr), - NamingClass(nullptr), - SemaPtr(&SemaRef), - NameInfo(NameInfo), - LookupKind(LookupKind), - IDNS(0), - Redecl(Redecl != Sema::NotForRedeclaration), - HideTags(true), - Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(false), - Shadowed(false) - { - configure(); - } - - // TODO: consider whether this constructor should be restricted to take - // as input a const IndentifierInfo* (instead of Name), - // forcing other cases towards the constructor taking a DNInfo. - LookupResult(Sema &SemaRef, DeclarationName Name, - SourceLocation NameLoc, Sema::LookupNameKind LookupKind, - Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration) - : ResultKind(NotFound), - Paths(nullptr), - NamingClass(nullptr), - SemaPtr(&SemaRef), - NameInfo(Name, NameLoc), - LookupKind(LookupKind), - IDNS(0), - Redecl(Redecl != Sema::NotForRedeclaration), - HideTags(true), - Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(false), - Shadowed(false) - { - configure(); - } - - /// Creates a temporary lookup result, initializing its core data - /// using the information from another result. Diagnostics are always - /// disabled. - LookupResult(TemporaryToken _, const LookupResult &Other) - : ResultKind(NotFound), - Paths(nullptr), - NamingClass(nullptr), - SemaPtr(Other.SemaPtr), - NameInfo(Other.NameInfo), - LookupKind(Other.LookupKind), - IDNS(Other.IDNS), - Redecl(Other.Redecl), - HideTags(Other.HideTags), - Diagnose(false), - AllowHidden(Other.AllowHidden), - Shadowed(false) - {} - - ~LookupResult() { - if (Diagnose) diagnose(); - if (Paths) deletePaths(Paths); - } - - /// Gets the name info to look up. - const DeclarationNameInfo &getLookupNameInfo() const { - return NameInfo; - } - - /// \brief Sets the name info to look up. - void setLookupNameInfo(const DeclarationNameInfo &NameInfo) { - this->NameInfo = NameInfo; - } - - /// Gets the name to look up. - DeclarationName getLookupName() const { - return NameInfo.getName(); - } - - /// \brief Sets the name to look up. - void setLookupName(DeclarationName Name) { - NameInfo.setName(Name); - } - - /// Gets the kind of lookup to perform. - Sema::LookupNameKind getLookupKind() const { - return LookupKind; - } - - /// True if this lookup is just looking for an existing declaration. - bool isForRedeclaration() const { - return Redecl; - } - - /// \brief Specify whether hidden declarations are visible, e.g., - /// for recovery reasons. - void setAllowHidden(bool AH) { - AllowHidden = AH; - } - - /// \brief Determine whether this lookup is permitted to see hidden - /// declarations, such as those in modules that have not yet been imported. - bool isHiddenDeclarationVisible(NamedDecl *ND) const { - return AllowHidden || - (isForRedeclaration() && ND->isExternallyVisible()); - } - - /// Sets whether tag declarations should be hidden by non-tag - /// declarations during resolution. The default is true. - void setHideTags(bool Hide) { - HideTags = Hide; - } - - bool isAmbiguous() const { - return getResultKind() == Ambiguous; - } - - /// Determines if this names a single result which is not an - /// unresolved value using decl. If so, it is safe to call - /// getFoundDecl(). - bool isSingleResult() const { - return getResultKind() == Found; - } - - /// Determines if the results are overloaded. - bool isOverloadedResult() const { - return getResultKind() == FoundOverloaded; - } - - bool isUnresolvableResult() const { - return getResultKind() == FoundUnresolvedValue; - } - - LookupResultKind getResultKind() const { - assert(sanity()); - return ResultKind; - } - - AmbiguityKind getAmbiguityKind() const { - assert(isAmbiguous()); - return Ambiguity; - } - - const UnresolvedSetImpl &asUnresolvedSet() const { - return Decls; - } - - iterator begin() const { return iterator(Decls.begin()); } - iterator end() const { return iterator(Decls.end()); } - - /// \brief Return true if no decls were found - bool empty() const { return Decls.empty(); } - - /// \brief Return the base paths structure that's associated with - /// these results, or null if none is. - CXXBasePaths *getBasePaths() const { - return Paths; - } - - /// \brief Determine whether the given declaration is visible to the - /// program. - static bool isVisible(Sema &SemaRef, NamedDecl *D) { - // If this declaration is not hidden, it's visible. - if (!D->isHidden()) - return true; - - // During template instantiation, we can refer to hidden declarations, if - // they were visible in any module along the path of instantiation. - return isVisibleSlow(SemaRef, D); - } - - /// \brief Retrieve the accepted (re)declaration of the given declaration, - /// if there is one. - NamedDecl *getAcceptableDecl(NamedDecl *D) const { - if (!D->isInIdentifierNamespace(IDNS)) - return nullptr; - - if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D)) - return D; - - return getAcceptableDeclSlow(D); - } - -private: - static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D); - NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const; - -public: - /// \brief Returns the identifier namespace mask for this lookup. - unsigned getIdentifierNamespace() const { - return IDNS; - } - - /// \brief Returns whether these results arose from performing a - /// lookup into a class. - bool isClassLookup() const { - return NamingClass != nullptr; - } - - /// \brief Returns the 'naming class' for this lookup, i.e. the - /// class which was looked into to find these results. - /// - /// C++0x [class.access.base]p5: - /// The access to a member is affected by the class in which the - /// member is named. This naming class is the class in which the - /// member name was looked up and found. [Note: this class can be - /// explicit, e.g., when a qualified-id is used, or implicit, - /// e.g., when a class member access operator (5.2.5) is used - /// (including cases where an implicit "this->" is added). If both - /// a class member access operator and a qualified-id are used to - /// name the member (as in p->T::m), the class naming the member - /// is the class named by the nested-name-specifier of the - /// qualified-id (that is, T). -- end note ] - /// - /// This is set by the lookup routines when they find results in a class. - CXXRecordDecl *getNamingClass() const { - return NamingClass; - } - - /// \brief Sets the 'naming class' for this lookup. - void setNamingClass(CXXRecordDecl *Record) { - NamingClass = Record; - } - - /// \brief Returns the base object type associated with this lookup; - /// important for [class.protected]. Most lookups do not have an - /// associated base object. - QualType getBaseObjectType() const { - return BaseObjectType; - } - - /// \brief Sets the base object type for this lookup. - void setBaseObjectType(QualType T) { - BaseObjectType = T; - } - - /// \brief Add a declaration to these results with its natural access. - /// Does not test the acceptance criteria. - void addDecl(NamedDecl *D) { - addDecl(D, D->getAccess()); - } - - /// \brief Add a declaration to these results with the given access. - /// Does not test the acceptance criteria. - void addDecl(NamedDecl *D, AccessSpecifier AS) { - Decls.addDecl(D, AS); - ResultKind = Found; - } - - /// \brief Add all the declarations from another set of lookup - /// results. - void addAllDecls(const LookupResult &Other) { - Decls.append(Other.Decls.begin(), Other.Decls.end()); - ResultKind = Found; - } - - /// \brief Determine whether no result was found because we could not - /// search into dependent base classes of the current instantiation. - bool wasNotFoundInCurrentInstantiation() const { - return ResultKind == NotFoundInCurrentInstantiation; - } - - /// \brief Note that while no result was found in the current instantiation, - /// there were dependent base classes that could not be searched. - void setNotFoundInCurrentInstantiation() { - assert(ResultKind == NotFound && Decls.empty()); - ResultKind = NotFoundInCurrentInstantiation; - } - - /// \brief Determine whether the lookup result was shadowed by some other - /// declaration that lookup ignored. - bool isShadowed() const { return Shadowed; } - - /// \brief Note that we found and ignored a declaration while performing - /// lookup. - void setShadowed() { Shadowed = true; } - - /// \brief Resolves the result kind of the lookup, possibly hiding - /// decls. - /// - /// This should be called in any environment where lookup might - /// generate multiple lookup results. - void resolveKind(); - - /// \brief Re-resolves the result kind of the lookup after a set of - /// removals has been performed. - void resolveKindAfterFilter() { - if (Decls.empty()) { - if (ResultKind != NotFoundInCurrentInstantiation) - ResultKind = NotFound; - - if (Paths) { - deletePaths(Paths); - Paths = nullptr; - } - } else { - AmbiguityKind SavedAK; - bool WasAmbiguous = false; - if (ResultKind == Ambiguous) { - SavedAK = Ambiguity; - WasAmbiguous = true; - } - ResultKind = Found; - resolveKind(); - - // If we didn't make the lookup unambiguous, restore the old - // ambiguity kind. - if (ResultKind == Ambiguous) { - (void)WasAmbiguous; - assert(WasAmbiguous); - Ambiguity = SavedAK; - } else if (Paths) { - deletePaths(Paths); - Paths = nullptr; - } - } - } - - template <class DeclClass> - DeclClass *getAsSingle() const { - if (getResultKind() != Found) return nullptr; - return dyn_cast<DeclClass>(getFoundDecl()); - } - - /// \brief Fetch the unique decl found by this lookup. Asserts - /// that one was found. - /// - /// This is intended for users who have examined the result kind - /// and are certain that there is only one result. - NamedDecl *getFoundDecl() const { - assert(getResultKind() == Found - && "getFoundDecl called on non-unique result"); - return (*begin())->getUnderlyingDecl(); - } - - /// Fetches a representative decl. Useful for lazy diagnostics. - NamedDecl *getRepresentativeDecl() const { - assert(!Decls.empty() && "cannot get representative of empty set"); - return *begin(); - } - - /// \brief Asks if the result is a single tag decl. - bool isSingleTagDecl() const { - return getResultKind() == Found && isa<TagDecl>(getFoundDecl()); - } - - /// \brief Make these results show that the name was found in - /// base classes of different types. - /// - /// The given paths object is copied and invalidated. - void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P); - - /// \brief Make these results show that the name was found in - /// distinct base classes of the same type. - /// - /// The given paths object is copied and invalidated. - void setAmbiguousBaseSubobjects(CXXBasePaths &P); - - /// \brief Make these results show that the name was found in - /// different contexts and a tag decl was hidden by an ordinary - /// decl in a different context. - void setAmbiguousQualifiedTagHiding() { - setAmbiguous(AmbiguousTagHiding); - } - - /// \brief Clears out any current state. - void clear() { - ResultKind = NotFound; - Decls.clear(); - if (Paths) deletePaths(Paths); - Paths = nullptr; - NamingClass = nullptr; - Shadowed = false; - } - - /// \brief Clears out any current state and re-initializes for a - /// different kind of lookup. - void clear(Sema::LookupNameKind Kind) { - clear(); - LookupKind = Kind; - configure(); - } - - /// \brief Change this lookup's redeclaration kind. - void setRedeclarationKind(Sema::RedeclarationKind RK) { - Redecl = RK; - configure(); - } - - void print(raw_ostream &); - - /// Suppress the diagnostics that would normally fire because of this - /// lookup. This happens during (e.g.) redeclaration lookups. - void suppressDiagnostics() { - Diagnose = false; - } - - /// Determines whether this lookup is suppressing diagnostics. - bool isSuppressingDiagnostics() const { - return !Diagnose; - } - - /// Sets a 'context' source range. - void setContextRange(SourceRange SR) { - NameContextRange = SR; - } - - /// Gets the source range of the context of this name; for C++ - /// qualified lookups, this is the source range of the scope - /// specifier. - SourceRange getContextRange() const { - return NameContextRange; - } - - /// Gets the location of the identifier. This isn't always defined: - /// sometimes we're doing lookups on synthesized names. - SourceLocation getNameLoc() const { - return NameInfo.getLoc(); - } - - /// \brief Get the Sema object that this lookup result is searching - /// with. - Sema &getSema() const { return *SemaPtr; } - - /// A class for iterating through a result set and possibly - /// filtering out results. The results returned are possibly - /// sugared. - class Filter { - LookupResult &Results; - LookupResult::iterator I; - bool Changed; - bool CalledDone; - - friend class LookupResult; - Filter(LookupResult &Results) - : Results(Results), I(Results.begin()), Changed(false), CalledDone(false) - {} - - public: - Filter(Filter &&F) - : Results(F.Results), I(F.I), Changed(F.Changed), - CalledDone(F.CalledDone) { - F.CalledDone = true; - } - ~Filter() { - assert(CalledDone && - "LookupResult::Filter destroyed without done() call"); - } - - bool hasNext() const { - return I != Results.end(); - } - - NamedDecl *next() { - assert(I != Results.end() && "next() called on empty filter"); - return *I++; - } - - /// Restart the iteration. - void restart() { - I = Results.begin(); - } - - /// Erase the last element returned from this iterator. - void erase() { - Results.Decls.erase(--I); - Changed = true; - } - - /// Replaces the current entry with the given one, preserving the - /// access bits. - void replace(NamedDecl *D) { - Results.Decls.replace(I-1, D); - Changed = true; - } - - /// Replaces the current entry with the given one. - void replace(NamedDecl *D, AccessSpecifier AS) { - Results.Decls.replace(I-1, D, AS); - Changed = true; - } - - void done() { - assert(!CalledDone && "done() called twice"); - CalledDone = true; - - if (Changed) - Results.resolveKindAfterFilter(); - } - }; - - /// Create a filter for this result set. - Filter makeFilter() { - return Filter(*this); - } - - void setFindLocalExtern(bool FindLocalExtern) { - if (FindLocalExtern) - IDNS |= Decl::IDNS_LocalExtern; - else - IDNS &= ~Decl::IDNS_LocalExtern; - } - -private: - void diagnose() { - if (isAmbiguous()) - getSema().DiagnoseAmbiguousLookup(*this); - else if (isClassLookup() && getSema().getLangOpts().AccessControl) - getSema().CheckLookupAccess(*this); - } - - void setAmbiguous(AmbiguityKind AK) { - ResultKind = Ambiguous; - Ambiguity = AK; - } - - void addDeclsFromBasePaths(const CXXBasePaths &P); - void configure(); - - // Sanity checks. - bool sanity() const; - - bool sanityCheckUnresolved() const { - for (iterator I = begin(), E = end(); I != E; ++I) - if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl())) - return true; - return false; - } - - static void deletePaths(CXXBasePaths *); - - // Results. - LookupResultKind ResultKind; - AmbiguityKind Ambiguity; // ill-defined unless ambiguous - UnresolvedSet<8> Decls; - CXXBasePaths *Paths; - CXXRecordDecl *NamingClass; - QualType BaseObjectType; - - // Parameters. - Sema *SemaPtr; - DeclarationNameInfo NameInfo; - SourceRange NameContextRange; - Sema::LookupNameKind LookupKind; - unsigned IDNS; // set by configure() - - bool Redecl; - - /// \brief True if tag declarations should be hidden if non-tags - /// are present - bool HideTags; - - bool Diagnose; - - /// \brief True if we should allow hidden declarations to be 'visible'. - bool AllowHidden; - - /// \brief True if the found declarations were shadowed by some other - /// declaration that we skipped. This only happens when \c LookupKind - /// is \c LookupRedeclarationWithLinkage. - bool Shadowed; -}; - -/// \brief Consumes visible declarations found when searching for -/// all visible names within a given scope or context. -/// -/// This abstract class is meant to be subclassed by clients of \c -/// Sema::LookupVisibleDecls(), each of which should override the \c -/// FoundDecl() function to process declarations as they are found. -class VisibleDeclConsumer { -public: - /// \brief Destroys the visible declaration consumer. - virtual ~VisibleDeclConsumer(); - - /// \brief Determine whether hidden declarations (from unimported - /// modules) should be given to this consumer. By default, they - /// are not included. - virtual bool includeHiddenDecls() const; - - /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a - /// declaration visible from the current scope or context. - /// - /// \param ND the declaration found. - /// - /// \param Hiding a declaration that hides the declaration \p ND, - /// or NULL if no such declaration exists. - /// - /// \param Ctx the original context from which the lookup started. - /// - /// \param InBaseClass whether this declaration was found in base - /// class of the context we searched. - virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, - bool InBaseClass) = 0; -}; - -/// \brief A class for storing results from argument-dependent lookup. -class ADLResult { -private: - /// A map from canonical decls to the 'most recent' decl. - llvm::DenseMap<NamedDecl*, NamedDecl*> Decls; - -public: - /// Adds a new ADL candidate to this map. - void insert(NamedDecl *D); - - /// Removes any data associated with a given decl. - void erase(NamedDecl *D) { - Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); - } - - class iterator - : public llvm::iterator_adaptor_base< - iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator, - std::forward_iterator_tag, NamedDecl *> { - friend class ADLResult; - - iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter) - : iterator_adaptor_base(std::move(Iter)) {} - - public: - iterator() {} - - value_type operator*() const { return I->second; } - }; - - iterator begin() { return iterator(Decls.begin()); } - iterator end() { return iterator(Decls.end()); } -}; - -} - -#endif diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h deleted file mode 100644 index c8b2ee8..0000000 --- a/include/clang/Sema/LoopHint.h +++ /dev/null @@ -1,45 +0,0 @@ -//===--- LoopHint.h - Types for LoopHint ------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_LOOPHINT_H -#define LLVM_CLANG_SEMA_LOOPHINT_H - -#include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Sema/AttributeList.h" -#include "clang/Sema/Ownership.h" - -namespace clang { - -/// \brief Loop optimization hint for loop and unroll pragmas. -struct LoopHint { - // Source range of the directive. - SourceRange Range; - // Identifier corresponding to the name of the pragma. "loop" for - // "#pragma clang loop" directives and "unroll" for "#pragma unroll" - // hints. - IdentifierLoc *PragmaNameLoc; - // Name of the loop hint. Examples: "unroll", "vectorize". In the - // "#pragma unroll" and "#pragma nounroll" cases, this is identical to - // PragmaNameLoc. - IdentifierLoc *OptionLoc; - // Identifier for the hint state argument. If null, then the state is - // default value such as for "#pragma unroll". - IdentifierLoc *StateLoc; - // Expression for the hint argument if it exists, null otherwise. - Expr *ValueExpr; - - LoopHint() - : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr), - ValueExpr(nullptr) {} -}; - -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_LOOPHINT_H diff --git a/include/clang/Sema/Makefile b/include/clang/Sema/Makefile deleted file mode 100644 index 799f789..0000000 --- a/include/clang/Sema/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \ - AttrSpellingListIndex.inc AttrParsedAttrImpl.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/AttrTemplateInstantiate.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute template instantiate code with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-template-instantiate -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrList.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute list with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-list -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrKinds.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute kinds with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-kinds -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute spelling list index with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-spelling-index -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute list impl with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-impl -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h deleted file mode 100644 index d6daadc..0000000 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ /dev/null @@ -1,353 +0,0 @@ -//===--- MultiplexExternalSemaSource.h - External Sema Interface-*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines ExternalSemaSource interface, dispatching to all clients -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H -#define LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H - -#include "clang/Sema/ExternalSemaSource.h" -#include "clang/Sema/Weak.h" -#include "llvm/ADT/SmallVector.h" -#include <utility> - -namespace clang { - - class CXXConstructorDecl; - class CXXRecordDecl; - class DeclaratorDecl; - struct ExternalVTableUse; - class LookupResult; - class NamespaceDecl; - class Scope; - class Sema; - class TypedefNameDecl; - class ValueDecl; - class VarDecl; - - -/// \brief An abstract interface that should be implemented by -/// external AST sources that also provide information for semantic -/// analysis. -class MultiplexExternalSemaSource : public ExternalSemaSource { - -private: - SmallVector<ExternalSemaSource *, 2> Sources; // doesn't own them. - -public: - - ///\brief Constructs a new multiplexing external sema source and appends the - /// given element to it. - /// - ///\param[in] s1 - A non-null (old) ExternalSemaSource. - ///\param[in] s2 - A non-null (new) ExternalSemaSource. - /// - MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2); - - ~MultiplexExternalSemaSource() override; - - ///\brief Appends new source to the source list. - /// - ///\param[in] source - An ExternalSemaSource. - /// - void addSource(ExternalSemaSource &source); - - //===--------------------------------------------------------------------===// - // ExternalASTSource. - //===--------------------------------------------------------------------===// - - /// \brief Resolve a declaration ID into a declaration, potentially - /// building a new declaration. - Decl *GetExternalDecl(uint32_t ID) override; - - /// \brief Complete the redeclaration chain if it's been extended since the - /// previous generation of the AST source. - void CompleteRedeclChain(const Decl *D) override; - - /// \brief Resolve a selector ID into a selector. - Selector GetExternalSelector(uint32_t ID) override; - - /// \brief Returns the number of selectors known to the external AST - /// source. - uint32_t GetNumExternalSelectors() override; - - /// \brief Resolve the offset of a statement in the decl stream into - /// a statement. - Stmt *GetExternalDeclStmt(uint64_t Offset) override; - - /// \brief Resolve the offset of a set of C++ base specifiers in the decl - /// stream into an array of specifiers. - CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; - - /// \brief Resolve a handle to a list of ctor initializers into the list of - /// initializers themselves. - CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; - - /// \brief Find all declarations with the given name in the - /// given context. - bool FindExternalVisibleDeclsByName(const DeclContext *DC, - DeclarationName Name) override; - - /// \brief Ensures that the table of all visible declarations inside this - /// context is up to date. - void completeVisibleDeclsMap(const DeclContext *DC) override; - - /// \brief Finds all declarations lexically contained within the given - /// DeclContext, after applying an optional filter predicate. - /// - /// \param IsKindWeWant a predicate function that returns true if the passed - /// declaration kind is one we are looking for. - void - FindExternalLexicalDecls(const DeclContext *DC, - llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, - SmallVectorImpl<Decl *> &Result) override; - - /// \brief Get the decls that are contained in a file in the Offset/Length - /// range. \p Length can be 0 to indicate a point at \p Offset instead of - /// a range. - void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length, - SmallVectorImpl<Decl *> &Decls) override; - - /// \brief Gives the external AST source an opportunity to complete - /// an incomplete type. - void CompleteType(TagDecl *Tag) override; - - /// \brief Gives the external AST source an opportunity to complete an - /// incomplete Objective-C class. - /// - /// This routine will only be invoked if the "externally completed" bit is - /// set on the ObjCInterfaceDecl via the function - /// \c ObjCInterfaceDecl::setExternallyCompleted(). - void CompleteType(ObjCInterfaceDecl *Class) override; - - /// \brief Loads comment ranges. - void ReadComments() override; - - /// \brief Notify ExternalASTSource that we started deserialization of - /// a decl or type so until FinishedDeserializing is called there may be - /// decls that are initializing. Must be paired with FinishedDeserializing. - void StartedDeserializing() override; - - /// \brief Notify ExternalASTSource that we finished the deserialization of - /// a decl or type. Must be paired with StartedDeserializing. - void FinishedDeserializing() override; - - /// \brief Function that will be invoked when we begin parsing a new - /// translation unit involving this external AST source. - void StartTranslationUnit(ASTConsumer *Consumer) override; - - /// \brief Print any statistics that have been gathered regarding - /// the external AST source. - void PrintStats() override; - - - /// \brief Perform layout on the given record. - /// - /// This routine allows the external AST source to provide an specific - /// layout for a record, overriding the layout that would normally be - /// constructed. It is intended for clients who receive specific layout - /// details rather than source code (such as LLDB). The client is expected - /// to fill in the field offsets, base offsets, virtual base offsets, and - /// complete object size. - /// - /// \param Record The record whose layout is being requested. - /// - /// \param Size The final size of the record, in bits. - /// - /// \param Alignment The final alignment of the record, in bits. - /// - /// \param FieldOffsets The offset of each of the fields within the record, - /// expressed in bits. All of the fields must be provided with offsets. - /// - /// \param BaseOffsets The offset of each of the direct, non-virtual base - /// classes. If any bases are not given offsets, the bases will be laid - /// out according to the ABI. - /// - /// \param VirtualBaseOffsets The offset of each of the virtual base classes - /// (either direct or not). If any bases are not given offsets, the bases will - /// be laid out according to the ABI. - /// - /// \returns true if the record layout was provided, false otherwise. - bool - layoutRecordType(const RecordDecl *Record, - uint64_t &Size, uint64_t &Alignment, - llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets, - llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets, - llvm::DenseMap<const CXXRecordDecl *, - CharUnits> &VirtualBaseOffsets) override; - - /// Return the amount of memory used by memory buffers, breaking down - /// by heap-backed versus mmap'ed memory. - void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override; - - //===--------------------------------------------------------------------===// - // ExternalSemaSource. - //===--------------------------------------------------------------------===// - - /// \brief Initialize the semantic source with the Sema instance - /// being used to perform semantic analysis on the abstract syntax - /// tree. - void InitializeSema(Sema &S) override; - - /// \brief Inform the semantic consumer that Sema is no longer available. - void ForgetSema() override; - - /// \brief Load the contents of the global method pool for a given - /// selector. - void ReadMethodPool(Selector Sel) override; - - /// \brief Load the set of namespaces that are known to the external source, - /// which will be used during typo correction. - void - ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces) override; - - /// \brief Load the set of used but not defined functions or variables with - /// internal linkage, or used but not defined inline functions. - void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override; - - void ReadMismatchingDeleteExpressions(llvm::MapVector< - FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & - Exprs) override; - - /// \brief Do last resort, unqualified lookup on a LookupResult that - /// Sema cannot find. - /// - /// \param R a LookupResult that is being recovered. - /// - /// \param S the Scope of the identifier occurrence. - /// - /// \return true to tell Sema to recover using the LookupResult. - bool LookupUnqualified(LookupResult &R, Scope *S) override; - - /// \brief Read the set of tentative definitions known to the external Sema - /// source. - /// - /// The external source should append its own tentative definitions to the - /// given vector of tentative definitions. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs) override; - - /// \brief Read the set of unused file-scope declarations known to the - /// external Sema source. - /// - /// The external source should append its own unused, filed-scope to the - /// given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - void ReadUnusedFileScopedDecls( - SmallVectorImpl<const DeclaratorDecl*> &Decls) override; - - /// \brief Read the set of delegating constructors known to the - /// external Sema source. - /// - /// The external source should append its own delegating constructors to the - /// given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - void ReadDelegatingConstructors( - SmallVectorImpl<CXXConstructorDecl*> &Decls) override; - - /// \brief Read the set of ext_vector type declarations known to the - /// external Sema source. - /// - /// The external source should append its own ext_vector type declarations to - /// the given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override; - - /// \brief Read the set of potentially unused typedefs known to the source. - /// - /// The external source should append its own potentially unused local - /// typedefs to the given vector of declarations. Note that this routine may - /// be invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - void ReadUnusedLocalTypedefNameCandidates( - llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; - - /// \brief Read the set of referenced selectors known to the - /// external Sema source. - /// - /// The external source should append its own referenced selectors to the - /// given vector of selectors. Note that this routine - /// may be invoked multiple times; the external source should take care not - /// to introduce the same selectors repeatedly. - void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector, - SourceLocation> > &Sels) override; - - /// \brief Read the set of weak, undeclared identifiers known to the - /// external Sema source. - /// - /// The external source should append its own weak, undeclared identifiers to - /// the given vector. Note that this routine may be invoked multiple times; - /// the external source should take care not to introduce the same identifiers - /// repeatedly. - void ReadWeakUndeclaredIdentifiers( - SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override; - - /// \brief Read the set of used vtables known to the external Sema source. - /// - /// The external source should append its own used vtables to the given - /// vector. Note that this routine may be invoked multiple times; the external - /// source should take care not to introduce the same vtables repeatedly. - void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override; - - /// \brief Read the set of pending instantiations known to the external - /// Sema source. - /// - /// The external source should append its own pending instantiations to the - /// given vector. Note that this routine may be invoked multiple times; the - /// external source should take care not to introduce the same instantiations - /// repeatedly. - void ReadPendingInstantiations( - SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override; - - /// \brief Read the set of late parsed template functions for this source. - /// - /// The external source should insert its own late parsed template functions - /// into the map. Note that this routine may be invoked multiple times; the - /// external source should take care not to introduce the same map entries - /// repeatedly. - void ReadLateParsedTemplates( - llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) - override; - - /// \copydoc ExternalSemaSource::CorrectTypo - /// \note Returns the first nonempty correction. - TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, - int LookupKind, Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, - DeclContext *MemberContext, - bool EnteringContext, - const ObjCObjectPointerType *OPT) override; - - /// \brief Produces a diagnostic note if one of the attached sources - /// contains a complete definition for \p T. Queries the sources in list - /// order until the first one claims that a diagnostic was produced. - /// - /// \param Loc the location at which a complete type was required but not - /// provided - /// - /// \param T the \c QualType that should have been complete at \p Loc - /// - /// \return true if a diagnostic was produced, false otherwise. - bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, - QualType T) override; - - // isa/cast/dyn_cast support - static bool classof(const MultiplexExternalSemaSource*) { return true; } - //static bool classof(const ExternalSemaSource*) { return true; } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h deleted file mode 100644 index b618e38..0000000 --- a/include/clang/Sema/ObjCMethodList.h +++ /dev/null @@ -1,58 +0,0 @@ -//===--- ObjCMethodList.h - A singly linked list of methods -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines ObjCMethodList, a singly-linked list of methods. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_OBJCMETHODLIST_H -#define LLVM_CLANG_SEMA_OBJCMETHODLIST_H - -#include "llvm/ADT/PointerIntPair.h" - -namespace clang { - -class ObjCMethodDecl; - -/// \brief a linked list of methods with the same selector name but different -/// signatures. -struct ObjCMethodList { - // NOTE: If you add any members to this struct, make sure to serialize them. - /// \brief If there is more than one decl with this signature. - llvm::PointerIntPair<ObjCMethodDecl *, 1> MethodAndHasMoreThanOneDecl; - /// \brief The next list object and 2 bits for extra info. - llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits; - - ObjCMethodList() { } - ObjCMethodList(ObjCMethodDecl *M) - : MethodAndHasMoreThanOneDecl(M, 0) {} - - ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); } - unsigned getBits() const { return NextAndExtraBits.getInt(); } - void setNext(ObjCMethodList *L) { NextAndExtraBits.setPointer(L); } - void setBits(unsigned B) { NextAndExtraBits.setInt(B); } - - ObjCMethodDecl *getMethod() const { - return MethodAndHasMoreThanOneDecl.getPointer(); - } - void setMethod(ObjCMethodDecl *M) { - return MethodAndHasMoreThanOneDecl.setPointer(M); - } - - bool hasMoreThanOneDecl() const { - return MethodAndHasMoreThanOneDecl.getInt(); - } - void setHasMoreThanOneDecl(bool B) { - return MethodAndHasMoreThanOneDecl.setInt(B); - } -}; - -} - -#endif diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h deleted file mode 100644 index 20958b0..0000000 --- a/include/clang/Sema/Overload.h +++ /dev/null @@ -1,799 +0,0 @@ -//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the data structures and types used in C++ -// overload resolution. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_OVERLOAD_H -#define LLVM_CLANG_SEMA_OVERLOAD_H - -#include "clang/AST/Decl.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/Expr.h" -#include "clang/AST/TemplateBase.h" -#include "clang/AST/Type.h" -#include "clang/AST/UnresolvedSet.h" -#include "clang/Sema/SemaFixItUtils.h" -#include "clang/Sema/TemplateDeduction.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/AlignOf.h" -#include "llvm/Support/Allocator.h" - -namespace clang { - class ASTContext; - class CXXConstructorDecl; - class CXXConversionDecl; - class FunctionDecl; - class Sema; - - /// OverloadingResult - Capture the result of performing overload - /// resolution. - enum OverloadingResult { - OR_Success, ///< Overload resolution succeeded. - OR_No_Viable_Function, ///< No viable function found. - OR_Ambiguous, ///< Ambiguous candidates found. - OR_Deleted ///< Succeeded, but refers to a deleted function. - }; - - enum OverloadCandidateDisplayKind { - /// Requests that all candidates be shown. Viable candidates will - /// be printed first. - OCD_AllCandidates, - - /// Requests that only viable candidates be shown. - OCD_ViableCandidates - }; - - /// ImplicitConversionKind - The kind of implicit conversion used to - /// convert an argument to a parameter's type. The enumerator values - /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that - /// better conversion kinds have smaller values. - enum ImplicitConversionKind { - ICK_Identity = 0, ///< Identity conversion (no conversion) - ICK_Lvalue_To_Rvalue, ///< Lvalue-to-rvalue conversion (C++ 4.1) - ICK_Array_To_Pointer, ///< Array-to-pointer conversion (C++ 4.2) - ICK_Function_To_Pointer, ///< Function-to-pointer (C++ 4.3) - ICK_NoReturn_Adjustment, ///< Removal of noreturn from a type (Clang) - ICK_Qualification, ///< Qualification conversions (C++ 4.4) - ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5) - ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6) - ICK_Complex_Promotion, ///< Complex promotions (Clang extension) - ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7) - ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8) - ICK_Complex_Conversion, ///< Complex conversions (C99 6.3.1.6) - ICK_Floating_Integral, ///< Floating-integral conversions (C++ 4.9) - ICK_Pointer_Conversion, ///< Pointer conversions (C++ 4.10) - ICK_Pointer_Member, ///< Pointer-to-member conversions (C++ 4.11) - ICK_Boolean_Conversion, ///< Boolean conversions (C++ 4.12) - ICK_Compatible_Conversion, ///< Conversions between compatible types in C99 - ICK_Derived_To_Base, ///< Derived-to-base (C++ [over.best.ics]) - ICK_Vector_Conversion, ///< Vector conversions - ICK_Vector_Splat, ///< A vector splat from an arithmetic type - ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7) - ICK_Block_Pointer_Conversion, ///< Block Pointer conversions - ICK_TransparentUnionConversion, ///< Transparent Union Conversions - ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion - ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10) - ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++ - ICK_Num_Conversion_Kinds, ///< The number of conversion kinds - }; - - /// ImplicitConversionRank - The rank of an implicit conversion - /// kind. The enumerator values match with Table 9 of (C++ - /// 13.3.3.1.1) and are listed such that better conversion ranks - /// have smaller values. - enum ImplicitConversionRank { - ICR_Exact_Match = 0, ///< Exact Match - ICR_Promotion, ///< Promotion - ICR_Conversion, ///< Conversion - ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion - ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion - ICR_C_Conversion ///< Conversion only allowed in the C standard. - /// (e.g. void* to char*) - }; - - ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind); - - /// NarrowingKind - The kind of narrowing conversion being performed by a - /// standard conversion sequence according to C++11 [dcl.init.list]p7. - enum NarrowingKind { - /// Not a narrowing conversion. - NK_Not_Narrowing, - - /// A narrowing conversion by virtue of the source and destination types. - NK_Type_Narrowing, - - /// A narrowing conversion, because a constant expression got narrowed. - NK_Constant_Narrowing, - - /// A narrowing conversion, because a non-constant-expression variable might - /// have got narrowed. - NK_Variable_Narrowing - }; - - /// StandardConversionSequence - represents a standard conversion - /// sequence (C++ 13.3.3.1.1). A standard conversion sequence - /// contains between zero and three conversions. If a particular - /// conversion is not needed, it will be set to the identity conversion - /// (ICK_Identity). Note that the three conversions are - /// specified as separate members (rather than in an array) so that - /// we can keep the size of a standard conversion sequence to a - /// single word. - class StandardConversionSequence { - public: - /// First -- The first conversion can be an lvalue-to-rvalue - /// conversion, array-to-pointer conversion, or - /// function-to-pointer conversion. - ImplicitConversionKind First : 8; - - /// Second - The second conversion can be an integral promotion, - /// floating point promotion, integral conversion, floating point - /// conversion, floating-integral conversion, pointer conversion, - /// pointer-to-member conversion, or boolean conversion. - ImplicitConversionKind Second : 8; - - /// Third - The third conversion can be a qualification conversion. - ImplicitConversionKind Third : 8; - - /// \brief Whether this is the deprecated conversion of a - /// string literal to a pointer to non-const character data - /// (C++ 4.2p2). - unsigned DeprecatedStringLiteralToCharPtr : 1; - - /// \brief Whether the qualification conversion involves a change in the - /// Objective-C lifetime (for automatic reference counting). - unsigned QualificationIncludesObjCLifetime : 1; - - /// IncompatibleObjC - Whether this is an Objective-C conversion - /// that we should warn about (if we actually use it). - unsigned IncompatibleObjC : 1; - - /// ReferenceBinding - True when this is a reference binding - /// (C++ [over.ics.ref]). - unsigned ReferenceBinding : 1; - - /// DirectBinding - True when this is a reference binding that is a - /// direct binding (C++ [dcl.init.ref]). - unsigned DirectBinding : 1; - - /// \brief Whether this is an lvalue reference binding (otherwise, it's - /// an rvalue reference binding). - unsigned IsLvalueReference : 1; - - /// \brief Whether we're binding to a function lvalue. - unsigned BindsToFunctionLvalue : 1; - - /// \brief Whether we're binding to an rvalue. - unsigned BindsToRvalue : 1; - - /// \brief Whether this binds an implicit object argument to a - /// non-static member function without a ref-qualifier. - unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1; - - /// \brief Whether this binds a reference to an object with a different - /// Objective-C lifetime qualifier. - unsigned ObjCLifetimeConversionBinding : 1; - - /// FromType - The type that this conversion is converting - /// from. This is an opaque pointer that can be translated into a - /// QualType. - void *FromTypePtr; - - /// ToType - The types that this conversion is converting to in - /// each step. This is an opaque pointer that can be translated - /// into a QualType. - void *ToTypePtrs[3]; - - /// CopyConstructor - The copy constructor that is used to perform - /// this conversion, when the conversion is actually just the - /// initialization of an object via copy constructor. Such - /// conversions are either identity conversions or derived-to-base - /// conversions. - CXXConstructorDecl *CopyConstructor; - - void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } - void setToType(unsigned Idx, QualType T) { - assert(Idx < 3 && "To type index is out of range"); - ToTypePtrs[Idx] = T.getAsOpaquePtr(); - } - void setAllToTypes(QualType T) { - ToTypePtrs[0] = T.getAsOpaquePtr(); - ToTypePtrs[1] = ToTypePtrs[0]; - ToTypePtrs[2] = ToTypePtrs[0]; - } - - QualType getFromType() const { - return QualType::getFromOpaquePtr(FromTypePtr); - } - QualType getToType(unsigned Idx) const { - assert(Idx < 3 && "To type index is out of range"); - return QualType::getFromOpaquePtr(ToTypePtrs[Idx]); - } - - void setAsIdentityConversion(); - - bool isIdentityConversion() const { - return Second == ICK_Identity && Third == ICK_Identity; - } - - ImplicitConversionRank getRank() const; - NarrowingKind getNarrowingKind(ASTContext &Context, const Expr *Converted, - APValue &ConstantValue, - QualType &ConstantType) const; - bool isPointerConversionToBool() const; - bool isPointerConversionToVoidPointer(ASTContext& Context) const; - void dump() const; - }; - - /// UserDefinedConversionSequence - Represents a user-defined - /// conversion sequence (C++ 13.3.3.1.2). - struct UserDefinedConversionSequence { - /// \brief Represents the standard conversion that occurs before - /// the actual user-defined conversion. - /// - /// C++11 13.3.3.1.2p1: - /// If the user-defined conversion is specified by a constructor - /// (12.3.1), the initial standard conversion sequence converts - /// the source type to the type required by the argument of the - /// constructor. If the user-defined conversion is specified by - /// a conversion function (12.3.2), the initial standard - /// conversion sequence converts the source type to the implicit - /// object parameter of the conversion function. - StandardConversionSequence Before; - - /// EllipsisConversion - When this is true, it means user-defined - /// conversion sequence starts with a ... (ellipsis) conversion, instead of - /// a standard conversion. In this case, 'Before' field must be ignored. - // FIXME. I much rather put this as the first field. But there seems to be - // a gcc code gen. bug which causes a crash in a test. Putting it here seems - // to work around the crash. - bool EllipsisConversion : 1; - - /// HadMultipleCandidates - When this is true, it means that the - /// conversion function was resolved from an overloaded set having - /// size greater than 1. - bool HadMultipleCandidates : 1; - - /// After - Represents the standard conversion that occurs after - /// the actual user-defined conversion. - StandardConversionSequence After; - - /// ConversionFunction - The function that will perform the - /// user-defined conversion. Null if the conversion is an - /// aggregate initialization from an initializer list. - FunctionDecl* ConversionFunction; - - /// \brief The declaration that we found via name lookup, which might be - /// the same as \c ConversionFunction or it might be a using declaration - /// that refers to \c ConversionFunction. - DeclAccessPair FoundConversionFunction; - - void dump() const; - }; - - /// Represents an ambiguous user-defined conversion sequence. - struct AmbiguousConversionSequence { - typedef SmallVector<FunctionDecl*, 4> ConversionSet; - - void *FromTypePtr; - void *ToTypePtr; - char Buffer[sizeof(ConversionSet)]; - - QualType getFromType() const { - return QualType::getFromOpaquePtr(FromTypePtr); - } - QualType getToType() const { - return QualType::getFromOpaquePtr(ToTypePtr); - } - void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } - void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); } - - ConversionSet &conversions() { - return *reinterpret_cast<ConversionSet*>(Buffer); - } - - const ConversionSet &conversions() const { - return *reinterpret_cast<const ConversionSet*>(Buffer); - } - - void addConversion(FunctionDecl *D) { - conversions().push_back(D); - } - - typedef ConversionSet::iterator iterator; - iterator begin() { return conversions().begin(); } - iterator end() { return conversions().end(); } - - typedef ConversionSet::const_iterator const_iterator; - const_iterator begin() const { return conversions().begin(); } - const_iterator end() const { return conversions().end(); } - - void construct(); - void destruct(); - void copyFrom(const AmbiguousConversionSequence &); - }; - - /// BadConversionSequence - Records information about an invalid - /// conversion sequence. - struct BadConversionSequence { - enum FailureKind { - no_conversion, - unrelated_class, - bad_qualifiers, - lvalue_ref_to_rvalue, - rvalue_ref_to_lvalue - }; - - // This can be null, e.g. for implicit object arguments. - Expr *FromExpr; - - FailureKind Kind; - - private: - // The type we're converting from (an opaque QualType). - void *FromTy; - - // The type we're converting to (an opaque QualType). - void *ToTy; - - public: - void init(FailureKind K, Expr *From, QualType To) { - init(K, From->getType(), To); - FromExpr = From; - } - void init(FailureKind K, QualType From, QualType To) { - Kind = K; - FromExpr = nullptr; - setFromType(From); - setToType(To); - } - - QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); } - QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); } - - void setFromExpr(Expr *E) { - FromExpr = E; - setFromType(E->getType()); - } - void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); } - void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); } - }; - - /// ImplicitConversionSequence - Represents an implicit conversion - /// sequence, which may be a standard conversion sequence - /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2), - /// or an ellipsis conversion sequence (C++ 13.3.3.1.3). - class ImplicitConversionSequence { - public: - /// Kind - The kind of implicit conversion sequence. BadConversion - /// specifies that there is no conversion from the source type to - /// the target type. AmbiguousConversion represents the unique - /// ambiguous conversion (C++0x [over.best.ics]p10). - enum Kind { - StandardConversion = 0, - UserDefinedConversion, - AmbiguousConversion, - EllipsisConversion, - BadConversion - }; - - private: - enum { - Uninitialized = BadConversion + 1 - }; - - /// ConversionKind - The kind of implicit conversion sequence. - unsigned ConversionKind : 30; - - /// \brief Whether the target is really a std::initializer_list, and the - /// sequence only represents the worst element conversion. - bool StdInitializerListElement : 1; - - void setKind(Kind K) { - destruct(); - ConversionKind = K; - } - - void destruct() { - if (ConversionKind == AmbiguousConversion) Ambiguous.destruct(); - } - - public: - union { - /// When ConversionKind == StandardConversion, provides the - /// details of the standard conversion sequence. - StandardConversionSequence Standard; - - /// When ConversionKind == UserDefinedConversion, provides the - /// details of the user-defined conversion sequence. - UserDefinedConversionSequence UserDefined; - - /// When ConversionKind == AmbiguousConversion, provides the - /// details of the ambiguous conversion. - AmbiguousConversionSequence Ambiguous; - - /// When ConversionKind == BadConversion, provides the details - /// of the bad conversion. - BadConversionSequence Bad; - }; - - ImplicitConversionSequence() - : ConversionKind(Uninitialized), StdInitializerListElement(false) - {} - ~ImplicitConversionSequence() { - destruct(); - } - ImplicitConversionSequence(const ImplicitConversionSequence &Other) - : ConversionKind(Other.ConversionKind), - StdInitializerListElement(Other.StdInitializerListElement) - { - switch (ConversionKind) { - case Uninitialized: break; - case StandardConversion: Standard = Other.Standard; break; - case UserDefinedConversion: UserDefined = Other.UserDefined; break; - case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break; - case EllipsisConversion: break; - case BadConversion: Bad = Other.Bad; break; - } - } - - ImplicitConversionSequence & - operator=(const ImplicitConversionSequence &Other) { - destruct(); - new (this) ImplicitConversionSequence(Other); - return *this; - } - - Kind getKind() const { - assert(isInitialized() && "querying uninitialized conversion"); - return Kind(ConversionKind); - } - - /// \brief Return a ranking of the implicit conversion sequence - /// kind, where smaller ranks represent better conversion - /// sequences. - /// - /// In particular, this routine gives user-defined conversion - /// sequences and ambiguous conversion sequences the same rank, - /// per C++ [over.best.ics]p10. - unsigned getKindRank() const { - switch (getKind()) { - case StandardConversion: - return 0; - - case UserDefinedConversion: - case AmbiguousConversion: - return 1; - - case EllipsisConversion: - return 2; - - case BadConversion: - return 3; - } - - llvm_unreachable("Invalid ImplicitConversionSequence::Kind!"); - } - - bool isBad() const { return getKind() == BadConversion; } - bool isStandard() const { return getKind() == StandardConversion; } - bool isEllipsis() const { return getKind() == EllipsisConversion; } - bool isAmbiguous() const { return getKind() == AmbiguousConversion; } - bool isUserDefined() const { return getKind() == UserDefinedConversion; } - bool isFailure() const { return isBad() || isAmbiguous(); } - - /// Determines whether this conversion sequence has been - /// initialized. Most operations should never need to query - /// uninitialized conversions and should assert as above. - bool isInitialized() const { return ConversionKind != Uninitialized; } - - /// Sets this sequence as a bad conversion for an explicit argument. - void setBad(BadConversionSequence::FailureKind Failure, - Expr *FromExpr, QualType ToType) { - setKind(BadConversion); - Bad.init(Failure, FromExpr, ToType); - } - - /// Sets this sequence as a bad conversion for an implicit argument. - void setBad(BadConversionSequence::FailureKind Failure, - QualType FromType, QualType ToType) { - setKind(BadConversion); - Bad.init(Failure, FromType, ToType); - } - - void setStandard() { setKind(StandardConversion); } - void setEllipsis() { setKind(EllipsisConversion); } - void setUserDefined() { setKind(UserDefinedConversion); } - void setAmbiguous() { - if (ConversionKind == AmbiguousConversion) return; - ConversionKind = AmbiguousConversion; - Ambiguous.construct(); - } - - /// \brief Whether the target is really a std::initializer_list, and the - /// sequence only represents the worst element conversion. - bool isStdInitializerListElement() const { - return StdInitializerListElement; - } - - void setStdInitializerListElement(bool V = true) { - StdInitializerListElement = V; - } - - // The result of a comparison between implicit conversion - // sequences. Use Sema::CompareImplicitConversionSequences to - // actually perform the comparison. - enum CompareKind { - Better = -1, - Indistinguishable = 0, - Worse = 1 - }; - - void DiagnoseAmbiguousConversion(Sema &S, - SourceLocation CaretLoc, - const PartialDiagnostic &PDiag) const; - - void dump() const; - }; - - enum OverloadFailureKind { - ovl_fail_too_many_arguments, - ovl_fail_too_few_arguments, - ovl_fail_bad_conversion, - ovl_fail_bad_deduction, - - /// This conversion candidate was not considered because it - /// duplicates the work of a trivial or derived-to-base - /// conversion. - ovl_fail_trivial_conversion, - - /// This conversion candidate was not considered because it is - /// an illegal instantiation of a constructor temploid: it is - /// callable with one argument, we only have one argument, and - /// its first parameter type is exactly the type of the class. - /// - /// Defining such a constructor directly is illegal, and - /// template-argument deduction is supposed to ignore such - /// instantiations, but we can still get one with the right - /// kind of implicit instantiation. - ovl_fail_illegal_constructor, - - /// This conversion candidate is not viable because its result - /// type is not implicitly convertible to the desired type. - ovl_fail_bad_final_conversion, - - /// This conversion function template specialization candidate is not - /// viable because the final conversion was not an exact match. - ovl_fail_final_conversion_not_exact, - - /// (CUDA) This candidate was not viable because the callee - /// was not accessible from the caller's target (i.e. host->device, - /// global->host, device->host). - ovl_fail_bad_target, - - /// This candidate function was not viable because an enable_if - /// attribute disabled it. - ovl_fail_enable_if - }; - - /// OverloadCandidate - A single candidate in an overload set (C++ 13.3). - struct OverloadCandidate { - /// Function - The actual function that this candidate - /// represents. When NULL, this is a built-in candidate - /// (C++ [over.oper]) or a surrogate for a conversion to a - /// function pointer or reference (C++ [over.call.object]). - FunctionDecl *Function; - - /// FoundDecl - The original declaration that was looked up / - /// invented / otherwise found, together with its access. - /// Might be a UsingShadowDecl or a FunctionTemplateDecl. - DeclAccessPair FoundDecl; - - // BuiltinTypes - Provides the return and parameter types of a - // built-in overload candidate. Only valid when Function is NULL. - struct { - QualType ResultTy; - QualType ParamTypes[3]; - } BuiltinTypes; - - /// Surrogate - The conversion function for which this candidate - /// is a surrogate, but only if IsSurrogate is true. - CXXConversionDecl *Surrogate; - - /// Conversions - The conversion sequences used to convert the - /// function arguments to the function parameters, the pointer points to a - /// fixed size array with NumConversions elements. The memory is owned by - /// the OverloadCandidateSet. - ImplicitConversionSequence *Conversions; - - /// The FixIt hints which can be used to fix the Bad candidate. - ConversionFixItGenerator Fix; - - /// NumConversions - The number of elements in the Conversions array. - unsigned NumConversions; - - /// Viable - True to indicate that this overload candidate is viable. - bool Viable; - - /// IsSurrogate - True to indicate that this candidate is a - /// surrogate for a conversion to a function pointer or reference - /// (C++ [over.call.object]). - bool IsSurrogate; - - /// IgnoreObjectArgument - True to indicate that the first - /// argument's conversion, which for this function represents the - /// implicit object argument, should be ignored. This will be true - /// when the candidate is a static member function (where the - /// implicit object argument is just a placeholder) or a - /// non-static member function when the call doesn't have an - /// object argument. - bool IgnoreObjectArgument; - - /// FailureKind - The reason why this candidate is not viable. - /// Actually an OverloadFailureKind. - unsigned char FailureKind; - - /// \brief The number of call arguments that were explicitly provided, - /// to be used while performing partial ordering of function templates. - unsigned ExplicitCallArguments; - - union { - DeductionFailureInfo DeductionFailure; - - /// FinalConversion - For a conversion function (where Function is - /// a CXXConversionDecl), the standard conversion that occurs - /// after the call to the overload candidate to convert the result - /// of calling the conversion function to the required type. - StandardConversionSequence FinalConversion; - }; - - /// hasAmbiguousConversion - Returns whether this overload - /// candidate requires an ambiguous conversion or not. - bool hasAmbiguousConversion() const { - for (unsigned i = 0, e = NumConversions; i != e; ++i) { - if (!Conversions[i].isInitialized()) return false; - if (Conversions[i].isAmbiguous()) return true; - } - return false; - } - - bool TryToFixBadConversion(unsigned Idx, Sema &S) { - bool CanFix = Fix.tryToFixConversion( - Conversions[Idx].Bad.FromExpr, - Conversions[Idx].Bad.getFromType(), - Conversions[Idx].Bad.getToType(), S); - - // If at least one conversion fails, the candidate cannot be fixed. - if (!CanFix) - Fix.clear(); - - return CanFix; - } - - unsigned getNumParams() const { - if (IsSurrogate) { - auto STy = Surrogate->getConversionType(); - while (STy->isPointerType() || STy->isReferenceType()) - STy = STy->getPointeeType(); - return STy->getAs<FunctionProtoType>()->getNumParams(); - } - if (Function) - return Function->getNumParams(); - return ExplicitCallArguments; - } - }; - - /// OverloadCandidateSet - A set of overload candidates, used in C++ - /// overload resolution (C++ 13.3). - class OverloadCandidateSet { - public: - enum CandidateSetKind { - /// Normal lookup. - CSK_Normal, - /// Lookup for candidates for a call using operator syntax. Candidates - /// that have no parameters of class type will be skipped unless there - /// is a parameter of (reference to) enum type and the corresponding - /// argument is of the same enum type. - CSK_Operator - }; - - private: - SmallVector<OverloadCandidate, 16> Candidates; - llvm::SmallPtrSet<Decl *, 16> Functions; - - // Allocator for OverloadCandidate::Conversions. We store the first few - // elements inline to avoid allocation for small sets. - llvm::BumpPtrAllocator ConversionSequenceAllocator; - - SourceLocation Loc; - CandidateSetKind Kind; - - unsigned NumInlineSequences; - llvm::AlignedCharArray<llvm::AlignOf<ImplicitConversionSequence>::Alignment, - 16 * sizeof(ImplicitConversionSequence)> InlineSpace; - - OverloadCandidateSet(const OverloadCandidateSet &) = delete; - void operator=(const OverloadCandidateSet &) = delete; - - void destroyCandidates(); - - public: - OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK) - : Loc(Loc), Kind(CSK), NumInlineSequences(0) {} - ~OverloadCandidateSet() { destroyCandidates(); } - - SourceLocation getLocation() const { return Loc; } - CandidateSetKind getKind() const { return Kind; } - - /// \brief Determine when this overload candidate will be new to the - /// overload set. - bool isNewCandidate(Decl *F) { - return Functions.insert(F->getCanonicalDecl()).second; - } - - /// \brief Clear out all of the candidates. - void clear(); - - typedef SmallVectorImpl<OverloadCandidate>::iterator iterator; - iterator begin() { return Candidates.begin(); } - iterator end() { return Candidates.end(); } - - size_t size() const { return Candidates.size(); } - bool empty() const { return Candidates.empty(); } - - /// \brief Add a new candidate with NumConversions conversion sequence slots - /// to the overload set. - OverloadCandidate &addCandidate(unsigned NumConversions = 0) { - Candidates.push_back(OverloadCandidate()); - OverloadCandidate &C = Candidates.back(); - - // Assign space from the inline array if there are enough free slots - // available. - if (NumConversions + NumInlineSequences <= 16) { - ImplicitConversionSequence *I = - (ImplicitConversionSequence *)InlineSpace.buffer; - C.Conversions = &I[NumInlineSequences]; - NumInlineSequences += NumConversions; - } else { - // Otherwise get memory from the allocator. - C.Conversions = ConversionSequenceAllocator - .Allocate<ImplicitConversionSequence>(NumConversions); - } - - // Construct the new objects. - for (unsigned i = 0; i != NumConversions; ++i) - new (&C.Conversions[i]) ImplicitConversionSequence(); - - C.NumConversions = NumConversions; - return C; - } - - /// Find the best viable function on this overload set, if it exists. - OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, - OverloadCandidateSet::iterator& Best, - bool UserDefinedConversion = false); - - void NoteCandidates(Sema &S, - OverloadCandidateDisplayKind OCD, - ArrayRef<Expr *> Args, - StringRef Opc = "", - SourceLocation Loc = SourceLocation()); - }; - - bool isBetterOverloadCandidate(Sema &S, - const OverloadCandidate& Cand1, - const OverloadCandidate& Cand2, - SourceLocation Loc, - bool UserDefinedConversion = false); -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_OVERLOAD_H diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h deleted file mode 100644 index 8acf9e8..0000000 --- a/include/clang/Sema/Ownership.h +++ /dev/null @@ -1,287 +0,0 @@ -//===--- Ownership.h - Parser ownership helpers -----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains classes for managing ownership of Stmt and Expr nodes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_OWNERSHIP_H -#define LLVM_CLANG_SEMA_OWNERSHIP_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/PointerIntPair.h" - -//===----------------------------------------------------------------------===// -// OpaquePtr -//===----------------------------------------------------------------------===// - -namespace clang { - class CXXCtorInitializer; - class CXXBaseSpecifier; - class Decl; - class Expr; - class ParsedTemplateArgument; - class QualType; - class Stmt; - class TemplateName; - class TemplateParameterList; - - /// \brief Wrapper for void* pointer. - /// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like - /// a pointer. - /// - /// This is a very simple POD type that wraps a pointer that the Parser - /// doesn't know about but that Sema or another client does. The PtrTy - /// template argument is used to make sure that "Decl" pointers are not - /// compatible with "Type" pointers for example. - template <class PtrTy> - class OpaquePtr { - void *Ptr; - explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} - - typedef llvm::PointerLikeTypeTraits<PtrTy> Traits; - - public: - OpaquePtr() : Ptr(nullptr) {} - - static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } - - /// \brief Returns plain pointer to the entity pointed by this wrapper. - /// \tparam PointeeT Type of pointed entity. - /// - /// It is identical to getPtrAs<PointeeT*>. - template <typename PointeeT> PointeeT* getPtrTo() const { - return get(); - } - - /// \brief Returns pointer converted to the specified type. - /// \tparam PtrT Result pointer type. There must be implicit conversion - /// from PtrTy to PtrT. - /// - /// In contrast to getPtrTo, this method allows the return type to be - /// a smart pointer. - template <typename PtrT> PtrT getPtrAs() const { - return get(); - } - - PtrTy get() const { - return Traits::getFromVoidPointer(Ptr); - } - - void set(PtrTy P) { - Ptr = Traits::getAsVoidPointer(P); - } - - explicit operator bool() const { return Ptr != nullptr; } - - void *getAsOpaquePtr() const { return Ptr; } - static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } - }; - - /// UnionOpaquePtr - A version of OpaquePtr suitable for membership - /// in a union. - template <class T> struct UnionOpaquePtr { - void *Ptr; - - static UnionOpaquePtr make(OpaquePtr<T> P) { - UnionOpaquePtr OP = { P.getAsOpaquePtr() }; - return OP; - } - - OpaquePtr<T> get() const { return OpaquePtr<T>::getFromOpaquePtr(Ptr); } - operator OpaquePtr<T>() const { return get(); } - - UnionOpaquePtr &operator=(OpaquePtr<T> P) { - Ptr = P.getAsOpaquePtr(); - return *this; - } - }; -} - -namespace llvm { - template <class T> - class PointerLikeTypeTraits<clang::OpaquePtr<T> > { - public: - static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) { - // FIXME: Doesn't work? return P.getAs< void >(); - return P.getAsOpaquePtr(); - } - static inline clang::OpaquePtr<T> getFromVoidPointer(void *P) { - return clang::OpaquePtr<T>::getFromOpaquePtr(P); - } - enum { NumLowBitsAvailable = 0 }; - }; - - template <class T> - struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; }; -} - -namespace clang { - // Basic - class DiagnosticBuilder; - - // Determines whether the low bit of the result pointer for the - // given UID is always zero. If so, ActionResult will use that bit - // for it's "invalid" flag. - template<class Ptr> - struct IsResultPtrLowBitFree { - static const bool value = false; - }; - - /// ActionResult - This structure is used while parsing/acting on - /// expressions, stmts, etc. It encapsulates both the object returned by - /// the action, plus a sense of whether or not it is valid. - /// When CompressInvalid is true, the "invalid" flag will be - /// stored in the low bit of the Val pointer. - template<class PtrTy, - bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value> - class ActionResult { - PtrTy Val; - bool Invalid; - - public: - ActionResult(bool Invalid = false) - : Val(PtrTy()), Invalid(Invalid) {} - ActionResult(PtrTy val) : Val(val), Invalid(false) {} - ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {} - - // These two overloads prevent void* -> bool conversions. - ActionResult(const void *); - ActionResult(volatile void *); - - bool isInvalid() const { return Invalid; } - bool isUsable() const { return !Invalid && Val; } - bool isUnset() const { return !Invalid && !Val; } - - PtrTy get() const { return Val; } - template <typename T> T *getAs() { return static_cast<T*>(get()); } - - void set(PtrTy V) { Val = V; } - - const ActionResult &operator=(PtrTy RHS) { - Val = RHS; - Invalid = false; - return *this; - } - }; - - // This ActionResult partial specialization places the "invalid" - // flag into the low bit of the pointer. - template<typename PtrTy> - class ActionResult<PtrTy, true> { - // A pointer whose low bit is 1 if this result is invalid, 0 - // otherwise. - uintptr_t PtrWithInvalid; - typedef llvm::PointerLikeTypeTraits<PtrTy> PtrTraits; - public: - ActionResult(bool Invalid = false) - : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) { } - - ActionResult(PtrTy V) { - void *VP = PtrTraits::getAsVoidPointer(V); - PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); - assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); - } - ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { } - - // These two overloads prevent void* -> bool conversions. - ActionResult(const void *); - ActionResult(volatile void *); - - bool isInvalid() const { return PtrWithInvalid & 0x01; } - bool isUsable() const { return PtrWithInvalid > 0x01; } - bool isUnset() const { return PtrWithInvalid == 0; } - - PtrTy get() const { - void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01); - return PtrTraits::getFromVoidPointer(VP); - } - template <typename T> T *getAs() { return static_cast<T*>(get()); } - - void set(PtrTy V) { - void *VP = PtrTraits::getAsVoidPointer(V); - PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); - assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); - } - - const ActionResult &operator=(PtrTy RHS) { - void *VP = PtrTraits::getAsVoidPointer(RHS); - PtrWithInvalid = reinterpret_cast<uintptr_t>(VP); - assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); - return *this; - } - - // For types where we can fit a flag in with the pointer, provide - // conversions to/from pointer type. - static ActionResult getFromOpaquePointer(void *P) { - ActionResult Result; - Result.PtrWithInvalid = (uintptr_t)P; - return Result; - } - void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; } - }; - - /// An opaque type for threading parsed type information through the - /// parser. - typedef OpaquePtr<QualType> ParsedType; - typedef UnionOpaquePtr<QualType> UnionParsedType; - - // We can re-use the low bit of expression, statement, base, and - // member-initializer pointers for the "invalid" flag of - // ActionResult. - template<> struct IsResultPtrLowBitFree<Expr*> { - static const bool value = true; - }; - template<> struct IsResultPtrLowBitFree<Stmt*> { - static const bool value = true; - }; - template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> { - static const bool value = true; - }; - template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> { - static const bool value = true; - }; - - typedef ActionResult<Expr*> ExprResult; - typedef ActionResult<Stmt*> StmtResult; - typedef ActionResult<ParsedType> TypeResult; - typedef ActionResult<CXXBaseSpecifier*> BaseResult; - typedef ActionResult<CXXCtorInitializer*> MemInitResult; - - typedef ActionResult<Decl*> DeclResult; - typedef OpaquePtr<TemplateName> ParsedTemplateTy; - - typedef MutableArrayRef<Expr*> MultiExprArg; - typedef MutableArrayRef<Stmt*> MultiStmtArg; - typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr; - typedef MutableArrayRef<ParsedType> MultiTypeArg; - typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg; - - inline ExprResult ExprError() { return ExprResult(true); } - inline StmtResult StmtError() { return StmtResult(true); } - - inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); } - inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); } - - inline ExprResult ExprEmpty() { return ExprResult(false); } - inline StmtResult StmtEmpty() { return StmtResult(false); } - - inline Expr *AssertSuccess(ExprResult R) { - assert(!R.isInvalid() && "operation was asserted to never fail!"); - return R.get(); - } - - inline Stmt *AssertSuccess(StmtResult R) { - assert(!R.isInvalid() && "operation was asserted to never fail!"); - return R.get(); - } -} - -#endif diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h deleted file mode 100644 index b36425f..0000000 --- a/include/clang/Sema/ParsedTemplate.h +++ /dev/null @@ -1,214 +0,0 @@ -//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides data structures that store the parsed representation of -// templates. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H -#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H - -#include "clang/Sema/DeclSpec.h" -#include "clang/Sema/Ownership.h" -#include <cassert> - -namespace clang { - /// \brief Represents the parsed form of a C++ template argument. - class ParsedTemplateArgument { - public: - /// \brief Describes the kind of template argument that was parsed. - enum KindType { - /// \brief A template type parameter, stored as a type. - Type, - /// \brief A non-type template parameter, stored as an expression. - NonType, - /// \brief A template template argument, stored as a template name. - Template - }; - - /// \brief Build an empty template argument. - /// - /// This template argument is invalid. - ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { } - - /// \brief Create a template type argument or non-type template argument. - /// - /// \param Arg the template type argument or non-type template argument. - /// \param Loc the location of the type. - ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc) - : Kind(Kind), Arg(Arg), Loc(Loc) { } - - /// \brief Create a template template argument. - /// - /// \param SS the C++ scope specifier that precedes the template name, if - /// any. - /// - /// \param Template the template to which this template template - /// argument refers. - /// - /// \param TemplateLoc the location of the template name. - ParsedTemplateArgument(const CXXScopeSpec &SS, - ParsedTemplateTy Template, - SourceLocation TemplateLoc) - : Kind(ParsedTemplateArgument::Template), - Arg(Template.getAsOpaquePtr()), - SS(SS), Loc(TemplateLoc), EllipsisLoc() { } - - /// \brief Determine whether the given template argument is invalid. - bool isInvalid() const { return Arg == nullptr; } - - /// \brief Determine what kind of template argument we have. - KindType getKind() const { return Kind; } - - /// \brief Retrieve the template type argument's type. - ParsedType getAsType() const { - assert(Kind == Type && "Not a template type argument"); - return ParsedType::getFromOpaquePtr(Arg); - } - - /// \brief Retrieve the non-type template argument's expression. - Expr *getAsExpr() const { - assert(Kind == NonType && "Not a non-type template argument"); - return static_cast<Expr*>(Arg); - } - - /// \brief Retrieve the template template argument's template name. - ParsedTemplateTy getAsTemplate() const { - assert(Kind == Template && "Not a template template argument"); - return ParsedTemplateTy::getFromOpaquePtr(Arg); - } - - /// \brief Retrieve the location of the template argument. - SourceLocation getLocation() const { return Loc; } - - /// \brief Retrieve the nested-name-specifier that precedes the template - /// name in a template template argument. - const CXXScopeSpec &getScopeSpec() const { - assert(Kind == Template && - "Only template template arguments can have a scope specifier"); - return SS; - } - - /// \brief Retrieve the location of the ellipsis that makes a template - /// template argument into a pack expansion. - SourceLocation getEllipsisLoc() const { - assert(Kind == Template && - "Only template template arguments can have an ellipsis"); - return EllipsisLoc; - } - - /// \brief Retrieve a pack expansion of the given template template - /// argument. - /// - /// \param EllipsisLoc The location of the ellipsis. - ParsedTemplateArgument getTemplatePackExpansion( - SourceLocation EllipsisLoc) const; - - private: - KindType Kind; - - /// \brief The actual template argument representation, which may be - /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an - /// expression), or an ActionBase::TemplateTy (for a template). - void *Arg; - - /// \brief The nested-name-specifier that can accompany a template template - /// argument. - CXXScopeSpec SS; - - /// \brief the location of the template argument. - SourceLocation Loc; - - /// \brief The ellipsis location that can accompany a template template - /// argument (turning it into a template template argument expansion). - SourceLocation EllipsisLoc; - }; - - /// \brief Information about a template-id annotation - /// token. - /// - /// A template-id annotation token contains the template declaration, - /// template arguments, whether those template arguments were types, - /// expressions, or template names, and the source locations for important - /// tokens. All of the information about template arguments is allocated - /// directly after this structure. - struct TemplateIdAnnotation { - /// \brief The nested-name-specifier that precedes the template name. - CXXScopeSpec SS; - - /// TemplateKWLoc - The location of the template keyword within the - /// source. - SourceLocation TemplateKWLoc; - - /// TemplateNameLoc - The location of the template name within the - /// source. - SourceLocation TemplateNameLoc; - - /// FIXME: Temporarily stores the name of a specialization - IdentifierInfo *Name; - - /// FIXME: Temporarily stores the overloaded operator kind. - OverloadedOperatorKind Operator; - - /// The declaration of the template corresponding to the - /// template-name. - ParsedTemplateTy Template; - - /// The kind of template that Template refers to. - TemplateNameKind Kind; - - /// The location of the '<' before the template argument - /// list. - SourceLocation LAngleLoc; - - /// The location of the '>' after the template argument - /// list. - SourceLocation RAngleLoc; - - /// NumArgs - The number of template arguments. - unsigned NumArgs; - - /// \brief Retrieves a pointer to the template arguments - ParsedTemplateArgument *getTemplateArgs() { - return reinterpret_cast<ParsedTemplateArgument *>(this + 1); - } - - /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and - /// appends it to List. - static TemplateIdAnnotation * - Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) { - TemplateIdAnnotation *TemplateId - = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + - sizeof(ParsedTemplateArgument) * NumArgs); - TemplateId->NumArgs = NumArgs; - - // Default-construct nested-name-specifier. - new (&TemplateId->SS) CXXScopeSpec(); - - // Default-construct parsed template arguments. - ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs(); - for (unsigned I = 0; I != NumArgs; ++I) - new (TemplateArgs + I) ParsedTemplateArgument(); - - List.push_back(TemplateId); - return TemplateId; - } - - void Destroy() { - SS.~CXXScopeSpec(); - free(this); - } - }; - - /// Retrieves the range of the given template parameter lists. - SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, - unsigned NumParams); -} - -#endif diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h deleted file mode 100644 index ca22e64..0000000 --- a/include/clang/Sema/PrettyDeclStackTrace.h +++ /dev/null @@ -1,47 +0,0 @@ -//===- PrettyDeclStackTrace.h - Stack trace for decl processing -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines an llvm::PrettyStackTraceEntry object for showing -// that a particular declaration was being processed when a crash -// occurred. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H -#define LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H - -#include "clang/Basic/SourceLocation.h" -#include "llvm/Support/PrettyStackTrace.h" - -namespace clang { - -class Decl; -class Sema; -class SourceManager; - -/// PrettyDeclStackTraceEntry - If a crash occurs in the parser while -/// parsing something related to a declaration, include that -/// declaration in the stack trace. -class PrettyDeclStackTraceEntry : public llvm::PrettyStackTraceEntry { - Sema &S; - Decl *TheDecl; - SourceLocation Loc; - const char *Message; - -public: - PrettyDeclStackTraceEntry(Sema &S, Decl *D, SourceLocation Loc, - const char *Msg) - : S(S), TheDecl(D), Loc(Loc), Message(Msg) {} - - void print(raw_ostream &OS) const override; -}; - -} - -#endif diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h deleted file mode 100644 index dfc6f9c..0000000 --- a/include/clang/Sema/Scope.h +++ /dev/null @@ -1,484 +0,0 @@ -//===--- Scope.h - Scope interface ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the Scope interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_SCOPE_H -#define LLVM_CLANG_SEMA_SCOPE_H - -#include "clang/Basic/Diagnostic.h" -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" - -namespace llvm { - -class raw_ostream; - -} - -namespace clang { - -class Decl; -class UsingDirectiveDecl; -class VarDecl; - -/// Scope - A scope is a transient data structure that is used while parsing the -/// program. It assists with resolving identifiers to the appropriate -/// declaration. -/// -class Scope { -public: - /// ScopeFlags - These are bitfields that are or'd together when creating a - /// scope, which defines the sorts of things the scope contains. - enum ScopeFlags { - /// \brief This indicates that the scope corresponds to a function, which - /// means that labels are set here. - FnScope = 0x01, - - /// \brief This is a while, do, switch, for, etc that can have break - /// statements embedded into it. - BreakScope = 0x02, - - /// \brief This is a while, do, for, which can have continue statements - /// embedded into it. - ContinueScope = 0x04, - - /// \brief This is a scope that can contain a declaration. Some scopes - /// just contain loop constructs but don't contain decls. - DeclScope = 0x08, - - /// \brief The controlling scope in a if/switch/while/for statement. - ControlScope = 0x10, - - /// \brief The scope of a struct/union/class definition. - ClassScope = 0x20, - - /// \brief This is a scope that corresponds to a block/closure object. - /// Blocks serve as top-level scopes for some objects like labels, they - /// also prevent things like break and continue. BlockScopes always have - /// the FnScope and DeclScope flags set as well. - BlockScope = 0x40, - - /// \brief This is a scope that corresponds to the - /// template parameters of a C++ template. Template parameter - /// scope starts at the 'template' keyword and ends when the - /// template declaration ends. - TemplateParamScope = 0x80, - - /// \brief This is a scope that corresponds to the - /// parameters within a function prototype. - FunctionPrototypeScope = 0x100, - - /// \brief This is a scope that corresponds to the parameters within - /// a function prototype for a function declaration (as opposed to any - /// other kind of function declarator). Always has FunctionPrototypeScope - /// set as well. - FunctionDeclarationScope = 0x200, - - /// \brief This is a scope that corresponds to the Objective-C - /// \@catch statement. - AtCatchScope = 0x400, - - /// \brief This scope corresponds to an Objective-C method body. - /// It always has FnScope and DeclScope set as well. - ObjCMethodScope = 0x800, - - /// \brief This is a scope that corresponds to a switch statement. - SwitchScope = 0x1000, - - /// \brief This is the scope of a C++ try statement. - TryScope = 0x2000, - - /// \brief This is the scope for a function-level C++ try or catch scope. - FnTryCatchScope = 0x4000, - - /// \brief This is the scope of OpenMP executable directive. - OpenMPDirectiveScope = 0x8000, - - /// \brief This is the scope of some OpenMP loop directive. - OpenMPLoopDirectiveScope = 0x10000, - - /// \brief This is the scope of some OpenMP simd directive. - /// For example, it is used for 'omp simd', 'omp for simd'. - /// This flag is propagated to children scopes. - OpenMPSimdDirectiveScope = 0x20000, - - /// This scope corresponds to an enum. - EnumScope = 0x40000, - - /// This scope corresponds to an SEH try. - SEHTryScope = 0x80000, - - /// This scope corresponds to an SEH except. - SEHExceptScope = 0x100000, - - /// We are currently in the filter expression of an SEH except block. - SEHFilterScope = 0x200000, - }; -private: - /// The parent scope for this scope. This is null for the translation-unit - /// scope. - Scope *AnyParent; - - /// Flags - This contains a set of ScopeFlags, which indicates how the scope - /// interrelates with other control flow statements. - unsigned Flags; - - /// Depth - This is the depth of this scope. The translation-unit scope has - /// depth 0. - unsigned short Depth; - - /// \brief Declarations with static linkage are mangled with the number of - /// scopes seen as a component. - unsigned short MSLastManglingNumber; - - unsigned short MSCurManglingNumber; - - /// PrototypeDepth - This is the number of function prototype scopes - /// enclosing this scope, including this scope. - unsigned short PrototypeDepth; - - /// PrototypeIndex - This is the number of parameters currently - /// declared in this scope. - unsigned short PrototypeIndex; - - /// FnParent - If this scope has a parent scope that is a function body, this - /// pointer is non-null and points to it. This is used for label processing. - Scope *FnParent; - Scope *MSLastManglingParent; - - /// BreakParent/ContinueParent - This is a direct link to the innermost - /// BreakScope/ContinueScope which contains the contents of this scope - /// for control flow purposes (and might be this scope itself), or null - /// if there is no such scope. - Scope *BreakParent, *ContinueParent; - - /// BlockParent - This is a direct link to the immediately containing - /// BlockScope if this scope is not one, or null if there is none. - Scope *BlockParent; - - /// TemplateParamParent - This is a direct link to the - /// immediately containing template parameter scope. In the - /// case of nested templates, template parameter scopes can have - /// other template parameter scopes as parents. - Scope *TemplateParamParent; - - /// DeclsInScope - This keeps track of all declarations in this scope. When - /// the declaration is added to the scope, it is set as the current - /// declaration for the identifier in the IdentifierTable. When the scope is - /// popped, these declarations are removed from the IdentifierTable's notion - /// of current declaration. It is up to the current Action implementation to - /// implement these semantics. - typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy; - DeclSetTy DeclsInScope; - - /// The DeclContext with which this scope is associated. For - /// example, the entity of a class scope is the class itself, the - /// entity of a function scope is a function, etc. - DeclContext *Entity; - - typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy; - UsingDirectivesTy UsingDirectives; - - /// \brief Used to determine if errors occurred in this scope. - DiagnosticErrorTrap ErrorTrap; - - /// A lattice consisting of undefined, a single NRVO candidate variable in - /// this scope, or over-defined. The bit is true when over-defined. - llvm::PointerIntPair<VarDecl *, 1, bool> NRVO; - -public: - Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag) - : ErrorTrap(Diag) { - Init(Parent, ScopeFlags); - } - - /// getFlags - Return the flags for this scope. - /// - unsigned getFlags() const { return Flags; } - void setFlags(unsigned F) { Flags = F; } - - /// isBlockScope - Return true if this scope correspond to a closure. - bool isBlockScope() const { return Flags & BlockScope; } - - /// getParent - Return the scope that this is nested in. - /// - const Scope *getParent() const { return AnyParent; } - Scope *getParent() { return AnyParent; } - - /// getFnParent - Return the closest scope that is a function body. - /// - const Scope *getFnParent() const { return FnParent; } - Scope *getFnParent() { return FnParent; } - - const Scope *getMSLastManglingParent() const { - return MSLastManglingParent; - } - Scope *getMSLastManglingParent() { return MSLastManglingParent; } - - /// getContinueParent - Return the closest scope that a continue statement - /// would be affected by. - Scope *getContinueParent() { - return ContinueParent; - } - - const Scope *getContinueParent() const { - return const_cast<Scope*>(this)->getContinueParent(); - } - - /// getBreakParent - Return the closest scope that a break statement - /// would be affected by. - Scope *getBreakParent() { - return BreakParent; - } - const Scope *getBreakParent() const { - return const_cast<Scope*>(this)->getBreakParent(); - } - - Scope *getBlockParent() { return BlockParent; } - const Scope *getBlockParent() const { return BlockParent; } - - Scope *getTemplateParamParent() { return TemplateParamParent; } - const Scope *getTemplateParamParent() const { return TemplateParamParent; } - - /// Returns the number of function prototype scopes in this scope - /// chain. - unsigned getFunctionPrototypeDepth() const { - return PrototypeDepth; - } - - /// Return the number of parameters declared in this function - /// prototype, increasing it by one for the next call. - unsigned getNextFunctionPrototypeIndex() { - assert(isFunctionPrototypeScope()); - return PrototypeIndex++; - } - - typedef llvm::iterator_range<DeclSetTy::iterator> decl_range; - decl_range decls() const { - return decl_range(DeclsInScope.begin(), DeclsInScope.end()); - } - bool decl_empty() const { return DeclsInScope.empty(); } - - void AddDecl(Decl *D) { - DeclsInScope.insert(D); - } - - void RemoveDecl(Decl *D) { - DeclsInScope.erase(D); - } - - void incrementMSManglingNumber() { - if (Scope *MSLMP = getMSLastManglingParent()) { - MSLMP->MSLastManglingNumber += 1; - MSCurManglingNumber += 1; - } - } - - void decrementMSManglingNumber() { - if (Scope *MSLMP = getMSLastManglingParent()) { - MSLMP->MSLastManglingNumber -= 1; - MSCurManglingNumber -= 1; - } - } - - unsigned getMSLastManglingNumber() const { - if (const Scope *MSLMP = getMSLastManglingParent()) - return MSLMP->MSLastManglingNumber; - return 1; - } - - unsigned getMSCurManglingNumber() const { - return MSCurManglingNumber; - } - - /// isDeclScope - Return true if this is the scope that the specified decl is - /// declared in. - bool isDeclScope(Decl *D) { - return DeclsInScope.count(D) != 0; - } - - DeclContext *getEntity() const { return Entity; } - void setEntity(DeclContext *E) { Entity = E; } - - bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); } - - bool hasUnrecoverableErrorOccurred() const { - return ErrorTrap.hasUnrecoverableErrorOccurred(); - } - - /// isFunctionScope() - Return true if this scope is a function scope. - bool isFunctionScope() const { return (getFlags() & Scope::FnScope); } - - /// isClassScope - Return true if this scope is a class/struct/union scope. - bool isClassScope() const { - return (getFlags() & Scope::ClassScope); - } - - /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline - /// method scope or is inside one. - bool isInCXXInlineMethodScope() const { - if (const Scope *FnS = getFnParent()) { - assert(FnS->getParent() && "TUScope not created?"); - return FnS->getParent()->isClassScope(); - } - return false; - } - - /// isInObjcMethodScope - Return true if this scope is, or is contained in, an - /// Objective-C method body. Note that this method is not constant time. - bool isInObjcMethodScope() const { - for (const Scope *S = this; S; S = S->getParent()) { - // If this scope is an objc method scope, then we succeed. - if (S->getFlags() & ObjCMethodScope) - return true; - } - return false; - } - - /// isInObjcMethodOuterScope - Return true if this scope is an - /// Objective-C method outer most body. - bool isInObjcMethodOuterScope() const { - if (const Scope *S = this) { - // If this scope is an objc method scope, then we succeed. - if (S->getFlags() & ObjCMethodScope) - return true; - } - return false; - } - - - /// isTemplateParamScope - Return true if this scope is a C++ - /// template parameter scope. - bool isTemplateParamScope() const { - return getFlags() & Scope::TemplateParamScope; - } - - /// isFunctionPrototypeScope - Return true if this scope is a - /// function prototype scope. - bool isFunctionPrototypeScope() const { - return getFlags() & Scope::FunctionPrototypeScope; - } - - /// isAtCatchScope - Return true if this scope is \@catch. - bool isAtCatchScope() const { - return getFlags() & Scope::AtCatchScope; - } - - /// isSwitchScope - Return true if this scope is a switch scope. - bool isSwitchScope() const { - for (const Scope *S = this; S; S = S->getParent()) { - if (S->getFlags() & Scope::SwitchScope) - return true; - else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope | - Scope::BlockScope | Scope::TemplateParamScope | - Scope::FunctionPrototypeScope | - Scope::AtCatchScope | Scope::ObjCMethodScope)) - return false; - } - return false; - } - - /// \brief Determines whether this scope is the OpenMP directive scope - bool isOpenMPDirectiveScope() const { - return (getFlags() & Scope::OpenMPDirectiveScope); - } - - /// \brief Determine whether this scope is some OpenMP loop directive scope - /// (for example, 'omp for', 'omp simd'). - bool isOpenMPLoopDirectiveScope() const { - if (getFlags() & Scope::OpenMPLoopDirectiveScope) { - assert(isOpenMPDirectiveScope() && - "OpenMP loop directive scope is not a directive scope"); - return true; - } - return false; - } - - /// \brief Determine whether this scope is (or is nested into) some OpenMP - /// loop simd directive scope (for example, 'omp simd', 'omp for simd'). - bool isOpenMPSimdDirectiveScope() const { - return getFlags() & Scope::OpenMPSimdDirectiveScope; - } - - /// \brief Determine whether this scope is a loop having OpenMP loop - /// directive attached. - bool isOpenMPLoopScope() const { - const Scope *P = getParent(); - return P && P->isOpenMPLoopDirectiveScope(); - } - - /// \brief Determine whether this scope is a C++ 'try' block. - bool isTryScope() const { return getFlags() & Scope::TryScope; } - - /// \brief Determine whether this scope is a SEH '__try' block. - bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; } - - /// \brief Determine whether this scope is a SEH '__except' block. - bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; } - - /// \brief Returns if rhs has a higher scope depth than this. - /// - /// The caller is responsible for calling this only if one of the two scopes - /// is an ancestor of the other. - bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; } - - /// containedInPrototypeScope - Return true if this or a parent scope - /// is a FunctionPrototypeScope. - bool containedInPrototypeScope() const; - - void PushUsingDirective(UsingDirectiveDecl *UDir) { - UsingDirectives.push_back(UDir); - } - - typedef llvm::iterator_range<UsingDirectivesTy::iterator> - using_directives_range; - - using_directives_range using_directives() { - return using_directives_range(UsingDirectives.begin(), - UsingDirectives.end()); - } - - void addNRVOCandidate(VarDecl *VD) { - if (NRVO.getInt()) - return; - if (NRVO.getPointer() == nullptr) { - NRVO.setPointer(VD); - return; - } - if (NRVO.getPointer() != VD) - setNoNRVO(); - } - - void setNoNRVO() { - NRVO.setInt(1); - NRVO.setPointer(nullptr); - } - - void mergeNRVOIntoParent(); - - /// Init - This is used by the parser to implement scope caching. - /// - void Init(Scope *parent, unsigned flags); - - /// \brief Sets up the specified scope flags and adjusts the scope state - /// variables accordingly. - /// - void AddFlags(unsigned Flags); - - void dumpImpl(raw_ostream &OS) const; - void dump() const; -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h deleted file mode 100644 index d13667e..0000000 --- a/include/clang/Sema/ScopeInfo.h +++ /dev/null @@ -1,858 +0,0 @@ -//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines FunctionScopeInfo and its subclasses, which contain -// information about a single function, block, lambda, or method body. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_SCOPEINFO_H -#define LLVM_CLANG_SEMA_SCOPEINFO_H - -#include "clang/AST/Expr.h" -#include "clang/AST/Type.h" -#include "clang/Basic/CapturedStmt.h" -#include "clang/Basic/PartialDiagnostic.h" -#include "clang/Sema/Ownership.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/SmallVector.h" -#include <algorithm> - -namespace clang { - -class Decl; -class BlockDecl; -class CapturedDecl; -class CXXMethodDecl; -class FieldDecl; -class ObjCPropertyDecl; -class IdentifierInfo; -class ImplicitParamDecl; -class LabelDecl; -class ReturnStmt; -class Scope; -class SwitchStmt; -class TemplateTypeParmDecl; -class TemplateParameterList; -class VarDecl; -class ObjCIvarRefExpr; -class ObjCPropertyRefExpr; -class ObjCMessageExpr; - -namespace sema { - -/// \brief Contains information about the compound statement currently being -/// parsed. -class CompoundScopeInfo { -public: - CompoundScopeInfo() - : HasEmptyLoopBodies(false) { } - - /// \brief Whether this compound stamement contains `for' or `while' loops - /// with empty bodies. - bool HasEmptyLoopBodies; - - void setHasEmptyLoopBodies() { - HasEmptyLoopBodies = true; - } -}; - -class PossiblyUnreachableDiag { -public: - PartialDiagnostic PD; - SourceLocation Loc; - const Stmt *stmt; - - PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, - const Stmt *stmt) - : PD(PD), Loc(Loc), stmt(stmt) {} -}; - -/// \brief Retains information about a function, method, or block that is -/// currently being parsed. -class FunctionScopeInfo { -protected: - enum ScopeKind { - SK_Function, - SK_Block, - SK_Lambda, - SK_CapturedRegion - }; - -public: - /// \brief What kind of scope we are describing. - /// - ScopeKind Kind : 3; - - /// \brief Whether this function contains a VLA, \@try, try, C++ - /// initializer, or anything else that can't be jumped past. - bool HasBranchProtectedScope : 1; - - /// \brief Whether this function contains any switches or direct gotos. - bool HasBranchIntoScope : 1; - - /// \brief Whether this function contains any indirect gotos. - bool HasIndirectGoto : 1; - - /// \brief Whether a statement was dropped because it was invalid. - bool HasDroppedStmt : 1; - - /// A flag that is set when parsing a method that must call super's - /// implementation, such as \c -dealloc, \c -finalize, or any method marked - /// with \c __attribute__((objc_requires_super)). - bool ObjCShouldCallSuper : 1; - - /// True when this is a method marked as a designated initializer. - bool ObjCIsDesignatedInit : 1; - /// This starts true for a method marked as designated initializer and will - /// be set to false if there is an invocation to a designated initializer of - /// the super class. - bool ObjCWarnForNoDesignatedInitChain : 1; - - /// True when this is an initializer method not marked as a designated - /// initializer within a class that has at least one initializer marked as a - /// designated initializer. - bool ObjCIsSecondaryInit : 1; - /// This starts true for a secondary initializer method and will be set to - /// false if there is an invocation of an initializer on 'self'. - bool ObjCWarnForNoInitDelegation : 1; - - /// First 'return' statement in the current function. - SourceLocation FirstReturnLoc; - - /// First C++ 'try' statement in the current function. - SourceLocation FirstCXXTryLoc; - - /// First SEH '__try' statement in the current function. - SourceLocation FirstSEHTryLoc; - - /// \brief Used to determine if errors occurred in this function or block. - DiagnosticErrorTrap ErrorTrap; - - /// SwitchStack - This is the current set of active switch statements in the - /// block. - SmallVector<SwitchStmt*, 8> SwitchStack; - - /// \brief The list of return statements that occur within the function or - /// block, if there is any chance of applying the named return value - /// optimization, or if we need to infer a return type. - SmallVector<ReturnStmt*, 4> Returns; - - /// \brief The promise object for this coroutine, if any. - VarDecl *CoroutinePromise; - - /// \brief The list of coroutine control flow constructs (co_await, co_yield, - /// co_return) that occur within the function or block. Empty if and only if - /// this function or block is not (yet known to be) a coroutine. - SmallVector<Stmt*, 4> CoroutineStmts; - - /// \brief The stack of currently active compound stamement scopes in the - /// function. - SmallVector<CompoundScopeInfo, 4> CompoundScopes; - - /// \brief A list of PartialDiagnostics created but delayed within the - /// current function scope. These diagnostics are vetted for reachability - /// prior to being emitted. - SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; - - /// \brief A list of parameters which have the nonnull attribute and are - /// modified in the function. - llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams; - -public: - /// Represents a simple identification of a weak object. - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - /// - /// This is used to determine if two weak accesses refer to the same object. - /// Here are some examples of how various accesses are "profiled": - /// - /// Access Expression | "Base" Decl | "Property" Decl - /// :---------------: | :-----------------: | :------------------------------: - /// self.property | self (VarDecl) | property (ObjCPropertyDecl) - /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) - /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) - /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) - /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) - /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) - /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) - /// weakVar | 0 (known) | weakVar (VarDecl) - /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) - /// - /// Objects are identified with only two Decls to make it reasonably fast to - /// compare them. - class WeakObjectProfileTy { - /// The base object decl, as described in the class documentation. - /// - /// The extra flag is "true" if the Base and Property are enough to uniquely - /// identify the object in memory. - /// - /// \sa isExactProfile() - typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; - BaseInfoTy Base; - - /// The "property" decl, as described in the class documentation. - /// - /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the - /// case of "implicit" properties (regular methods accessed via dot syntax). - const NamedDecl *Property; - - /// Used to find the proper base profile for a given base expression. - static BaseInfoTy getBaseInfo(const Expr *BaseE); - - inline WeakObjectProfileTy(); - static inline WeakObjectProfileTy getSentinel(); - - public: - WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); - WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); - WeakObjectProfileTy(const DeclRefExpr *RE); - WeakObjectProfileTy(const ObjCIvarRefExpr *RE); - - const NamedDecl *getBase() const { return Base.getPointer(); } - const NamedDecl *getProperty() const { return Property; } - - /// Returns true if the object base specifies a known object in memory, - /// rather than, say, an instance variable or property of another object. - /// - /// Note that this ignores the effects of aliasing; that is, \c foo.bar is - /// considered an exact profile if \c foo is a local variable, even if - /// another variable \c foo2 refers to the same object as \c foo. - /// - /// For increased precision, accesses with base variables that are - /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to - /// be exact, though this is not true for arbitrary variables - /// (foo.prop1.prop2). - bool isExactProfile() const { - return Base.getInt(); - } - - bool operator==(const WeakObjectProfileTy &Other) const { - return Base == Other.Base && Property == Other.Property; - } - - // For use in DenseMap. - // We can't specialize the usual llvm::DenseMapInfo at the end of the file - // because by that point the DenseMap in FunctionScopeInfo has already been - // instantiated. - class DenseMapInfo { - public: - static inline WeakObjectProfileTy getEmptyKey() { - return WeakObjectProfileTy(); - } - static inline WeakObjectProfileTy getTombstoneKey() { - return WeakObjectProfileTy::getSentinel(); - } - - static unsigned getHashValue(const WeakObjectProfileTy &Val) { - typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; - return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, - Val.Property)); - } - - static bool isEqual(const WeakObjectProfileTy &LHS, - const WeakObjectProfileTy &RHS) { - return LHS == RHS; - } - }; - }; - - /// Represents a single use of a weak object. - /// - /// Stores both the expression and whether the access is potentially unsafe - /// (i.e. it could potentially be warned about). - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - class WeakUseTy { - llvm::PointerIntPair<const Expr *, 1, bool> Rep; - public: - WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} - - const Expr *getUseExpr() const { return Rep.getPointer(); } - bool isUnsafe() const { return Rep.getInt(); } - void markSafe() { Rep.setInt(false); } - - bool operator==(const WeakUseTy &Other) const { - return Rep == Other.Rep; - } - }; - - /// Used to collect uses of a particular weak object in a function body. - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - typedef SmallVector<WeakUseTy, 4> WeakUseVector; - - /// Used to collect all uses of weak objects in a function body. - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, - WeakObjectProfileTy::DenseMapInfo> - WeakObjectUseMap; - -private: - /// Used to collect all uses of weak objects in this function body. - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - WeakObjectUseMap WeakObjectUses; - -protected: - FunctionScopeInfo(const FunctionScopeInfo&) = default; - -public: - /// Record that a weak object was accessed. - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - template <typename ExprT> - inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); - - void recordUseOfWeak(const ObjCMessageExpr *Msg, - const ObjCPropertyDecl *Prop); - - /// Record that a given expression is a "safe" access of a weak object (e.g. - /// assigning it to a strong variable.) - /// - /// Part of the implementation of -Wrepeated-use-of-weak. - void markSafeWeakUse(const Expr *E); - - const WeakObjectUseMap &getWeakObjectUses() const { - return WeakObjectUses; - } - - void setHasBranchIntoScope() { - HasBranchIntoScope = true; - } - - void setHasBranchProtectedScope() { - HasBranchProtectedScope = true; - } - - void setHasIndirectGoto() { - HasIndirectGoto = true; - } - - void setHasDroppedStmt() { - HasDroppedStmt = true; - } - - void setHasCXXTry(SourceLocation TryLoc) { - setHasBranchProtectedScope(); - FirstCXXTryLoc = TryLoc; - } - - void setHasSEHTry(SourceLocation TryLoc) { - setHasBranchProtectedScope(); - FirstSEHTryLoc = TryLoc; - } - - bool NeedsScopeChecking() const { - return !HasDroppedStmt && - (HasIndirectGoto || - (HasBranchProtectedScope && HasBranchIntoScope)); - } - - FunctionScopeInfo(DiagnosticsEngine &Diag) - : Kind(SK_Function), - HasBranchProtectedScope(false), - HasBranchIntoScope(false), - HasIndirectGoto(false), - HasDroppedStmt(false), - ObjCShouldCallSuper(false), - ObjCIsDesignatedInit(false), - ObjCWarnForNoDesignatedInitChain(false), - ObjCIsSecondaryInit(false), - ObjCWarnForNoInitDelegation(false), - ErrorTrap(Diag) { } - - virtual ~FunctionScopeInfo(); - - /// \brief Clear out the information in this function scope, making it - /// suitable for reuse. - void Clear(); -}; - -class CapturingScopeInfo : public FunctionScopeInfo { -protected: - CapturingScopeInfo(const CapturingScopeInfo&) = default; - -public: - enum ImplicitCaptureStyle { - ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, - ImpCap_CapturedRegion - }; - - ImplicitCaptureStyle ImpCaptureStyle; - - class Capture { - // There are three categories of capture: capturing 'this', capturing - // local variables, and C++1y initialized captures (which can have an - // arbitrary initializer, and don't really capture in the traditional - // sense at all). - // - // There are three ways to capture a local variable: - // - capture by copy in the C++11 sense, - // - capture by reference in the C++11 sense, and - // - __block capture. - // Lambdas explicitly specify capture by copy or capture by reference. - // For blocks, __block capture applies to variables with that annotation, - // variables of reference type are captured by reference, and other - // variables are captured by copy. - enum CaptureKind { - Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This - }; - - /// The variable being captured (if we are not capturing 'this') and whether - /// this is a nested capture. - llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested; - - /// Expression to initialize a field of the given type, and the kind of - /// capture (if this is a capture and not an init-capture). The expression - /// is only required if we are capturing ByVal and the variable's type has - /// a non-trivial copy constructor. - llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind; - - /// \brief The source location at which the first capture occurred. - SourceLocation Loc; - - /// \brief The location of the ellipsis that expands a parameter pack. - SourceLocation EllipsisLoc; - - /// \brief The type as it was captured, which is in effect the type of the - /// non-static data member that would hold the capture. - QualType CaptureType; - - public: - Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, - SourceLocation Loc, SourceLocation EllipsisLoc, - QualType CaptureType, Expr *Cpy) - : VarAndNested(Var, IsNested), - InitExprAndCaptureKind(Cpy, Block ? Cap_Block : - ByRef ? Cap_ByRef : Cap_ByCopy), - Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} - - enum IsThisCapture { ThisCapture }; - Capture(IsThisCapture, bool IsNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy) - : VarAndNested(nullptr, IsNested), - InitExprAndCaptureKind(Cpy, Cap_This), - Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} - - bool isThisCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_This; - } - bool isVariableCapture() const { - return InitExprAndCaptureKind.getInt() != Cap_This && !isVLATypeCapture(); - } - bool isCopyCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy && - !isVLATypeCapture(); - } - bool isReferenceCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByRef; - } - bool isBlockCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_Block; - } - bool isVLATypeCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy && - getVariable() == nullptr; - } - bool isNested() const { return VarAndNested.getInt(); } - - VarDecl *getVariable() const { - return VarAndNested.getPointer(); - } - - /// \brief Retrieve the location at which this variable was captured. - SourceLocation getLocation() const { return Loc; } - - /// \brief Retrieve the source location of the ellipsis, whose presence - /// indicates that the capture is a pack expansion. - SourceLocation getEllipsisLoc() const { return EllipsisLoc; } - - /// \brief Retrieve the capture type for this capture, which is effectively - /// the type of the non-static data member in the lambda/block structure - /// that would store this capture. - QualType getCaptureType() const { return CaptureType; } - - Expr *getInitExpr() const { - assert(!isVLATypeCapture() && "no init expression for type capture"); - return static_cast<Expr *>(InitExprAndCaptureKind.getPointer()); - } - }; - - CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) - : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), - HasImplicitReturnType(false) - {} - - /// CaptureMap - A map of captured variables to (index+1) into Captures. - llvm::DenseMap<VarDecl*, unsigned> CaptureMap; - - /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; - /// zero if 'this' is not captured. - unsigned CXXThisCaptureIndex; - - /// Captures - The captures. - SmallVector<Capture, 4> Captures; - - /// \brief - Whether the target type of return statements in this context - /// is deduced (e.g. a lambda or block with omitted return type). - bool HasImplicitReturnType; - - /// ReturnType - The target type of return statements in this context, - /// or null if unknown. - QualType ReturnType; - - void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, - SourceLocation Loc, SourceLocation EllipsisLoc, - QualType CaptureType, Expr *Cpy) { - Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, - EllipsisLoc, CaptureType, Cpy)); - CaptureMap[Var] = Captures.size(); - } - - void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) { - Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false, - /*isByref*/ false, /*isNested*/ false, Loc, - /*EllipsisLoc*/ SourceLocation(), CaptureType, - /*Cpy*/ nullptr)); - } - - void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, - Expr *Cpy); - - /// \brief Determine whether the C++ 'this' is captured. - bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } - - /// \brief Retrieve the capture of C++ 'this', if it has been captured. - Capture &getCXXThisCapture() { - assert(isCXXThisCaptured() && "this has not been captured"); - return Captures[CXXThisCaptureIndex - 1]; - } - - /// \brief Determine whether the given variable has been captured. - bool isCaptured(VarDecl *Var) const { - return CaptureMap.count(Var); - } - - /// \brief Determine whether the given variable-array type has been captured. - bool isVLATypeCaptured(const VariableArrayType *VAT) const; - - /// \brief Retrieve the capture of the given variable, if it has been - /// captured already. - Capture &getCapture(VarDecl *Var) { - assert(isCaptured(Var) && "Variable has not been captured"); - return Captures[CaptureMap[Var] - 1]; - } - - const Capture &getCapture(VarDecl *Var) const { - llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known - = CaptureMap.find(Var); - assert(Known != CaptureMap.end() && "Variable has not been captured"); - return Captures[Known->second - 1]; - } - - static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda - || FSI->Kind == SK_CapturedRegion; - } -}; - -/// \brief Retains information about a block that is currently being parsed. -class BlockScopeInfo final : public CapturingScopeInfo { -public: - BlockDecl *TheDecl; - - /// TheScope - This is the scope for the block itself, which contains - /// arguments etc. - Scope *TheScope; - - /// BlockType - The function type of the block, if one was given. - /// Its return type may be BuiltinType::Dependent. - QualType FunctionType; - - BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) - : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), - TheScope(BlockScope) - { - Kind = SK_Block; - } - - ~BlockScopeInfo() override; - - static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_Block; - } -}; - -/// \brief Retains information about a captured region. -class CapturedRegionScopeInfo final : public CapturingScopeInfo { -public: - /// \brief The CapturedDecl for this statement. - CapturedDecl *TheCapturedDecl; - /// \brief The captured record type. - RecordDecl *TheRecordDecl; - /// \brief This is the enclosing scope of the captured region. - Scope *TheScope; - /// \brief The implicit parameter for the captured variables. - ImplicitParamDecl *ContextParam; - /// \brief The kind of captured region. - CapturedRegionKind CapRegionKind; - - CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, - RecordDecl *RD, ImplicitParamDecl *Context, - CapturedRegionKind K) - : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), - TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), - ContextParam(Context), CapRegionKind(K) - { - Kind = SK_CapturedRegion; - } - - ~CapturedRegionScopeInfo() override; - - /// \brief A descriptive name for the kind of captured region this is. - StringRef getRegionName() const { - switch (CapRegionKind) { - case CR_Default: - return "default captured statement"; - case CR_OpenMP: - return "OpenMP region"; - } - llvm_unreachable("Invalid captured region kind!"); - } - - static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_CapturedRegion; - } -}; - -class LambdaScopeInfo final : public CapturingScopeInfo { -public: - /// \brief The class that describes the lambda. - CXXRecordDecl *Lambda; - - /// \brief The lambda's compiler-generated \c operator(). - CXXMethodDecl *CallOperator; - - /// \brief Source range covering the lambda introducer [...]. - SourceRange IntroducerRange; - - /// \brief Source location of the '&' or '=' specifying the default capture - /// type, if any. - SourceLocation CaptureDefaultLoc; - - /// \brief The number of captures in the \c Captures list that are - /// explicit captures. - unsigned NumExplicitCaptures; - - /// \brief Whether this is a mutable lambda. - bool Mutable; - - /// \brief Whether the (empty) parameter list is explicit. - bool ExplicitParams; - - /// \brief Whether any of the capture expressions requires cleanups. - bool ExprNeedsCleanups; - - /// \brief Whether the lambda contains an unexpanded parameter pack. - bool ContainsUnexpandedParameterPack; - - /// \brief If this is a generic lambda, use this as the depth of - /// each 'auto' parameter, during initial AST construction. - unsigned AutoTemplateParameterDepth; - - /// \brief Store the list of the auto parameters for a generic lambda. - /// If this is a generic lambda, store the list of the auto - /// parameters converted into TemplateTypeParmDecls into a vector - /// that can be used to construct the generic lambda's template - /// parameter list, during initial AST construction. - SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams; - - /// If this is a generic lambda, and the template parameter - /// list has been created (from the AutoTemplateParams) then - /// store a reference to it (cache it to avoid reconstructing it). - TemplateParameterList *GLTemplateParameterList; - - /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs - /// or MemberExprs) that refer to local variables in a generic lambda - /// or a lambda in a potentially-evaluated-if-used context. - /// - /// Potentially capturable variables of a nested lambda that might need - /// to be captured by the lambda are housed here. - /// This is specifically useful for generic lambdas or - /// lambdas within a a potentially evaluated-if-used context. - /// If an enclosing variable is named in an expression of a lambda nested - /// within a generic lambda, we don't always know know whether the variable - /// will truly be odr-used (i.e. need to be captured) by that nested lambda, - /// until its instantiation. But we still need to capture it in the - /// enclosing lambda if all intervening lambdas can capture the variable. - - llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs; - - /// \brief Contains all variable-referring-expressions that refer - /// to local variables that are usable as constant expressions and - /// do not involve an odr-use (they may still need to be captured - /// if the enclosing full-expression is instantiation dependent). - llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs; - - SourceLocation PotentialThisCaptureLocation; - - LambdaScopeInfo(DiagnosticsEngine &Diag) - : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr), - CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false), - ExplicitParams(false), ExprNeedsCleanups(false), - ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0), - GLTemplateParameterList(nullptr) { - Kind = SK_Lambda; - } - - /// \brief Note when all explicit captures have been added. - void finishedExplicitCaptures() { - NumExplicitCaptures = Captures.size(); - } - - static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_Lambda; - } - - /// - /// \brief Add a variable that might potentially be captured by the - /// lambda and therefore the enclosing lambdas. - /// - /// This is also used by enclosing lambda's to speculatively capture - /// variables that nested lambda's - depending on their enclosing - /// specialization - might need to capture. - /// Consider: - /// void f(int, int); <-- don't capture - /// void f(const int&, double); <-- capture - /// void foo() { - /// const int x = 10; - /// auto L = [=](auto a) { // capture 'x' - /// return [=](auto b) { - /// f(x, a); // we may or may not need to capture 'x' - /// }; - /// }; - /// } - void addPotentialCapture(Expr *VarExpr) { - assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr)); - PotentiallyCapturingExprs.push_back(VarExpr); - } - - void addPotentialThisCapture(SourceLocation Loc) { - PotentialThisCaptureLocation = Loc; - } - bool hasPotentialThisCapture() const { - return PotentialThisCaptureLocation.isValid(); - } - - /// \brief Mark a variable's reference in a lambda as non-odr using. - /// - /// For generic lambdas, if a variable is named in a potentially evaluated - /// expression, where the enclosing full expression is dependent then we - /// must capture the variable (given a default capture). - /// This is accomplished by recording all references to variables - /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of - /// PotentialCaptures. All such variables have to be captured by that lambda, - /// except for as described below. - /// If that variable is usable as a constant expression and is named in a - /// manner that does not involve its odr-use (e.g. undergoes - /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the - /// act of analyzing the enclosing full expression (ActOnFinishFullExpr) - /// if we can determine that the full expression is not instantiation- - /// dependent, then we can entirely avoid its capture. - /// - /// const int n = 0; - /// [&] (auto x) { - /// (void)+n + x; - /// }; - /// Interestingly, this strategy would involve a capture of n, even though - /// it's obviously not odr-used here, because the full-expression is - /// instantiation-dependent. It could be useful to avoid capturing such - /// variables, even when they are referred to in an instantiation-dependent - /// expression, if we can unambiguously determine that they shall never be - /// odr-used. This would involve removal of the variable-referring-expression - /// from the array of PotentialCaptures during the lvalue-to-rvalue - /// conversions. But per the working draft N3797, (post-chicago 2013) we must - /// capture such variables. - /// Before anyone is tempted to implement a strategy for not-capturing 'n', - /// consider the insightful warning in: - /// /cfe-commits/Week-of-Mon-20131104/092596.html - /// "The problem is that the set of captures for a lambda is part of the ABI - /// (since lambda layout can be made visible through inline functions and the - /// like), and there are no guarantees as to which cases we'll manage to build - /// an lvalue-to-rvalue conversion in, when parsing a template -- some - /// seemingly harmless change elsewhere in Sema could cause us to start or stop - /// building such a node. So we need a rule that anyone can implement and get - /// exactly the same result". - /// - void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) { - assert(isa<DeclRefExpr>(CapturingVarExpr) - || isa<MemberExpr>(CapturingVarExpr)); - NonODRUsedCapturingExprs.insert(CapturingVarExpr); - } - bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const { - assert(isa<DeclRefExpr>(CapturingVarExpr) - || isa<MemberExpr>(CapturingVarExpr)); - return NonODRUsedCapturingExprs.count(CapturingVarExpr); - } - void removePotentialCapture(Expr *E) { - PotentiallyCapturingExprs.erase( - std::remove(PotentiallyCapturingExprs.begin(), - PotentiallyCapturingExprs.end(), E), - PotentiallyCapturingExprs.end()); - } - void clearPotentialCaptures() { - PotentiallyCapturingExprs.clear(); - PotentialThisCaptureLocation = SourceLocation(); - } - unsigned getNumPotentialVariableCaptures() const { - return PotentiallyCapturingExprs.size(); - } - - bool hasPotentialCaptures() const { - return getNumPotentialVariableCaptures() || - PotentialThisCaptureLocation.isValid(); - } - - // When passed the index, returns the VarDecl and Expr associated - // with the index. - void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const; -}; - -FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() - : Base(nullptr, false), Property(nullptr) {} - -FunctionScopeInfo::WeakObjectProfileTy -FunctionScopeInfo::WeakObjectProfileTy::getSentinel() { - FunctionScopeInfo::WeakObjectProfileTy Result; - Result.Base.setInt(true); - return Result; -} - -template <typename ExprT> -void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { - assert(E); - WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; - Uses.push_back(WeakUseTy(E, IsRead)); -} - -inline void -CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy) { - Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, - Cpy)); - CXXThisCaptureIndex = Captures.size(); -} - -} // end namespace sema -} // end namespace clang - -#endif diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h deleted file mode 100644 index 77d06f2..0000000 --- a/include/clang/Sema/Sema.h +++ /dev/null @@ -1,9265 +0,0 @@ -//===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the Sema class, which performs semantic analysis and -// builds ASTs. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_SEMA_H -#define LLVM_CLANG_SEMA_SEMA_H - -#include "clang/AST/Attr.h" -#include "clang/AST/DeclarationName.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/ExternalASTSource.h" -#include "clang/AST/MangleNumberingContext.h" -#include "clang/AST/NSAPI.h" -#include "clang/AST/PrettyPrinter.h" -#include "clang/AST/TypeLoc.h" -#include "clang/Basic/ExpressionTraits.h" -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/Module.h" -#include "clang/Basic/OpenMPKinds.h" -#include "clang/Basic/Specifiers.h" -#include "clang/Basic/TemplateKinds.h" -#include "clang/Basic/TypeTraits.h" -#include "clang/Sema/AnalysisBasedWarnings.h" -#include "clang/Sema/DeclSpec.h" -#include "clang/Sema/ExternalSemaSource.h" -#include "clang/Sema/IdentifierResolver.h" -#include "clang/Sema/LocInfoType.h" -#include "clang/Sema/ObjCMethodList.h" -#include "clang/Sema/Ownership.h" -#include "clang/Sema/Scope.h" -#include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/TypoCorrection.h" -#include "clang/Sema/Weak.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/TinyPtrVector.h" -#include <deque> -#include <memory> -#include <string> -#include <vector> - -namespace llvm { - class APSInt; - template <typename ValueT> struct DenseMapInfo; - template <typename ValueT, typename ValueInfoT> class DenseSet; - class SmallBitVector; - class InlineAsmIdentifierInfo; -} - -namespace clang { - class ADLResult; - class ASTConsumer; - class ASTContext; - class ASTMutationListener; - class ASTReader; - class ASTWriter; - class ArrayType; - class AttributeList; - class BlockDecl; - class CapturedDecl; - class CXXBasePath; - class CXXBasePaths; - class CXXBindTemporaryExpr; - typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; - class CXXConstructorDecl; - class CXXConversionDecl; - class CXXDeleteExpr; - class CXXDestructorDecl; - class CXXFieldCollector; - class CXXMemberCallExpr; - class CXXMethodDecl; - class CXXScopeSpec; - class CXXTemporary; - class CXXTryStmt; - class CallExpr; - class ClassTemplateDecl; - class ClassTemplatePartialSpecializationDecl; - class ClassTemplateSpecializationDecl; - class VarTemplatePartialSpecializationDecl; - class CodeCompleteConsumer; - class CodeCompletionAllocator; - class CodeCompletionTUInfo; - class CodeCompletionResult; - class Decl; - class DeclAccessPair; - class DeclContext; - class DeclRefExpr; - class DeclaratorDecl; - class DeducedTemplateArgument; - class DependentDiagnostic; - class DesignatedInitExpr; - class Designation; - class EnableIfAttr; - class EnumConstantDecl; - class Expr; - class ExtVectorType; - class ExternalSemaSource; - class FormatAttr; - class FriendDecl; - class FunctionDecl; - class FunctionProtoType; - class FunctionTemplateDecl; - class ImplicitConversionSequence; - class InitListExpr; - class InitializationKind; - class InitializationSequence; - class InitializedEntity; - class IntegerLiteral; - class LabelStmt; - class LambdaExpr; - class LangOptions; - class LocalInstantiationScope; - class LookupResult; - class MacroInfo; - typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath; - class ModuleLoader; - class MultiLevelTemplateArgumentList; - class NamedDecl; - class ObjCCategoryDecl; - class ObjCCategoryImplDecl; - class ObjCCompatibleAliasDecl; - class ObjCContainerDecl; - class ObjCImplDecl; - class ObjCImplementationDecl; - class ObjCInterfaceDecl; - class ObjCIvarDecl; - template <class T> class ObjCList; - class ObjCMessageExpr; - class ObjCMethodDecl; - class ObjCPropertyDecl; - class ObjCProtocolDecl; - class OMPThreadPrivateDecl; - class OMPClause; - struct OverloadCandidate; - class OverloadCandidateSet; - class OverloadExpr; - class ParenListExpr; - class ParmVarDecl; - class Preprocessor; - class PseudoDestructorTypeStorage; - class PseudoObjectExpr; - class QualType; - class StandardConversionSequence; - class Stmt; - class StringLiteral; - class SwitchStmt; - class TemplateArgument; - class TemplateArgumentList; - class TemplateArgumentLoc; - class TemplateDecl; - class TemplateParameterList; - class TemplatePartialOrderingContext; - class TemplateTemplateParmDecl; - class Token; - class TypeAliasDecl; - class TypedefDecl; - class TypedefNameDecl; - class TypeLoc; - class TypoCorrectionConsumer; - class UnqualifiedId; - class UnresolvedLookupExpr; - class UnresolvedMemberExpr; - class UnresolvedSetImpl; - class UnresolvedSetIterator; - class UsingDecl; - class UsingShadowDecl; - class ValueDecl; - class VarDecl; - class VarTemplateSpecializationDecl; - class VisibilityAttr; - class VisibleDeclConsumer; - class IndirectFieldDecl; - struct DeductionFailureInfo; - class TemplateSpecCandidateSet; - -namespace sema { - class AccessedEntity; - class BlockScopeInfo; - class CapturedRegionScopeInfo; - class CapturingScopeInfo; - class CompoundScopeInfo; - class DelayedDiagnostic; - class DelayedDiagnosticPool; - class FunctionScopeInfo; - class LambdaScopeInfo; - class PossiblyUnreachableDiag; - class TemplateDeductionInfo; -} - -namespace threadSafety { - class BeforeSet; - void threadSafetyCleanup(BeforeSet* Cache); -} - -// FIXME: No way to easily map from TemplateTypeParmTypes to -// TemplateTypeParmDecls, so we have this horrible PointerUnion. -typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, - SourceLocation> UnexpandedParameterPack; - -/// Describes whether we've seen any nullability information for the given -/// file. -struct FileNullability { - /// The first pointer declarator (of any pointer kind) in the file that does - /// not have a corresponding nullability annotation. - SourceLocation PointerLoc; - - /// Which kind of pointer declarator we saw. - uint8_t PointerKind; - - /// Whether we saw any type nullability annotations in the given file. - bool SawTypeNullability = false; -}; - -/// A mapping from file IDs to a record of whether we've seen nullability -/// information in that file. -class FileNullabilityMap { - /// A mapping from file IDs to the nullability information for each file ID. - llvm::DenseMap<FileID, FileNullability> Map; - - /// A single-element cache based on the file ID. - struct { - FileID File; - FileNullability Nullability; - } Cache; - -public: - FileNullability &operator[](FileID file) { - // Check the single-element cache. - if (file == Cache.File) - return Cache.Nullability; - - // It's not in the single-element cache; flush the cache if we have one. - if (!Cache.File.isInvalid()) { - Map[Cache.File] = Cache.Nullability; - } - - // Pull this entry into the cache. - Cache.File = file; - Cache.Nullability = Map[file]; - return Cache.Nullability; - } -}; - -/// Sema - This implements semantic analysis and AST building for C. -class Sema { - Sema(const Sema &) = delete; - void operator=(const Sema &) = delete; - - ///\brief Source of additional semantic information. - ExternalSemaSource *ExternalSource; - - ///\brief Whether Sema has generated a multiplexer and has to delete it. - bool isMultiplexExternalSource; - - static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); - - bool isVisibleSlow(const NamedDecl *D); - - bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, - const NamedDecl *New) { - // We are about to link these. It is now safe to compute the linkage of - // the new decl. If the new decl has external linkage, we will - // link it with the hidden decl (which also has external linkage) and - // it will keep having external linkage. If it has internal linkage, we - // will not link it. Since it has no previous decls, it will remain - // with internal linkage. - return isVisible(Old) || New->isExternallyVisible(); - } - bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New); - -public: - typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; - typedef OpaquePtr<TemplateName> TemplateTy; - typedef OpaquePtr<QualType> TypeTy; - - OpenCLOptions OpenCLFeatures; - FPOptions FPFeatures; - - const LangOptions &LangOpts; - Preprocessor &PP; - ASTContext &Context; - ASTConsumer &Consumer; - DiagnosticsEngine &Diags; - SourceManager &SourceMgr; - - /// \brief Flag indicating whether or not to collect detailed statistics. - bool CollectStats; - - /// \brief Code-completion consumer. - CodeCompleteConsumer *CodeCompleter; - - /// CurContext - This is the current declaration context of parsing. - DeclContext *CurContext; - - /// \brief Generally null except when we temporarily switch decl contexts, - /// like in \see ActOnObjCTemporaryExitContainerContext. - DeclContext *OriginalLexicalContext; - - /// VAListTagName - The declaration name corresponding to __va_list_tag. - /// This is used as part of a hack to omit that class from ADL results. - DeclarationName VAListTagName; - - /// PackContext - Manages the stack for \#pragma pack. An alignment - /// of 0 indicates default alignment. - void *PackContext; // Really a "PragmaPackStack*" - - bool MSStructPragmaOn; // True when \#pragma ms_struct on - - /// \brief Controls member pointer representation format under the MS ABI. - LangOptions::PragmaMSPointersToMembersKind - MSPointerToMemberRepresentationMethod; - - enum PragmaVtorDispKind { - PVDK_Push, ///< #pragma vtordisp(push, mode) - PVDK_Set, ///< #pragma vtordisp(mode) - PVDK_Pop, ///< #pragma vtordisp(pop) - PVDK_Reset ///< #pragma vtordisp() - }; - - enum PragmaMsStackAction { - PSK_Reset, // #pragma () - PSK_Set, // #pragma ("name") - PSK_Push, // #pragma (push[, id]) - PSK_Push_Set, // #pragma (push[, id], "name") - PSK_Pop, // #pragma (pop[, id]) - PSK_Pop_Set, // #pragma (pop[, id], "name") - }; - - /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft - /// C++ ABI. Possible values are 0, 1, and 2, which mean: - /// - /// 0: Suppress all vtordisps - /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial - /// structors - /// 2: Always insert vtordisps to support RTTI on partially constructed - /// objects - /// - /// The stack always has at least one element in it. - SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack; - - /// Stack of active SEH __finally scopes. Can be empty. - SmallVector<Scope*, 2> CurrentSEHFinally; - - /// \brief Source location for newly created implicit MSInheritanceAttrs - SourceLocation ImplicitMSInheritanceAttrLoc; - - template<typename ValueType> - struct PragmaStack { - struct Slot { - llvm::StringRef StackSlotLabel; - ValueType Value; - SourceLocation PragmaLocation; - Slot(llvm::StringRef StackSlotLabel, - ValueType Value, - SourceLocation PragmaLocation) - : StackSlotLabel(StackSlotLabel), Value(Value), - PragmaLocation(PragmaLocation) {} - }; - void Act(SourceLocation PragmaLocation, - PragmaMsStackAction Action, - llvm::StringRef StackSlotLabel, - ValueType Value); - explicit PragmaStack(const ValueType &Value) - : CurrentValue(Value) {} - SmallVector<Slot, 2> Stack; - ValueType CurrentValue; - SourceLocation CurrentPragmaLocation; - }; - // FIXME: We should serialize / deserialize these if they occur in a PCH (but - // we shouldn't do so if they're in a module). - PragmaStack<StringLiteral *> DataSegStack; - PragmaStack<StringLiteral *> BSSSegStack; - PragmaStack<StringLiteral *> ConstSegStack; - PragmaStack<StringLiteral *> CodeSegStack; - - /// A mapping that describes the nullability we've seen in each header file. - FileNullabilityMap NullabilityMap; - - /// Last section used with #pragma init_seg. - StringLiteral *CurInitSeg; - SourceLocation CurInitSegLoc; - - /// VisContext - Manages the stack for \#pragma GCC visibility. - void *VisContext; // Really a "PragmaVisStack*" - - /// \brief This represents the last location of a "#pragma clang optimize off" - /// directive if such a directive has not been closed by an "on" yet. If - /// optimizations are currently "on", this is set to an invalid location. - SourceLocation OptimizeOffPragmaLocation; - - /// \brief Flag indicating if Sema is building a recovery call expression. - /// - /// This flag is used to avoid building recovery call expressions - /// if Sema is already doing so, which would cause infinite recursions. - bool IsBuildingRecoveryCallExpr; - - /// ExprNeedsCleanups - True if the current evaluation context - /// requires cleanups to be run at its conclusion. - bool ExprNeedsCleanups; - - /// ExprCleanupObjects - This is the stack of objects requiring - /// cleanup that are created by the current full expression. The - /// element type here is ExprWithCleanups::Object. - SmallVector<BlockDecl*, 8> ExprCleanupObjects; - - /// \brief Store a list of either DeclRefExprs or MemberExprs - /// that contain a reference to a variable (constant) that may or may not - /// be odr-used in this Expr, and we won't know until all lvalue-to-rvalue - /// and discarded value conversions have been applied to all subexpressions - /// of the enclosing full expression. This is cleared at the end of each - /// full expression. - llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs; - - /// \brief Stack containing information about each of the nested - /// function, block, and method scopes that are currently active. - /// - /// This array is never empty. Clients should ignore the first - /// element, which is used to cache a single FunctionScopeInfo - /// that's used to parse every top-level function. - SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; - - typedef LazyVector<TypedefNameDecl *, ExternalSemaSource, - &ExternalSemaSource::ReadExtVectorDecls, 2, 2> - ExtVectorDeclsType; - - /// ExtVectorDecls - This is a list all the extended vector types. This allows - /// us to associate a raw vector type with one of the ext_vector type names. - /// This is only necessary for issuing pretty diagnostics. - ExtVectorDeclsType ExtVectorDecls; - - /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. - std::unique_ptr<CXXFieldCollector> FieldCollector; - - typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType; - - /// \brief Set containing all declared private fields that are not used. - NamedDeclSetType UnusedPrivateFields; - - /// \brief Set containing all typedefs that are likely unused. - llvm::SmallSetVector<const TypedefNameDecl *, 4> - UnusedLocalTypedefNameCandidates; - - /// \brief Delete-expressions to be analyzed at the end of translation unit - /// - /// This list contains class members, and locations of delete-expressions - /// that could not be proven as to whether they mismatch with new-expression - /// used in initializer of the field. - typedef std::pair<SourceLocation, bool> DeleteExprLoc; - typedef llvm::SmallVector<DeleteExprLoc, 4> DeleteLocs; - llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs; - - typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy; - - /// PureVirtualClassDiagSet - a set of class declarations which we have - /// emitted a list of pure virtual functions. Used to prevent emitting the - /// same list more than once. - std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet; - - /// ParsingInitForAutoVars - a set of declarations with auto types for which - /// we are currently parsing the initializer. - llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars; - - /// \brief Look for a locally scoped extern "C" declaration by the given name. - NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); - - typedef LazyVector<VarDecl *, ExternalSemaSource, - &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> - TentativeDefinitionsType; - - /// \brief All the tentative definitions encountered in the TU. - TentativeDefinitionsType TentativeDefinitions; - - typedef LazyVector<const DeclaratorDecl *, ExternalSemaSource, - &ExternalSemaSource::ReadUnusedFileScopedDecls, 2, 2> - UnusedFileScopedDeclsType; - - /// \brief The set of file scoped decls seen so far that have not been used - /// and must warn if not used. Only contains the first declaration. - UnusedFileScopedDeclsType UnusedFileScopedDecls; - - typedef LazyVector<CXXConstructorDecl *, ExternalSemaSource, - &ExternalSemaSource::ReadDelegatingConstructors, 2, 2> - DelegatingCtorDeclsType; - - /// \brief All the delegating constructors seen so far in the file, used for - /// cycle detection at the end of the TU. - DelegatingCtorDeclsType DelegatingCtorDecls; - - /// \brief All the overriding functions seen during a class definition - /// that had their exception spec checks delayed, plus the overridden - /// function. - SmallVector<std::pair<const CXXMethodDecl*, const CXXMethodDecl*>, 2> - DelayedExceptionSpecChecks; - - /// \brief All the members seen during a class definition which were both - /// explicitly defaulted and had explicitly-specified exception - /// specifications, along with the function type containing their - /// user-specified exception specification. Those exception specifications - /// were overridden with the default specifications, but we still need to - /// check whether they are compatible with the default specification, and - /// we can't do that until the nesting set of class definitions is complete. - SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> - DelayedDefaultedMemberExceptionSpecs; - - typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> - LateParsedTemplateMapT; - LateParsedTemplateMapT LateParsedTemplateMap; - - /// \brief Callback to the parser to parse templated functions when needed. - typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT); - typedef void LateTemplateParserCleanupCB(void *P); - LateTemplateParserCB *LateTemplateParser; - LateTemplateParserCleanupCB *LateTemplateParserCleanup; - void *OpaqueParser; - - void SetLateTemplateParser(LateTemplateParserCB *LTP, - LateTemplateParserCleanupCB *LTPCleanup, - void *P) { - LateTemplateParser = LTP; - LateTemplateParserCleanup = LTPCleanup; - OpaqueParser = P; - } - - class DelayedDiagnostics; - - class DelayedDiagnosticsState { - sema::DelayedDiagnosticPool *SavedPool; - friend class Sema::DelayedDiagnostics; - }; - typedef DelayedDiagnosticsState ParsingDeclState; - typedef DelayedDiagnosticsState ProcessingContextState; - - /// A class which encapsulates the logic for delaying diagnostics - /// during parsing and other processing. - class DelayedDiagnostics { - /// \brief The current pool of diagnostics into which delayed - /// diagnostics should go. - sema::DelayedDiagnosticPool *CurPool; - - public: - DelayedDiagnostics() : CurPool(nullptr) {} - - /// Adds a delayed diagnostic. - void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h - - /// Determines whether diagnostics should be delayed. - bool shouldDelayDiagnostics() { return CurPool != nullptr; } - - /// Returns the current delayed-diagnostics pool. - sema::DelayedDiagnosticPool *getCurrentPool() const { - return CurPool; - } - - /// Enter a new scope. Access and deprecation diagnostics will be - /// collected in this pool. - DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) { - DelayedDiagnosticsState state; - state.SavedPool = CurPool; - CurPool = &pool; - return state; - } - - /// Leave a delayed-diagnostic state that was previously pushed. - /// Do not emit any of the diagnostics. This is performed as part - /// of the bookkeeping of popping a pool "properly". - void popWithoutEmitting(DelayedDiagnosticsState state) { - CurPool = state.SavedPool; - } - - /// Enter a new scope where access and deprecation diagnostics are - /// not delayed. - DelayedDiagnosticsState pushUndelayed() { - DelayedDiagnosticsState state; - state.SavedPool = CurPool; - CurPool = nullptr; - return state; - } - - /// Undo a previous pushUndelayed(). - void popUndelayed(DelayedDiagnosticsState state) { - assert(CurPool == nullptr); - CurPool = state.SavedPool; - } - } DelayedDiagnostics; - - /// A RAII object to temporarily push a declaration context. - class ContextRAII { - private: - Sema &S; - DeclContext *SavedContext; - ProcessingContextState SavedContextState; - QualType SavedCXXThisTypeOverride; - - public: - ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true) - : S(S), SavedContext(S.CurContext), - SavedContextState(S.DelayedDiagnostics.pushUndelayed()), - SavedCXXThisTypeOverride(S.CXXThisTypeOverride) - { - assert(ContextToPush && "pushing null context"); - S.CurContext = ContextToPush; - if (NewThisContext) - S.CXXThisTypeOverride = QualType(); - } - - void pop() { - if (!SavedContext) return; - S.CurContext = SavedContext; - S.DelayedDiagnostics.popUndelayed(SavedContextState); - S.CXXThisTypeOverride = SavedCXXThisTypeOverride; - SavedContext = nullptr; - } - - ~ContextRAII() { - pop(); - } - }; - - /// \brief RAII object to handle the state changes required to synthesize - /// a function body. - class SynthesizedFunctionScope { - Sema &S; - Sema::ContextRAII SavedContext; - - public: - SynthesizedFunctionScope(Sema &S, DeclContext *DC) - : S(S), SavedContext(S, DC) - { - S.PushFunctionScope(); - S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); - } - - ~SynthesizedFunctionScope() { - S.PopExpressionEvaluationContext(); - S.PopFunctionScopeInfo(); - } - }; - - /// WeakUndeclaredIdentifiers - Identifiers contained in - /// \#pragma weak before declared. rare. may alias another - /// identifier, declared or undeclared - llvm::MapVector<IdentifierInfo *, WeakInfo> WeakUndeclaredIdentifiers; - - /// ExtnameUndeclaredIdentifiers - Identifiers contained in - /// \#pragma redefine_extname before declared. Used in Solaris system headers - /// to define functions that occur in multiple standards to call the version - /// in the currently selected standard. - llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers; - - - /// \brief Load weak undeclared identifiers from the external source. - void LoadExternalWeakUndeclaredIdentifiers(); - - /// WeakTopLevelDecl - Translation-unit scoped declarations generated by - /// \#pragma weak during processing of other Decls. - /// I couldn't figure out a clean way to generate these in-line, so - /// we store them here and handle separately -- which is a hack. - /// It would be best to refactor this. - SmallVector<Decl*,2> WeakTopLevelDecl; - - IdentifierResolver IdResolver; - - /// Translation Unit Scope - useful to Objective-C actions that need - /// to lookup file scope declarations in the "ordinary" C decl namespace. - /// For example, user-defined classes, built-in "id" type, etc. - Scope *TUScope; - - /// \brief The C++ "std" namespace, where the standard library resides. - LazyDeclPtr StdNamespace; - - /// \brief The C++ "std::bad_alloc" class, which is defined by the C++ - /// standard library. - LazyDeclPtr StdBadAlloc; - - /// \brief The C++ "std::initializer_list" template, which is defined in - /// \<initializer_list>. - ClassTemplateDecl *StdInitializerList; - - /// \brief The C++ "type_info" declaration, which is defined in \<typeinfo>. - RecordDecl *CXXTypeInfoDecl; - - /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files. - RecordDecl *MSVCGuidDecl; - - /// \brief Caches identifiers/selectors for NSFoundation APIs. - std::unique_ptr<NSAPI> NSAPIObj; - - /// \brief The declaration of the Objective-C NSNumber class. - ObjCInterfaceDecl *NSNumberDecl; - - /// \brief The declaration of the Objective-C NSValue class. - ObjCInterfaceDecl *NSValueDecl; - - /// \brief Pointer to NSNumber type (NSNumber *). - QualType NSNumberPointer; - - /// \brief Pointer to NSValue type (NSValue *). - QualType NSValuePointer; - - /// \brief The Objective-C NSNumber methods used to create NSNumber literals. - ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]; - - /// \brief The declaration of the Objective-C NSString class. - ObjCInterfaceDecl *NSStringDecl; - - /// \brief Pointer to NSString type (NSString *). - QualType NSStringPointer; - - /// \brief The declaration of the stringWithUTF8String: method. - ObjCMethodDecl *StringWithUTF8StringMethod; - - /// \brief The declaration of the valueWithBytes:objCType: method. - ObjCMethodDecl *ValueWithBytesObjCTypeMethod; - - /// \brief The declaration of the Objective-C NSArray class. - ObjCInterfaceDecl *NSArrayDecl; - - /// \brief The declaration of the arrayWithObjects:count: method. - ObjCMethodDecl *ArrayWithObjectsMethod; - - /// \brief The declaration of the Objective-C NSDictionary class. - ObjCInterfaceDecl *NSDictionaryDecl; - - /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method. - ObjCMethodDecl *DictionaryWithObjectsMethod; - - /// \brief id<NSCopying> type. - QualType QIDNSCopying; - - /// \brief will hold 'respondsToSelector:' - Selector RespondsToSelectorSel; - - /// \brief counter for internal MS Asm label names. - unsigned MSAsmLabelNameCounter; - - /// A flag to remember whether the implicit forms of operator new and delete - /// have been declared. - bool GlobalNewDeleteDeclared; - - /// A flag to indicate that we're in a context that permits abstract - /// references to fields. This is really a - bool AllowAbstractFieldReference; - - /// \brief Describes how the expressions currently being parsed are - /// evaluated at run-time, if at all. - enum ExpressionEvaluationContext { - /// \brief The current expression and its subexpressions occur within an - /// unevaluated operand (C++11 [expr]p7), such as the subexpression of - /// \c sizeof, where the type of the expression may be significant but - /// no code will be generated to evaluate the value of the expression at - /// run time. - Unevaluated, - - /// \brief The current expression occurs within an unevaluated - /// operand that unconditionally permits abstract references to - /// fields, such as a SIZE operator in MS-style inline assembly. - UnevaluatedAbstract, - - /// \brief The current context is "potentially evaluated" in C++11 terms, - /// but the expression is evaluated at compile-time (like the values of - /// cases in a switch statement). - ConstantEvaluated, - - /// \brief The current expression is potentially evaluated at run time, - /// which means that code may be generated to evaluate the value of the - /// expression at run time. - PotentiallyEvaluated, - - /// \brief The current expression is potentially evaluated, but any - /// declarations referenced inside that expression are only used if - /// in fact the current expression is used. - /// - /// This value is used when parsing default function arguments, for which - /// we would like to provide diagnostics (e.g., passing non-POD arguments - /// through varargs) but do not want to mark declarations as "referenced" - /// until the default argument is used. - PotentiallyEvaluatedIfUsed - }; - - /// \brief Data structure used to record current or nested - /// expression evaluation contexts. - struct ExpressionEvaluationContextRecord { - /// \brief The expression evaluation context. - ExpressionEvaluationContext Context; - - /// \brief Whether the enclosing context needed a cleanup. - bool ParentNeedsCleanups; - - /// \brief Whether we are in a decltype expression. - bool IsDecltype; - - /// \brief The number of active cleanup objects when we entered - /// this expression evaluation context. - unsigned NumCleanupObjects; - - /// \brief The number of typos encountered during this expression evaluation - /// context (i.e. the number of TypoExprs created). - unsigned NumTypos; - - llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs; - - /// \brief The lambdas that are present within this context, if it - /// is indeed an unevaluated context. - SmallVector<LambdaExpr *, 2> Lambdas; - - /// \brief The declaration that provides context for lambda expressions - /// and block literals if the normal declaration context does not - /// suffice, e.g., in a default function argument. - Decl *ManglingContextDecl; - - /// \brief The context information used to mangle lambda expressions - /// and block literals within this context. - /// - /// This mangling information is allocated lazily, since most contexts - /// do not have lambda expressions or block literals. - IntrusiveRefCntPtr<MangleNumberingContext> MangleNumbering; - - /// \brief If we are processing a decltype type, a set of call expressions - /// for which we have deferred checking the completeness of the return type. - SmallVector<CallExpr *, 8> DelayedDecltypeCalls; - - /// \brief If we are processing a decltype type, a set of temporary binding - /// expressions for which we have deferred checking the destructor. - SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds; - - ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, - unsigned NumCleanupObjects, - bool ParentNeedsCleanups, - Decl *ManglingContextDecl, - bool IsDecltype) - : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), - IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), - NumTypos(0), - ManglingContextDecl(ManglingContextDecl), MangleNumbering() { } - - /// \brief Retrieve the mangling numbering context, used to consistently - /// number constructs like lambdas for mangling. - MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx); - - bool isUnevaluated() const { - return Context == Unevaluated || Context == UnevaluatedAbstract; - } - }; - - /// A stack of expression evaluation contexts. - SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; - - /// \brief Compute the mangling number context for a lambda expression or - /// block literal. - /// - /// \param DC - The DeclContext containing the lambda expression or - /// block literal. - /// \param[out] ManglingContextDecl - Returns the ManglingContextDecl - /// associated with the context, if relevant. - MangleNumberingContext *getCurrentMangleNumberContext( - const DeclContext *DC, - Decl *&ManglingContextDecl); - - - /// SpecialMemberOverloadResult - The overloading result for a special member - /// function. - /// - /// This is basically a wrapper around PointerIntPair. The lowest bits of the - /// integer are used to determine whether overload resolution succeeded. - class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode { - public: - enum Kind { - NoMemberOrDeleted, - Ambiguous, - Success - }; - - private: - llvm::PointerIntPair<CXXMethodDecl*, 2> Pair; - - public: - SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID) - : FastFoldingSetNode(ID) - {} - - CXXMethodDecl *getMethod() const { return Pair.getPointer(); } - void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); } - - Kind getKind() const { return static_cast<Kind>(Pair.getInt()); } - void setKind(Kind K) { Pair.setInt(K); } - }; - - /// \brief A cache of special member function overload resolution results - /// for C++ records. - llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; - - /// \brief A cache of the flags available in enumerations with the flag_bits - /// attribute. - mutable llvm::DenseMap<const EnumDecl*, llvm::APInt> FlagBitsCache; - - /// \brief The kind of translation unit we are processing. - /// - /// When we're processing a complete translation unit, Sema will perform - /// end-of-translation-unit semantic tasks (such as creating - /// initializers for tentative definitions in C) once parsing has - /// completed. Modules and precompiled headers perform different kinds of - /// checks. - TranslationUnitKind TUKind; - - llvm::BumpPtrAllocator BumpAlloc; - - /// \brief The number of SFINAE diagnostics that have been trapped. - unsigned NumSFINAEErrors; - - typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>> - UnparsedDefaultArgInstantiationsMap; - - /// \brief A mapping from parameters with unparsed default arguments to the - /// set of instantiations of each parameter. - /// - /// This mapping is a temporary data structure used when parsing - /// nested class templates or nested classes of class templates, - /// where we might end up instantiating an inner class before the - /// default arguments of its methods have been parsed. - UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations; - - // Contains the locations of the beginning of unparsed default - // argument locations. - llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs; - - /// UndefinedInternals - all the used, undefined objects which require a - /// definition in this translation unit. - llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed; - - /// Obtain a sorted list of functions that are undefined but ODR-used. - void getUndefinedButUsed( - SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); - - /// Retrieves list of suspicious delete-expressions that will be checked at - /// the end of translation unit. - const llvm::MapVector<FieldDecl *, DeleteLocs> & - getMismatchingDeleteExpressions() const; - - typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; - typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; - - /// Method Pool - allows efficient lookup when typechecking messages to "id". - /// We need to maintain a list, since selectors can have differing signatures - /// across classes. In Cocoa, this happens to be extremely uncommon (only 1% - /// of selectors are "overloaded"). - /// At the head of the list it is recorded whether there were 0, 1, or >= 2 - /// methods inside categories with a particular selector. - GlobalMethodPool MethodPool; - - /// Method selectors used in a \@selector expression. Used for implementation - /// of -Wselector. - llvm::MapVector<Selector, SourceLocation> ReferencedSelectors; - - /// Kinds of C++ special members. - enum CXXSpecialMember { - CXXDefaultConstructor, - CXXCopyConstructor, - CXXMoveConstructor, - CXXCopyAssignment, - CXXMoveAssignment, - CXXDestructor, - CXXInvalid - }; - - typedef std::pair<CXXRecordDecl*, CXXSpecialMember> SpecialMemberDecl; - - /// The C++ special members which we are currently in the process of - /// declaring. If this process recursively triggers the declaration of the - /// same special member, we should act as if it is not yet declared. - llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared; - - void ReadMethodPool(Selector Sel); - - /// Private Helper predicate to check for 'self'. - bool isSelfExpr(Expr *RExpr); - bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method); - - /// \brief Cause the active diagnostic on the DiagosticsEngine to be - /// emitted. This is closely coupled to the SemaDiagnosticBuilder class and - /// should not be used elsewhere. - void EmitCurrentDiagnostic(unsigned DiagID); - - /// Records and restores the FP_CONTRACT state on entry/exit of compound - /// statements. - class FPContractStateRAII { - public: - FPContractStateRAII(Sema& S) - : S(S), OldFPContractState(S.FPFeatures.fp_contract) {} - ~FPContractStateRAII() { - S.FPFeatures.fp_contract = OldFPContractState; - } - private: - Sema& S; - bool OldFPContractState : 1; - }; - - /// Records and restores the vtordisp state on entry/exit of C++ method body. - class VtorDispStackRAII { - public: - VtorDispStackRAII(Sema &S, bool ShouldSaveAndRestore) - : S(S), ShouldSaveAndRestore(ShouldSaveAndRestore), OldVtorDispStack() { - if (ShouldSaveAndRestore) - OldVtorDispStack = S.VtorDispModeStack; - } - ~VtorDispStackRAII() { - if (ShouldSaveAndRestore) - S.VtorDispModeStack = OldVtorDispStack; - } - private: - Sema &S; - bool ShouldSaveAndRestore; - SmallVector<MSVtorDispAttr::Mode, 2> OldVtorDispStack; - }; - - void addImplicitTypedef(StringRef Name, QualType T); - -public: - Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, - TranslationUnitKind TUKind = TU_Complete, - CodeCompleteConsumer *CompletionConsumer = nullptr); - ~Sema(); - - /// \brief Perform initialization that occurs after the parser has been - /// initialized but before it parses anything. - void Initialize(); - - const LangOptions &getLangOpts() const { return LangOpts; } - OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; } - FPOptions &getFPOptions() { return FPFeatures; } - - DiagnosticsEngine &getDiagnostics() const { return Diags; } - SourceManager &getSourceManager() const { return SourceMgr; } - Preprocessor &getPreprocessor() const { return PP; } - ASTContext &getASTContext() const { return Context; } - ASTConsumer &getASTConsumer() const { return Consumer; } - ASTMutationListener *getASTMutationListener() const; - ExternalSemaSource* getExternalSource() const { return ExternalSource; } - - ///\brief Registers an external source. If an external source already exists, - /// creates a multiplex external source and appends to it. - /// - ///\param[in] E - A non-null external sema source. - /// - void addExternalSource(ExternalSemaSource *E); - - void PrintStats() const; - - /// \brief Helper class that creates diagnostics with optional - /// template instantiation stacks. - /// - /// This class provides a wrapper around the basic DiagnosticBuilder - /// class that emits diagnostics. SemaDiagnosticBuilder is - /// responsible for emitting the diagnostic (as DiagnosticBuilder - /// does) and, if the diagnostic comes from inside a template - /// instantiation, printing the template instantiation stack as - /// well. - class SemaDiagnosticBuilder : public DiagnosticBuilder { - Sema &SemaRef; - unsigned DiagID; - - public: - SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID) - : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { } - - // This is a cunning lie. DiagnosticBuilder actually performs move - // construction in its copy constructor (but due to varied uses, it's not - // possible to conveniently express this as actual move construction). So - // the default copy ctor here is fine, because the base class disables the - // source anyway, so the user-defined ~SemaDiagnosticBuilder is a safe no-op - // in that case anwyay. - SemaDiagnosticBuilder(const SemaDiagnosticBuilder&) = default; - - ~SemaDiagnosticBuilder() { - // If we aren't active, there is nothing to do. - if (!isActive()) return; - - // Otherwise, we need to emit the diagnostic. First flush the underlying - // DiagnosticBuilder data, and clear the diagnostic builder itself so it - // won't emit the diagnostic in its own destructor. - // - // This seems wasteful, in that as written the DiagnosticBuilder dtor will - // do its own needless checks to see if the diagnostic needs to be - // emitted. However, because we take care to ensure that the builder - // objects never escape, a sufficiently smart compiler will be able to - // eliminate that code. - FlushCounts(); - Clear(); - - // Dispatch to Sema to emit the diagnostic. - SemaRef.EmitCurrentDiagnostic(DiagID); - } - - /// Teach operator<< to produce an object of the correct type. - template<typename T> - friend const SemaDiagnosticBuilder &operator<<( - const SemaDiagnosticBuilder &Diag, const T &Value) { - const DiagnosticBuilder &BaseDiag = Diag; - BaseDiag << Value; - return Diag; - } - }; - - /// \brief Emit a diagnostic. - SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { - DiagnosticBuilder DB = Diags.Report(Loc, DiagID); - return SemaDiagnosticBuilder(DB, *this, DiagID); - } - - /// \brief Emit a partial diagnostic. - SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD); - - /// \brief Build a partial diagnostic. - PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h - - bool findMacroSpelling(SourceLocation &loc, StringRef name); - - /// \brief Get a string to suggest for zero-initialization of a type. - std::string - getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const; - std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const; - - /// \brief Calls \c Lexer::getLocForEndOfToken() - SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0); - - /// \brief Retrieve the module loader associated with the preprocessor. - ModuleLoader &getModuleLoader() const; - - void emitAndClearUnusedLocalTypedefWarnings(); - - void ActOnEndOfTranslationUnit(); - - void CheckDelegatingCtorCycles(); - - Scope *getScopeForContext(DeclContext *Ctx); - - void PushFunctionScope(); - void PushBlockScope(Scope *BlockScope, BlockDecl *Block); - sema::LambdaScopeInfo *PushLambdaScope(); - - /// \brief This is used to inform Sema what the current TemplateParameterDepth - /// is during Parsing. Currently it is used to pass on the depth - /// when parsing generic lambda 'auto' parameters. - void RecordParsingTemplateParameterDepth(unsigned Depth); - - void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, - RecordDecl *RD, - CapturedRegionKind K); - void - PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr, - const Decl *D = nullptr, - const BlockExpr *blkExpr = nullptr); - - sema::FunctionScopeInfo *getCurFunction() const { - return FunctionScopes.back(); - } - - sema::FunctionScopeInfo *getEnclosingFunction() const { - if (FunctionScopes.empty()) - return nullptr; - - for (int e = FunctionScopes.size()-1; e >= 0; --e) { - if (isa<sema::BlockScopeInfo>(FunctionScopes[e])) - continue; - return FunctionScopes[e]; - } - return nullptr; - } - - template <typename ExprT> - void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) { - if (!isUnevaluatedContext()) - getCurFunction()->recordUseOfWeak(E, IsRead); - } - - void PushCompoundScope(); - void PopCompoundScope(); - - sema::CompoundScopeInfo &getCurCompoundScope() const; - - bool hasAnyUnrecoverableErrorsInThisFunction() const; - - /// \brief Retrieve the current block, if any. - sema::BlockScopeInfo *getCurBlock(); - - /// \brief Retrieve the current lambda scope info, if any. - sema::LambdaScopeInfo *getCurLambda(); - - /// \brief Retrieve the current generic lambda info, if any. - sema::LambdaScopeInfo *getCurGenericLambda(); - - /// \brief Retrieve the current captured region, if any. - sema::CapturedRegionScopeInfo *getCurCapturedRegion(); - - /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls - SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; } - - void ActOnComment(SourceRange Comment); - - //===--------------------------------------------------------------------===// - // Type Analysis / Processing: SemaType.cpp. - // - - QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, - const DeclSpec *DS = nullptr); - QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA, - const DeclSpec *DS = nullptr); - QualType BuildPointerType(QualType T, - SourceLocation Loc, DeclarationName Entity); - QualType BuildReferenceType(QualType T, bool LValueRef, - SourceLocation Loc, DeclarationName Entity); - QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, - Expr *ArraySize, unsigned Quals, - SourceRange Brackets, DeclarationName Entity); - QualType BuildExtVectorType(QualType T, Expr *ArraySize, - SourceLocation AttrLoc); - - bool CheckFunctionReturnType(QualType T, SourceLocation Loc); - - /// \brief Build a function type. - /// - /// This routine checks the function type according to C++ rules and - /// under the assumption that the result type and parameter types have - /// just been instantiated from a template. It therefore duplicates - /// some of the behavior of GetTypeForDeclarator, but in a much - /// simpler form that is only suitable for this narrow use case. - /// - /// \param T The return type of the function. - /// - /// \param ParamTypes The parameter types of the function. This array - /// will be modified to account for adjustments to the types of the - /// function parameters. - /// - /// \param Loc The location of the entity whose type involves this - /// function type or, if there is no such entity, the location of the - /// type that will have function type. - /// - /// \param Entity The name of the entity that involves the function - /// type, if known. - /// - /// \param EPI Extra information about the function type. Usually this will - /// be taken from an existing function with the same prototype. - /// - /// \returns A suitable function type, if there are no errors. The - /// unqualified type will always be a FunctionProtoType. - /// Otherwise, returns a NULL type. - QualType BuildFunctionType(QualType T, - MutableArrayRef<QualType> ParamTypes, - SourceLocation Loc, DeclarationName Entity, - const FunctionProtoType::ExtProtoInfo &EPI); - - QualType BuildMemberPointerType(QualType T, QualType Class, - SourceLocation Loc, - DeclarationName Entity); - QualType BuildBlockPointerType(QualType T, - SourceLocation Loc, DeclarationName Entity); - QualType BuildParenType(QualType T); - QualType BuildAtomicType(QualType T, SourceLocation Loc); - - TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); - TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); - TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, - TypeSourceInfo *ReturnTypeInfo); - - /// \brief Package the given type and TSI into a ParsedType. - ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo); - DeclarationNameInfo GetNameForDeclarator(Declarator &D); - DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name); - static QualType GetTypeFromParser(ParsedType Ty, - TypeSourceInfo **TInfo = nullptr); - CanThrowResult canThrow(const Expr *E); - const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, - const FunctionProtoType *FPT); - void UpdateExceptionSpec(FunctionDecl *FD, - const FunctionProtoType::ExceptionSpecInfo &ESI); - bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range); - bool CheckDistantExceptionSpec(QualType T); - bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New); - bool CheckEquivalentExceptionSpec( - const FunctionProtoType *Old, SourceLocation OldLoc, - const FunctionProtoType *New, SourceLocation NewLoc); - bool CheckEquivalentExceptionSpec( - const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, - const FunctionProtoType *Old, SourceLocation OldLoc, - const FunctionProtoType *New, SourceLocation NewLoc, - bool *MissingExceptionSpecification = nullptr, - bool *MissingEmptyExceptionSpecification = nullptr, - bool AllowNoexceptAllMatchWithNoSpec = false, - bool IsOperatorNew = false); - bool CheckExceptionSpecSubset( - const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, - const FunctionProtoType *Superset, SourceLocation SuperLoc, - const FunctionProtoType *Subset, SourceLocation SubLoc); - bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID, - const FunctionProtoType *Target, SourceLocation TargetLoc, - const FunctionProtoType *Source, SourceLocation SourceLoc); - - TypeResult ActOnTypeName(Scope *S, Declarator &D); - - /// \brief The parser has parsed the context-sensitive type 'instancetype' - /// in an Objective-C message declaration. Return the appropriate type. - ParsedType ActOnObjCInstanceType(SourceLocation Loc); - - /// \brief Abstract class used to diagnose incomplete types. - struct TypeDiagnoser { - TypeDiagnoser() {} - - virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0; - virtual ~TypeDiagnoser() {} - }; - - static int getPrintable(int I) { return I; } - static unsigned getPrintable(unsigned I) { return I; } - static bool getPrintable(bool B) { return B; } - static const char * getPrintable(const char *S) { return S; } - static StringRef getPrintable(StringRef S) { return S; } - static const std::string &getPrintable(const std::string &S) { return S; } - static const IdentifierInfo *getPrintable(const IdentifierInfo *II) { - return II; - } - static DeclarationName getPrintable(DeclarationName N) { return N; } - static QualType getPrintable(QualType T) { return T; } - static SourceRange getPrintable(SourceRange R) { return R; } - static SourceRange getPrintable(SourceLocation L) { return L; } - static SourceRange getPrintable(const Expr *E) { return E->getSourceRange(); } - static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} - - template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser { - unsigned DiagID; - std::tuple<const Ts &...> Args; - - template <std::size_t... Is> - void emit(const SemaDiagnosticBuilder &DB, - llvm::index_sequence<Is...>) const { - // Apply all tuple elements to the builder in order. - bool Dummy[] = {false, (DB << getPrintable(std::get<Is>(Args)))...}; - (void)Dummy; - } - - public: - BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args) - : TypeDiagnoser(), DiagID(DiagID), Args(Args...) { - assert(DiagID != 0 && "no diagnostic for type diagnoser"); - } - - void diagnose(Sema &S, SourceLocation Loc, QualType T) override { - const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID); - emit(DB, llvm::index_sequence_for<Ts...>()); - DB << T; - } - }; - -private: - bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, - TypeDiagnoser *Diagnoser); - - VisibleModuleSet VisibleModules; - llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack; - - Module *CachedFakeTopLevelModule; - -public: - /// \brief Get the module owning an entity. - Module *getOwningModule(Decl *Entity); - - /// \brief Make a merged definition of an existing hidden definition \p ND - /// visible at the specified location. - void makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc); - - bool isModuleVisible(Module *M) { return VisibleModules.isVisible(M); } - - /// Determine whether a declaration is visible to name lookup. - bool isVisible(const NamedDecl *D) { - return !D->isHidden() || isVisibleSlow(D); - } - bool hasVisibleMergedDefinition(NamedDecl *Def); - - /// Determine if \p D has a visible definition. If not, suggest a declaration - /// that should be made visible to expose the definition. - bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, - bool OnlyNeedComplete = false); - bool hasVisibleDefinition(const NamedDecl *D) { - NamedDecl *Hidden; - return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden); - } - - /// Determine if the template parameter \p D has a visible default argument. - bool - hasVisibleDefaultArgument(const NamedDecl *D, - llvm::SmallVectorImpl<Module *> *Modules = nullptr); - - /// Determine if \p A and \p B are equivalent internal linkage declarations - /// from different modules, and thus an ambiguity error can be downgraded to - /// an extension warning. - bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A, - const NamedDecl *B); - void diagnoseEquivalentInternalLinkageDeclarations( - SourceLocation Loc, const NamedDecl *D, - ArrayRef<const NamedDecl *> Equiv); - - bool isCompleteType(SourceLocation Loc, QualType T) { - return !RequireCompleteTypeImpl(Loc, T, nullptr); - } - bool RequireCompleteType(SourceLocation Loc, QualType T, - TypeDiagnoser &Diagnoser); - bool RequireCompleteType(SourceLocation Loc, QualType T, - unsigned DiagID); - - template <typename... Ts> - bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID, - const Ts &...Args) { - BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); - return RequireCompleteType(Loc, T, Diagnoser); - } - - void completeExprArrayBound(Expr *E); - bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser); - bool RequireCompleteExprType(Expr *E, unsigned DiagID); - - template <typename... Ts> - bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) { - BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); - return RequireCompleteExprType(E, Diagnoser); - } - - bool RequireLiteralType(SourceLocation Loc, QualType T, - TypeDiagnoser &Diagnoser); - bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID); - - template <typename... Ts> - bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID, - const Ts &...Args) { - BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); - return RequireLiteralType(Loc, T, Diagnoser); - } - - QualType getElaboratedType(ElaboratedTypeKeyword Keyword, - const CXXScopeSpec &SS, QualType T); - - QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); - /// If AsUnevaluated is false, E is treated as though it were an evaluated - /// context, such as when building a type for decltype(auto). - QualType BuildDecltypeType(Expr *E, SourceLocation Loc, - bool AsUnevaluated = true); - QualType BuildUnaryTransformType(QualType BaseType, - UnaryTransformType::UTTKind UKind, - SourceLocation Loc); - - //===--------------------------------------------------------------------===// - // Symbol table / Decl tracking callbacks: SemaDecl.cpp. - // - - struct SkipBodyInfo { - SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {} - bool ShouldSkip; - NamedDecl *Previous; - }; - - /// List of decls defined in a function prototype. This contains EnumConstants - /// that incorrectly end up in translation unit scope because there is no - /// function to pin them on. ActOnFunctionDeclarator reads this list and patches - /// them into the FunctionDecl. - std::vector<NamedDecl*> DeclsInPrototypeScope; - - DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr); - - void DiagnoseUseOfUnimplementedSelectors(); - - bool isSimpleTypeSpecifier(tok::TokenKind Kind) const; - - ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, - Scope *S, CXXScopeSpec *SS = nullptr, - bool isClassName = false, - bool HasTrailingDot = false, - ParsedType ObjectType = ParsedType(), - bool IsCtorOrDtorName = false, - bool WantNontrivialTypeSourceInfo = false, - IdentifierInfo **CorrectedII = nullptr); - TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); - bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); - void DiagnoseUnknownTypeName(IdentifierInfo *&II, - SourceLocation IILoc, - Scope *S, - CXXScopeSpec *SS, - ParsedType &SuggestedType, - bool AllowClassTemplates = false); - - /// \brief For compatibility with MSVC, we delay parsing of some default - /// template type arguments until instantiation time. Emits a warning and - /// returns a synthesized DependentNameType that isn't really dependent on any - /// other template arguments. - ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, - SourceLocation NameLoc); - - /// \brief Describes the result of the name lookup and resolution performed - /// by \c ClassifyName(). - enum NameClassificationKind { - NC_Unknown, - NC_Error, - NC_Keyword, - NC_Type, - NC_Expression, - NC_NestedNameSpecifier, - NC_TypeTemplate, - NC_VarTemplate, - NC_FunctionTemplate - }; - - class NameClassification { - NameClassificationKind Kind; - ExprResult Expr; - TemplateName Template; - ParsedType Type; - const IdentifierInfo *Keyword; - - explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {} - - public: - NameClassification(ExprResult Expr) : Kind(NC_Expression), Expr(Expr) {} - - NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {} - - NameClassification(const IdentifierInfo *Keyword) - : Kind(NC_Keyword), Keyword(Keyword) { } - - static NameClassification Error() { - return NameClassification(NC_Error); - } - - static NameClassification Unknown() { - return NameClassification(NC_Unknown); - } - - static NameClassification NestedNameSpecifier() { - return NameClassification(NC_NestedNameSpecifier); - } - - static NameClassification TypeTemplate(TemplateName Name) { - NameClassification Result(NC_TypeTemplate); - Result.Template = Name; - return Result; - } - - static NameClassification VarTemplate(TemplateName Name) { - NameClassification Result(NC_VarTemplate); - Result.Template = Name; - return Result; - } - - static NameClassification FunctionTemplate(TemplateName Name) { - NameClassification Result(NC_FunctionTemplate); - Result.Template = Name; - return Result; - } - - NameClassificationKind getKind() const { return Kind; } - - ParsedType getType() const { - assert(Kind == NC_Type); - return Type; - } - - ExprResult getExpression() const { - assert(Kind == NC_Expression); - return Expr; - } - - TemplateName getTemplateName() const { - assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || - Kind == NC_VarTemplate); - return Template; - } - - TemplateNameKind getTemplateNameKind() const { - switch (Kind) { - case NC_TypeTemplate: - return TNK_Type_template; - case NC_FunctionTemplate: - return TNK_Function_template; - case NC_VarTemplate: - return TNK_Var_template; - default: - llvm_unreachable("unsupported name classification."); - } - } - }; - - /// \brief Perform name lookup on the given name, classifying it based on - /// the results of name lookup and the following token. - /// - /// This routine is used by the parser to resolve identifiers and help direct - /// parsing. When the identifier cannot be found, this routine will attempt - /// to correct the typo and classify based on the resulting name. - /// - /// \param S The scope in which we're performing name lookup. - /// - /// \param SS The nested-name-specifier that precedes the name. - /// - /// \param Name The identifier. If typo correction finds an alternative name, - /// this pointer parameter will be updated accordingly. - /// - /// \param NameLoc The location of the identifier. - /// - /// \param NextToken The token following the identifier. Used to help - /// disambiguate the name. - /// - /// \param IsAddressOfOperand True if this name is the operand of a unary - /// address of ('&') expression, assuming it is classified as an - /// expression. - /// - /// \param CCC The correction callback, if typo correction is desired. - NameClassification - ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, - SourceLocation NameLoc, const Token &NextToken, - bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); - - Decl *ActOnDeclarator(Scope *S, Declarator &D); - - NamedDecl *HandleDeclarator(Scope *S, Declarator &D, - MultiTemplateParamsArg TemplateParameterLists); - void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S); - bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); - bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, - DeclarationName Name, - SourceLocation Loc); - void - diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, - SourceLocation FallbackLoc, - SourceLocation ConstQualLoc = SourceLocation(), - SourceLocation VolatileQualLoc = SourceLocation(), - SourceLocation RestrictQualLoc = SourceLocation(), - SourceLocation AtomicQualLoc = SourceLocation()); - - static bool adjustContextForLocalExternDecl(DeclContext *&DC); - void DiagnoseFunctionSpecifiers(const DeclSpec &DS); - void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); - void CheckShadow(Scope *S, VarDecl *D); - void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); - void handleTagNumbering(const TagDecl *Tag, Scope *TagScope); - void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, - TypedefNameDecl *NewTD); - void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D); - NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, - TypeSourceInfo *TInfo, - LookupResult &Previous); - NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, - LookupResult &Previous, bool &Redeclaration); - NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, - TypeSourceInfo *TInfo, - LookupResult &Previous, - MultiTemplateParamsArg TemplateParamLists, - bool &AddToScope); - // Returns true if the variable declaration is a redeclaration - bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); - void CheckVariableDeclarationType(VarDecl *NewVD); - void CheckCompleteVariableDeclaration(VarDecl *var); - void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); - - NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, - TypeSourceInfo *TInfo, - LookupResult &Previous, - MultiTemplateParamsArg TemplateParamLists, - bool &AddToScope); - bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); - - bool CheckConstexprFunctionDecl(const FunctionDecl *FD); - bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body); - - void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD); - void FindHiddenVirtualMethods(CXXMethodDecl *MD, - SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); - void NoteHiddenVirtualMethods(CXXMethodDecl *MD, - SmallVectorImpl<CXXMethodDecl*> &OverloadedMethods); - // Returns true if the function declaration is a redeclaration - bool CheckFunctionDeclaration(Scope *S, - FunctionDecl *NewFD, LookupResult &Previous, - bool IsExplicitSpecialization); - void CheckMain(FunctionDecl *FD, const DeclSpec &D); - void CheckMSVCRTEntryPoint(FunctionDecl *FD); - Decl *ActOnParamDeclarator(Scope *S, Declarator &D); - ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, - SourceLocation Loc, - QualType T); - ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc, - SourceLocation NameLoc, IdentifierInfo *Name, - QualType T, TypeSourceInfo *TSInfo, - StorageClass SC); - void ActOnParamDefaultArgument(Decl *param, - SourceLocation EqualLoc, - Expr *defarg); - void ActOnParamUnparsedDefaultArgument(Decl *param, - SourceLocation EqualLoc, - SourceLocation ArgLoc); - void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); - bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, - SourceLocation EqualLoc); - - void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, - bool TypeMayContainAuto); - void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); - void ActOnInitializerError(Decl *Dcl); - void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc); - void ActOnCXXForRangeDecl(Decl *D); - StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, - IdentifierInfo *Ident, - ParsedAttributes &Attrs, - SourceLocation AttrEnd); - void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); - void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); - void FinalizeDeclaration(Decl *D); - DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, - ArrayRef<Decl *> Group); - DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group, - bool TypeMayContainAuto = true); - - /// Should be called on all declarations that might have attached - /// documentation comments. - void ActOnDocumentableDecl(Decl *D); - void ActOnDocumentableDecls(ArrayRef<Decl *> Group); - - void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, - SourceLocation LocAfterDecls); - void CheckForFunctionRedefinition( - FunctionDecl *FD, const FunctionDecl *EffectiveDefinition = nullptr, - SkipBodyInfo *SkipBody = nullptr); - Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D, - MultiTemplateParamsArg TemplateParamLists, - SkipBodyInfo *SkipBody = nullptr); - Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D, - SkipBodyInfo *SkipBody = nullptr); - void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); - bool isObjCMethodDecl(Decl *D) { - return D && isa<ObjCMethodDecl>(D); - } - - /// \brief Determine whether we can delay parsing the body of a function or - /// function template until it is used, assuming we don't care about emitting - /// code for that function. - /// - /// This will be \c false if we may need the body of the function in the - /// middle of parsing an expression (where it's impractical to switch to - /// parsing a different function), for instance, if it's constexpr in C++11 - /// or has an 'auto' return type in C++14. These cases are essentially bugs. - bool canDelayFunctionBody(const Declarator &D); - - /// \brief Determine whether we can skip parsing the body of a function - /// definition, assuming we don't care about analyzing its body or emitting - /// code for that function. - /// - /// This will be \c false only if we may need the body of the function in - /// order to parse the rest of the program (for instance, if it is - /// \c constexpr in C++11 or has an 'auto' return type in C++14). - bool canSkipFunctionBody(Decl *D); - - void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); - Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); - Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); - Decl *ActOnSkippedFunctionBody(Decl *Decl); - void ActOnFinishInlineMethodDef(CXXMethodDecl *D); - - /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an - /// attribute for which parsing is delayed. - void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs); - - /// \brief Diagnose any unused parameters in the given sequence of - /// ParmVarDecl pointers. - void DiagnoseUnusedParameters(ParmVarDecl * const *Begin, - ParmVarDecl * const *End); - - /// \brief Diagnose whether the size of parameters or return value of a - /// function or obj-c method definition is pass-by-value and larger than a - /// specified threshold. - void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin, - ParmVarDecl * const *End, - QualType ReturnTy, - NamedDecl *D); - - void DiagnoseInvalidJumps(Stmt *Body); - Decl *ActOnFileScopeAsmDecl(Expr *expr, - SourceLocation AsmLoc, - SourceLocation RParenLoc); - - /// \brief Handle a C++11 empty-declaration and attribute-declaration. - Decl *ActOnEmptyDeclaration(Scope *S, - AttributeList *AttrList, - SourceLocation SemiLoc); - - /// \brief The parser has processed a module import declaration. - /// - /// \param AtLoc The location of the '@' symbol, if any. - /// - /// \param ImportLoc The location of the 'import' keyword. - /// - /// \param Path The module access path. - DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, - ModuleIdPath Path); - - /// \brief The parser has processed a module import translated from a - /// #include or similar preprocessing directive. - void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); - - /// \brief The parsed has entered a submodule. - void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod); - /// \brief The parser has left a submodule. - void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); - - /// \brief Check if module import may be found in the current context, - /// emit error if not. - void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc); - - /// \brief Create an implicit import of the given module at the given - /// source location, for error recovery, if possible. - /// - /// This routine is typically used when an entity found by name lookup - /// is actually hidden within a module that we know about but the user - /// has forgotten to import. - void createImplicitModuleImportForErrorRecovery(SourceLocation Loc, - Module *Mod); - - /// Kinds of missing import. Note, the values of these enumerators correspond - /// to %select values in diagnostics. - enum class MissingImportKind { - Declaration, - Definition, - DefaultArgument - }; - - /// \brief Diagnose that the specified declaration needs to be visible but - /// isn't, and suggest a module import that would resolve the problem. - void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, - bool NeedDefinition, bool Recover = true); - void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, - SourceLocation DeclLoc, ArrayRef<Module *> Modules, - MissingImportKind MIK, bool Recover); - - /// \brief Retrieve a suitable printing policy. - PrintingPolicy getPrintingPolicy() const { - return getPrintingPolicy(Context, PP); - } - - /// \brief Retrieve a suitable printing policy. - static PrintingPolicy getPrintingPolicy(const ASTContext &Ctx, - const Preprocessor &PP); - - /// Scope actions. - void ActOnPopScope(SourceLocation Loc, Scope *S); - void ActOnTranslationUnitScope(Scope *S); - - Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, - DeclSpec &DS); - Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, - DeclSpec &DS, - MultiTemplateParamsArg TemplateParams, - bool IsExplicitInstantiation = false); - - Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, - AccessSpecifier AS, - RecordDecl *Record, - const PrintingPolicy &Policy); - - Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, - RecordDecl *Record); - - bool isAcceptableTagRedeclaration(const TagDecl *Previous, - TagTypeKind NewTag, bool isDefinition, - SourceLocation NewTagLoc, - const IdentifierInfo *Name); - - enum TagUseKind { - TUK_Reference, // Reference to a tag: 'struct foo *X;' - TUK_Declaration, // Fwd decl of a tag: 'struct foo;' - TUK_Definition, // Definition of a tag: 'struct foo { int X; } Y;' - TUK_Friend // Friend declaration: 'friend struct foo;' - }; - - Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, - SourceLocation KWLoc, CXXScopeSpec &SS, - IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr, AccessSpecifier AS, - SourceLocation ModulePrivateLoc, - MultiTemplateParamsArg TemplateParameterLists, - bool &OwnedDecl, bool &IsDependent, - SourceLocation ScopedEnumKWLoc, - bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, - bool IsTypeSpecifier, SkipBodyInfo *SkipBody = nullptr); - - Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, - unsigned TagSpec, SourceLocation TagLoc, - CXXScopeSpec &SS, - IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr, - MultiTemplateParamsArg TempParamLists); - - TypeResult ActOnDependentTag(Scope *S, - unsigned TagSpec, - TagUseKind TUK, - const CXXScopeSpec &SS, - IdentifierInfo *Name, - SourceLocation TagLoc, - SourceLocation NameLoc); - - void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, - IdentifierInfo *ClassName, - SmallVectorImpl<Decl *> &Decls); - Decl *ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, - Declarator &D, Expr *BitfieldWidth); - - FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, - Declarator &D, Expr *BitfieldWidth, - InClassInitStyle InitStyle, - AccessSpecifier AS); - MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD, - SourceLocation DeclStart, - Declarator &D, Expr *BitfieldWidth, - InClassInitStyle InitStyle, - AccessSpecifier AS, - AttributeList *MSPropertyAttr); - - FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, - TypeSourceInfo *TInfo, - RecordDecl *Record, SourceLocation Loc, - bool Mutable, Expr *BitfieldWidth, - InClassInitStyle InitStyle, - SourceLocation TSSL, - AccessSpecifier AS, NamedDecl *PrevDecl, - Declarator *D = nullptr); - - bool CheckNontrivialField(FieldDecl *FD); - void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM); - bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMember CSM, - bool Diagnose = false); - CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD); - void ActOnLastBitfield(SourceLocation DeclStart, - SmallVectorImpl<Decl *> &AllIvarDecls); - Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, - Declarator &D, Expr *BitfieldWidth, - tok::ObjCKeywordKind visibility); - - // This is used for both record definitions and ObjC interface declarations. - void ActOnFields(Scope* S, SourceLocation RecLoc, Decl *TagDecl, - ArrayRef<Decl *> Fields, - SourceLocation LBrac, SourceLocation RBrac, - AttributeList *AttrList); - - /// ActOnTagStartDefinition - Invoked when we have entered the - /// scope of a tag's definition (e.g., for an enumeration, class, - /// struct, or union). - void ActOnTagStartDefinition(Scope *S, Decl *TagDecl); - - typedef void *SkippedDefinitionContext; - - /// \brief Invoked when we enter a tag definition that we're skipping. - SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD); - - Decl *ActOnObjCContainerStartDefinition(Decl *IDecl); - - /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a - /// C++ record definition's base-specifiers clause and are starting its - /// member declarations. - void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, - SourceLocation FinalLoc, - bool IsFinalSpelledSealed, - SourceLocation LBraceLoc); - - /// ActOnTagFinishDefinition - Invoked once we have finished parsing - /// the definition of a tag (enumeration, class, struct, or union). - void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, - SourceLocation RBraceLoc); - - void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context); - - void ActOnObjCContainerFinishDefinition(); - - /// \brief Invoked when we must temporarily exit the objective-c container - /// scope for parsing/looking-up C constructs. - /// - /// Must be followed by a call to \see ActOnObjCReenterContainerContext - void ActOnObjCTemporaryExitContainerContext(DeclContext *DC); - void ActOnObjCReenterContainerContext(DeclContext *DC); - - /// ActOnTagDefinitionError - Invoked when there was an unrecoverable - /// error parsing the definition of a tag. - void ActOnTagDefinitionError(Scope *S, Decl *TagDecl); - - EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum, - EnumConstantDecl *LastEnumConst, - SourceLocation IdLoc, - IdentifierInfo *Id, - Expr *val); - bool CheckEnumUnderlyingType(TypeSourceInfo *TI); - bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, - QualType EnumUnderlyingTy, - bool EnumUnderlyingIsImplicit, - const EnumDecl *Prev); - - /// Determine whether the body of an anonymous enumeration should be skipped. - /// \param II The name of the first enumerator. - SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, - SourceLocation IILoc); - - Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, - SourceLocation IdLoc, IdentifierInfo *Id, - AttributeList *Attrs, - SourceLocation EqualLoc, Expr *Val); - void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, - SourceLocation RBraceLoc, Decl *EnumDecl, - ArrayRef<Decl *> Elements, - Scope *S, AttributeList *Attr); - - DeclContext *getContainingDC(DeclContext *DC); - - /// Set the current declaration context until it gets popped. - void PushDeclContext(Scope *S, DeclContext *DC); - void PopDeclContext(); - - /// EnterDeclaratorContext - Used when we must lookup names in the context - /// of a declarator's nested name specifier. - void EnterDeclaratorContext(Scope *S, DeclContext *DC); - void ExitDeclaratorContext(Scope *S); - - /// Push the parameters of D, which must be a function, into scope. - void ActOnReenterFunctionContext(Scope* S, Decl* D); - void ActOnExitFunctionContext(); - - DeclContext *getFunctionLevelDeclContext(); - - /// getCurFunctionDecl - If inside of a function body, this returns a pointer - /// to the function decl for the function being parsed. If we're currently - /// in a 'block', this returns the containing context. - FunctionDecl *getCurFunctionDecl(); - - /// getCurMethodDecl - If inside of a method body, this returns a pointer to - /// the method decl for the method being parsed. If we're currently - /// in a 'block', this returns the containing context. - ObjCMethodDecl *getCurMethodDecl(); - - /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method - /// or C function we're in, otherwise return null. If we're currently - /// in a 'block', this returns the containing context. - NamedDecl *getCurFunctionOrMethodDecl(); - - /// Add this decl to the scope shadowed decl chains. - void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true); - - /// \brief Make the given externally-produced declaration visible at the - /// top level scope. - /// - /// \param D The externally-produced declaration to push. - /// - /// \param Name The name of the externally-produced declaration. - void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); - - /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true - /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns - /// true if 'D' belongs to the given declaration context. - /// - /// \param AllowInlineNamespace If \c true, allow the declaration to be in the - /// enclosing namespace set of the context, rather than contained - /// directly within it. - bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr, - bool AllowInlineNamespace = false); - - /// Finds the scope corresponding to the given decl context, if it - /// happens to be an enclosing scope. Otherwise return NULL. - static Scope *getScopeForDeclContext(Scope *S, DeclContext *DC); - - /// Subroutines of ActOnDeclarator(). - TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, - TypeSourceInfo *TInfo); - bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New); - - /// \brief Describes the kind of merge to perform for availability - /// attributes (including "deprecated", "unavailable", and "availability"). - enum AvailabilityMergeKind { - /// \brief Don't merge availability attributes at all. - AMK_None, - /// \brief Merge availability attributes for a redeclaration, which requires - /// an exact match. - AMK_Redeclaration, - /// \brief Merge availability attributes for an override, which requires - /// an exact match or a weakening of constraints. - AMK_Override, - /// \brief Merge availability attributes for an implementation of - /// a protocol requirement. - AMK_ProtocolImplementation, - }; - - /// Attribute merging methods. Return true if a new attribute was added. - AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, - IdentifierInfo *Platform, - VersionTuple Introduced, - VersionTuple Deprecated, - VersionTuple Obsoleted, - bool IsUnavailable, - StringRef Message, - AvailabilityMergeKind AMK, - unsigned AttrSpellingListIndex); - TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, - TypeVisibilityAttr::VisibilityType Vis, - unsigned AttrSpellingListIndex); - VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range, - VisibilityAttr::VisibilityType Vis, - unsigned AttrSpellingListIndex); - DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range, - unsigned AttrSpellingListIndex); - DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range, - unsigned AttrSpellingListIndex); - MSInheritanceAttr * - mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, - unsigned AttrSpellingListIndex, - MSInheritanceAttr::Spelling SemanticSpelling); - FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, - IdentifierInfo *Format, int FormatIdx, - int FirstArg, unsigned AttrSpellingListIndex); - SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name, - unsigned AttrSpellingListIndex); - AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, SourceRange Range, - IdentifierInfo *Ident, - unsigned AttrSpellingListIndex); - MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range, - unsigned AttrSpellingListIndex); - OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range, - unsigned AttrSpellingListIndex); - InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, SourceRange Range, - IdentifierInfo *Ident, - unsigned AttrSpellingListIndex); - CommonAttr *mergeCommonAttr(Decl *D, SourceRange Range, IdentifierInfo *Ident, - unsigned AttrSpellingListIndex); - - void mergeDeclAttributes(NamedDecl *New, Decl *Old, - AvailabilityMergeKind AMK = AMK_Redeclaration); - void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New, - LookupResult &OldDecls); - bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S, - bool MergeTypeWithOld); - bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, - Scope *S, bool MergeTypeWithOld); - void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old); - void MergeVarDecl(VarDecl *New, LookupResult &Previous); - void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld); - void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); - bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S); - - // AssignmentAction - This is used by all the assignment diagnostic functions - // to represent what is actually causing the operation - enum AssignmentAction { - AA_Assigning, - AA_Passing, - AA_Returning, - AA_Converting, - AA_Initializing, - AA_Sending, - AA_Casting, - AA_Passing_CFAudited - }; - - /// C++ Overloading. - enum OverloadKind { - /// This is a legitimate overload: the existing declarations are - /// functions or function templates with different signatures. - Ovl_Overload, - - /// This is not an overload because the signature exactly matches - /// an existing declaration. - Ovl_Match, - - /// This is not an overload because the lookup results contain a - /// non-function. - Ovl_NonFunction - }; - OverloadKind CheckOverload(Scope *S, - FunctionDecl *New, - const LookupResult &OldDecls, - NamedDecl *&OldDecl, - bool IsForUsingDecl); - bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl); - - /// \brief Checks availability of the function depending on the current - /// function context.Inside an unavailable function,unavailability is ignored. - /// - /// \returns true if \p FD is unavailable and current context is inside - /// an available function, false otherwise. - bool isFunctionConsideredUnavailable(FunctionDecl *FD); - - ImplicitConversionSequence - TryImplicitConversion(Expr *From, QualType ToType, - bool SuppressUserConversions, - bool AllowExplicit, - bool InOverloadResolution, - bool CStyle, - bool AllowObjCWritebackConversion); - - bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType); - bool IsFloatingPointPromotion(QualType FromType, QualType ToType); - bool IsComplexPromotion(QualType FromType, QualType ToType); - bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType, - bool InOverloadResolution, - QualType& ConvertedType, bool &IncompatibleObjC); - bool isObjCPointerConversion(QualType FromType, QualType ToType, - QualType& ConvertedType, bool &IncompatibleObjC); - bool isObjCWritebackConversion(QualType FromType, QualType ToType, - QualType &ConvertedType); - bool IsBlockPointerConversion(QualType FromType, QualType ToType, - QualType& ConvertedType); - bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType, - const FunctionProtoType *NewType, - unsigned *ArgPos = nullptr); - void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, - QualType FromType, QualType ToType); - - void maybeExtendBlockObject(ExprResult &E); - CastKind PrepareCastToObjCObjectPointer(ExprResult &E); - bool CheckPointerConversion(Expr *From, QualType ToType, - CastKind &Kind, - CXXCastPath& BasePath, - bool IgnoreBaseAccess); - bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, - bool InOverloadResolution, - QualType &ConvertedType); - bool CheckMemberPointerConversion(Expr *From, QualType ToType, - CastKind &Kind, - CXXCastPath &BasePath, - bool IgnoreBaseAccess); - bool IsQualificationConversion(QualType FromType, QualType ToType, - bool CStyle, bool &ObjCLifetimeConversion); - bool IsNoReturnConversion(QualType FromType, QualType ToType, - QualType &ResultTy); - bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); - bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg); - - ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, - const VarDecl *NRVOCandidate, - QualType ResultType, - Expr *Value, - bool AllowNRVO = true); - - bool CanPerformCopyInitialization(const InitializedEntity &Entity, - ExprResult Init); - ExprResult PerformCopyInitialization(const InitializedEntity &Entity, - SourceLocation EqualLoc, - ExprResult Init, - bool TopLevelOfInitList = false, - bool AllowExplicit = false); - ExprResult PerformObjectArgumentInitialization(Expr *From, - NestedNameSpecifier *Qualifier, - NamedDecl *FoundDecl, - CXXMethodDecl *Method); - - ExprResult PerformContextuallyConvertToBool(Expr *From); - ExprResult PerformContextuallyConvertToObjCPointer(Expr *From); - - /// Contexts in which a converted constant expression is required. - enum CCEKind { - CCEK_CaseValue, ///< Expression in a case label. - CCEK_Enumerator, ///< Enumerator value with fixed underlying type. - CCEK_TemplateArg, ///< Value of a non-type template parameter. - CCEK_NewExpr ///< Constant expression in a noptr-new-declarator. - }; - ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, - llvm::APSInt &Value, CCEKind CCE); - ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, - APValue &Value, CCEKind CCE); - - /// \brief Abstract base class used to perform a contextual implicit - /// conversion from an expression to any type passing a filter. - class ContextualImplicitConverter { - public: - bool Suppress; - bool SuppressConversion; - - ContextualImplicitConverter(bool Suppress = false, - bool SuppressConversion = false) - : Suppress(Suppress), SuppressConversion(SuppressConversion) {} - - /// \brief Determine whether the specified type is a valid destination type - /// for this conversion. - virtual bool match(QualType T) = 0; - - /// \brief Emits a diagnostic complaining that the expression does not have - /// integral or enumeration type. - virtual SemaDiagnosticBuilder - diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0; - - /// \brief Emits a diagnostic when the expression has incomplete class type. - virtual SemaDiagnosticBuilder - diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0; - - /// \brief Emits a diagnostic when the only matching conversion function - /// is explicit. - virtual SemaDiagnosticBuilder diagnoseExplicitConv( - Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; - - /// \brief Emits a note for the explicit conversion function. - virtual SemaDiagnosticBuilder - noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; - - /// \brief Emits a diagnostic when there are multiple possible conversion - /// functions. - virtual SemaDiagnosticBuilder - diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0; - - /// \brief Emits a note for one of the candidate conversions. - virtual SemaDiagnosticBuilder - noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; - - /// \brief Emits a diagnostic when we picked a conversion function - /// (for cases when we are not allowed to pick a conversion function). - virtual SemaDiagnosticBuilder diagnoseConversion( - Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; - - virtual ~ContextualImplicitConverter() {} - }; - - class ICEConvertDiagnoser : public ContextualImplicitConverter { - bool AllowScopedEnumerations; - - public: - ICEConvertDiagnoser(bool AllowScopedEnumerations, - bool Suppress, bool SuppressConversion) - : ContextualImplicitConverter(Suppress, SuppressConversion), - AllowScopedEnumerations(AllowScopedEnumerations) {} - - /// Match an integral or (possibly scoped) enumeration type. - bool match(QualType T) override; - - SemaDiagnosticBuilder - diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override { - return diagnoseNotInt(S, Loc, T); - } - - /// \brief Emits a diagnostic complaining that the expression does not have - /// integral or enumeration type. - virtual SemaDiagnosticBuilder - diagnoseNotInt(Sema &S, SourceLocation Loc, QualType T) = 0; - }; - - /// Perform a contextual implicit conversion. - ExprResult PerformContextualImplicitConversion( - SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter); - - - enum ObjCSubscriptKind { - OS_Array, - OS_Dictionary, - OS_Error - }; - ObjCSubscriptKind CheckSubscriptingKind(Expr *FromE); - - // Note that LK_String is intentionally after the other literals, as - // this is used for diagnostics logic. - enum ObjCLiteralKind { - LK_Array, - LK_Dictionary, - LK_Numeric, - LK_Boxed, - LK_String, - LK_Block, - LK_None - }; - ObjCLiteralKind CheckLiteralKind(Expr *FromE); - - ExprResult PerformObjectMemberConversion(Expr *From, - NestedNameSpecifier *Qualifier, - NamedDecl *FoundDecl, - NamedDecl *Member); - - // Members have to be NamespaceDecl* or TranslationUnitDecl*. - // TODO: make this is a typesafe union. - typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet; - typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet; - - void AddOverloadCandidate(FunctionDecl *Function, - DeclAccessPair FoundDecl, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false, - bool PartialOverloading = false, - bool AllowExplicit = false); - void AddFunctionCandidates(const UnresolvedSetImpl &Functions, - ArrayRef<Expr *> Args, - OverloadCandidateSet &CandidateSet, - TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, - bool SuppressUserConversions = false, - bool PartialOverloading = false); - void AddMethodCandidate(DeclAccessPair FoundDecl, - QualType ObjectType, - Expr::Classification ObjectClassification, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool SuppressUserConversion = false); - void AddMethodCandidate(CXXMethodDecl *Method, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, QualType ObjectType, - Expr::Classification ObjectClassification, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false, - bool PartialOverloading = false); - void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - TemplateArgumentListInfo *ExplicitTemplateArgs, - QualType ObjectType, - Expr::Classification ObjectClassification, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false, - bool PartialOverloading = false); - void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, - DeclAccessPair FoundDecl, - TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false, - bool PartialOverloading = false); - void AddConversionCandidate(CXXConversionDecl *Conversion, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet& CandidateSet, - bool AllowObjCConversionOnExplicit); - void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - Expr *From, QualType ToType, - OverloadCandidateSet &CandidateSet, - bool AllowObjCConversionOnExplicit); - void AddSurrogateCandidate(CXXConversionDecl *Conversion, - DeclAccessPair FoundDecl, - CXXRecordDecl *ActingContext, - const FunctionProtoType *Proto, - Expr *Object, ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet); - void AddMemberOperatorCandidates(OverloadedOperatorKind Op, - SourceLocation OpLoc, ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - SourceRange OpRange = SourceRange()); - void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool IsAssignmentOperator = false, - unsigned NumContextualBoolArguments = 0); - void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, - SourceLocation OpLoc, ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet); - void AddArgumentDependentLookupCandidates(DeclarationName Name, - SourceLocation Loc, - ArrayRef<Expr *> Args, - TemplateArgumentListInfo *ExplicitTemplateArgs, - OverloadCandidateSet& CandidateSet, - bool PartialOverloading = false); - - // Emit as a 'note' the specific overload candidate - void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(), - bool TakingAddress = false); - - // Emit as a series of 'note's all template and non-templates identified by - // the expression Expr - void NoteAllOverloadCandidates(Expr *E, QualType DestType = QualType(), - bool TakingAddress = false); - - /// Check the enable_if expressions on the given function. Returns the first - /// failing attribute, or NULL if they were all successful. - EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, - bool MissingImplicitThis = false); - - /// Returns whether the given function's address can be taken or not, - /// optionally emitting a diagnostic if the address can't be taken. - /// - /// Returns false if taking the address of the function is illegal. - bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, - bool Complain = false, - SourceLocation Loc = SourceLocation()); - - // [PossiblyAFunctionType] --> [Return] - // NonFunctionType --> NonFunctionType - // R (A) --> R(A) - // R (*)(A) --> R (A) - // R (&)(A) --> R (A) - // R (S::*)(A) --> R (A) - QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType); - - FunctionDecl * - ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, - QualType TargetType, - bool Complain, - DeclAccessPair &Found, - bool *pHadMultipleCandidates = nullptr); - - FunctionDecl * - ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, - bool Complain = false, - DeclAccessPair *Found = nullptr); - - bool ResolveAndFixSingleFunctionTemplateSpecialization( - ExprResult &SrcExpr, - bool DoFunctionPointerConverion = false, - bool Complain = false, - SourceRange OpRangeForComplaining = SourceRange(), - QualType DestTypeForComplaining = QualType(), - unsigned DiagIDForComplaining = 0); - - - Expr *FixOverloadedFunctionReference(Expr *E, - DeclAccessPair FoundDecl, - FunctionDecl *Fn); - ExprResult FixOverloadedFunctionReference(ExprResult, - DeclAccessPair FoundDecl, - FunctionDecl *Fn); - - void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, - ArrayRef<Expr *> Args, - OverloadCandidateSet &CandidateSet, - bool PartialOverloading = false); - - // An enum used to represent the different possible results of building a - // range-based for loop. - enum ForRangeStatus { - FRS_Success, - FRS_NoViableFunction, - FRS_DiagnosticIssued - }; - - ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, - SourceLocation RangeLoc, - const DeclarationNameInfo &NameInfo, - LookupResult &MemberLookup, - OverloadCandidateSet *CandidateSet, - Expr *Range, ExprResult *CallExpr); - - ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn, - UnresolvedLookupExpr *ULE, - SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation RParenLoc, - Expr *ExecConfig, - bool AllowTypoCorrection=true); - - bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, - MultiExprArg Args, SourceLocation RParenLoc, - OverloadCandidateSet *CandidateSet, - ExprResult *Result); - - ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, - UnaryOperatorKind Opc, - const UnresolvedSetImpl &Fns, - Expr *input); - - ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, - BinaryOperatorKind Opc, - const UnresolvedSetImpl &Fns, - Expr *LHS, Expr *RHS); - - ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, - SourceLocation RLoc, - Expr *Base,Expr *Idx); - - ExprResult - BuildCallToMemberFunction(Scope *S, Expr *MemExpr, - SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation RParenLoc); - ExprResult - BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation RParenLoc); - - ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - bool *NoArrowOperatorFound = nullptr); - - /// CheckCallReturnType - Checks that a call expression's return type is - /// complete. Returns true on failure. The location passed in is the location - /// that best represents the call. - bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc, - CallExpr *CE, FunctionDecl *FD); - - /// Helpers for dealing with blocks and functions. - bool CheckParmsForFunctionDef(ParmVarDecl *const *Param, - ParmVarDecl *const *ParamEnd, - bool CheckParameterNames); - void CheckCXXDefaultArguments(FunctionDecl *FD); - void CheckExtraCXXDefaultArguments(Declarator &D); - Scope *getNonFieldDeclScope(Scope *S); - - /// \name Name lookup - /// - /// These routines provide name lookup that is used during semantic - /// analysis to resolve the various kinds of names (identifiers, - /// overloaded operator names, constructor names, etc.) into zero or - /// more declarations within a particular scope. The major entry - /// points are LookupName, which performs unqualified name lookup, - /// and LookupQualifiedName, which performs qualified name lookup. - /// - /// All name lookup is performed based on some specific criteria, - /// which specify what names will be visible to name lookup and how - /// far name lookup should work. These criteria are important both - /// for capturing language semantics (certain lookups will ignore - /// certain names, for example) and for performance, since name - /// lookup is often a bottleneck in the compilation of C++. Name - /// lookup criteria is specified via the LookupCriteria enumeration. - /// - /// The results of name lookup can vary based on the kind of name - /// lookup performed, the current language, and the translation - /// unit. In C, for example, name lookup will either return nothing - /// (no entity found) or a single declaration. In C++, name lookup - /// can additionally refer to a set of overloaded functions or - /// result in an ambiguity. All of the possible results of name - /// lookup are captured by the LookupResult class, which provides - /// the ability to distinguish among them. - //@{ - - /// @brief Describes the kind of name lookup to perform. - enum LookupNameKind { - /// Ordinary name lookup, which finds ordinary names (functions, - /// variables, typedefs, etc.) in C and most kinds of names - /// (functions, variables, members, types, etc.) in C++. - LookupOrdinaryName = 0, - /// Tag name lookup, which finds the names of enums, classes, - /// structs, and unions. - LookupTagName, - /// Label name lookup. - LookupLabel, - /// Member name lookup, which finds the names of - /// class/struct/union members. - LookupMemberName, - /// Look up of an operator name (e.g., operator+) for use with - /// operator overloading. This lookup is similar to ordinary name - /// lookup, but will ignore any declarations that are class members. - LookupOperatorName, - /// Look up of a name that precedes the '::' scope resolution - /// operator in C++. This lookup completely ignores operator, object, - /// function, and enumerator names (C++ [basic.lookup.qual]p1). - LookupNestedNameSpecifierName, - /// Look up a namespace name within a C++ using directive or - /// namespace alias definition, ignoring non-namespace names (C++ - /// [basic.lookup.udir]p1). - LookupNamespaceName, - /// Look up all declarations in a scope with the given name, - /// including resolved using declarations. This is appropriate - /// for checking redeclarations for a using declaration. - LookupUsingDeclName, - /// Look up an ordinary name that is going to be redeclared as a - /// name with linkage. This lookup ignores any declarations that - /// are outside of the current scope unless they have linkage. See - /// C99 6.2.2p4-5 and C++ [basic.link]p6. - LookupRedeclarationWithLinkage, - /// Look up a friend of a local class. This lookup does not look - /// outside the innermost non-class scope. See C++11 [class.friend]p11. - LookupLocalFriendName, - /// Look up the name of an Objective-C protocol. - LookupObjCProtocolName, - /// Look up implicit 'self' parameter of an objective-c method. - LookupObjCImplicitSelfParam, - /// \brief Look up any declaration with any name. - LookupAnyName - }; - - /// \brief Specifies whether (or how) name lookup is being performed for a - /// redeclaration (vs. a reference). - enum RedeclarationKind { - /// \brief The lookup is a reference to this name that is not for the - /// purpose of redeclaring the name. - NotForRedeclaration = 0, - /// \brief The lookup results will be used for redeclaration of a name, - /// if an entity by that name already exists. - ForRedeclaration - }; - - /// \brief The possible outcomes of name lookup for a literal operator. - enum LiteralOperatorLookupResult { - /// \brief The lookup resulted in an error. - LOLR_Error, - /// \brief The lookup found a single 'cooked' literal operator, which - /// expects a normal literal to be built and passed to it. - LOLR_Cooked, - /// \brief The lookup found a single 'raw' literal operator, which expects - /// a string literal containing the spelling of the literal token. - LOLR_Raw, - /// \brief The lookup found an overload set of literal operator templates, - /// which expect the characters of the spelling of the literal token to be - /// passed as a non-type template argument pack. - LOLR_Template, - /// \brief The lookup found an overload set of literal operator templates, - /// which expect the character type and characters of the spelling of the - /// string literal token to be passed as template arguments. - LOLR_StringTemplate - }; - - SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D, - CXXSpecialMember SM, - bool ConstArg, - bool VolatileArg, - bool RValueThis, - bool ConstThis, - bool VolatileThis); - - typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator; - typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)> - TypoRecoveryCallback; - -private: - bool CppLookupName(LookupResult &R, Scope *S); - - struct TypoExprState { - std::unique_ptr<TypoCorrectionConsumer> Consumer; - TypoDiagnosticGenerator DiagHandler; - TypoRecoveryCallback RecoveryHandler; - TypoExprState(); - TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT; - TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT; - }; - - /// \brief The set of unhandled TypoExprs and their associated state. - llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos; - - /// \brief Creates a new TypoExpr AST node. - TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, - TypoDiagnosticGenerator TDG, - TypoRecoveryCallback TRC); - - // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls. - // - // The boolean value will be true to indicate that the namespace was loaded - // from an AST/PCH file, or false otherwise. - llvm::MapVector<NamespaceDecl*, bool> KnownNamespaces; - - /// \brief Whether we have already loaded known namespaces from an extenal - /// source. - bool LoadedExternalKnownNamespaces; - - /// \brief Helper for CorrectTypo and CorrectTypoDelayed used to create and - /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction - /// should be skipped entirely. - std::unique_ptr<TypoCorrectionConsumer> - makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, - Sema::LookupNameKind LookupKind, Scope *S, - CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, - DeclContext *MemberContext, bool EnteringContext, - const ObjCObjectPointerType *OPT, - bool ErrorRecovery); - -public: - const TypoExprState &getTypoExprState(TypoExpr *TE) const; - - /// \brief Clears the state of the given TypoExpr. - void clearDelayedTypo(TypoExpr *TE); - - /// \brief Look up a name, looking for a single declaration. Return - /// null if the results were absent, ambiguous, or overloaded. - /// - /// It is preferable to use the elaborated form and explicitly handle - /// ambiguity and overloaded. - NamedDecl *LookupSingleName(Scope *S, DeclarationName Name, - SourceLocation Loc, - LookupNameKind NameKind, - RedeclarationKind Redecl - = NotForRedeclaration); - bool LookupName(LookupResult &R, Scope *S, - bool AllowBuiltinCreation = false); - bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, - bool InUnqualifiedLookup = false); - bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, - CXXScopeSpec &SS); - bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, - bool AllowBuiltinCreation = false, - bool EnteringContext = false); - ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, - RedeclarationKind Redecl - = NotForRedeclaration); - bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class); - - void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, - QualType T1, QualType T2, - UnresolvedSetImpl &Functions); - void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions, - DeclAccessPair Operator, - QualType T1, QualType T2); - - LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, - SourceLocation GnuLabelLoc = SourceLocation()); - - DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); - CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); - CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class, - unsigned Quals); - CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, - bool RValueThis, unsigned ThisQuals); - CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class, - unsigned Quals); - CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, - bool RValueThis, unsigned ThisQuals); - CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); - - bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id); - LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, - ArrayRef<QualType> ArgTys, - bool AllowRaw, - bool AllowTemplate, - bool AllowStringTemplate); - bool isKnownName(StringRef name); - - void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, - ArrayRef<Expr *> Args, ADLResult &Functions); - - void LookupVisibleDecls(Scope *S, LookupNameKind Kind, - VisibleDeclConsumer &Consumer, - bool IncludeGlobalScope = true); - void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, - VisibleDeclConsumer &Consumer, - bool IncludeGlobalScope = true); - - enum CorrectTypoKind { - CTK_NonError, // CorrectTypo used in a non error recovery situation. - CTK_ErrorRecovery // CorrectTypo used in normal error recovery. - }; - - TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, - Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, - CorrectTypoKind Mode, - DeclContext *MemberContext = nullptr, - bool EnteringContext = false, - const ObjCObjectPointerType *OPT = nullptr, - bool RecordFailure = true); - - TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, - Sema::LookupNameKind LookupKind, Scope *S, - CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, - TypoDiagnosticGenerator TDG, - TypoRecoveryCallback TRC, CorrectTypoKind Mode, - DeclContext *MemberContext = nullptr, - bool EnteringContext = false, - const ObjCObjectPointerType *OPT = nullptr); - - /// \brief Process any TypoExprs in the given Expr and its children, - /// generating diagnostics as appropriate and returning a new Expr if there - /// were typos that were all successfully corrected and ExprError if one or - /// more typos could not be corrected. - /// - /// \param E The Expr to check for TypoExprs. - /// - /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its - /// initializer. - /// - /// \param Filter A function applied to a newly rebuilt Expr to determine if - /// it is an acceptable/usable result from a single combination of typo - /// corrections. As long as the filter returns ExprError, different - /// combinations of corrections will be tried until all are exhausted. - ExprResult - CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl = nullptr, - llvm::function_ref<ExprResult(Expr *)> Filter = - [](Expr *E) -> ExprResult { return E; }); - - ExprResult - CorrectDelayedTyposInExpr(Expr *E, - llvm::function_ref<ExprResult(Expr *)> Filter) { - return CorrectDelayedTyposInExpr(E, nullptr, Filter); - } - - ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, VarDecl *InitDecl = nullptr, - llvm::function_ref<ExprResult(Expr *)> Filter = - [](Expr *E) -> ExprResult { return E; }) { - return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter); - } - - ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, - llvm::function_ref<ExprResult(Expr *)> Filter) { - return CorrectDelayedTyposInExpr(ER, nullptr, Filter); - } - - void diagnoseTypo(const TypoCorrection &Correction, - const PartialDiagnostic &TypoDiag, - bool ErrorRecovery = true); - - void diagnoseTypo(const TypoCorrection &Correction, - const PartialDiagnostic &TypoDiag, - const PartialDiagnostic &PrevNote, - bool ErrorRecovery = true); - - void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, - ArrayRef<Expr *> Args, - AssociatedNamespaceSet &AssociatedNamespaces, - AssociatedClassSet &AssociatedClasses); - - void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, - bool ConsiderLinkage, bool AllowInlineNamespace); - - void DiagnoseAmbiguousLookup(LookupResult &Result); - //@} - - ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id, - SourceLocation IdLoc, - bool TypoCorrection = false); - NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, - Scope *S, bool ForRedeclaration, - SourceLocation Loc); - NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, - Scope *S); - void AddKnownFunctionAttributes(FunctionDecl *FD); - - // More parsing and symbol table subroutines. - - void ProcessPragmaWeak(Scope *S, Decl *D); - // Decl attributes - this routine is the top level dispatcher. - void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); - void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, - bool IncludeCXX11Attributes = true); - bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, - const AttributeList *AttrList); - - void checkUnusedDeclAttributes(Declarator &D); - - /// Determine if type T is a valid subject for a nonnull and similar - /// attributes. By default, we look through references (the behavior used by - /// nonnull), but if the second parameter is true, then we treat a reference - /// type as valid. - bool isValidPointerAttrType(QualType T, bool RefOkay = false); - - bool CheckRegparmAttr(const AttributeList &attr, unsigned &value); - bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, - const FunctionDecl *FD = nullptr); - bool CheckNoReturnAttr(const AttributeList &attr); - bool checkStringLiteralArgumentAttr(const AttributeList &Attr, - unsigned ArgNum, StringRef &Str, - SourceLocation *ArgLocation = nullptr); - bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); - void checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); - bool checkMSInheritanceAttrOnDefinition( - CXXRecordDecl *RD, SourceRange Range, bool BestCase, - MSInheritanceAttr::Spelling SemanticSpelling); - - void CheckAlignasUnderalignment(Decl *D); - - /// Adjust the calling convention of a method to be the ABI default if it - /// wasn't specified explicitly. This handles method types formed from - /// function type typedefs and typename template arguments. - void adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor, - SourceLocation Loc); - - // Check if there is an explicit attribute, but only look through parens. - // The intent is to look for an attribute on the current declarator, but not - // one that came from a typedef. - bool hasExplicitCallingConv(QualType &T); - - /// Get the outermost AttributedType node that sets a calling convention. - /// Valid types should not have multiple attributes with different CCs. - const AttributedType *getCallingConvAttributedType(QualType T) const; - - /// Check whether a nullability type specifier can be added to the given - /// type. - /// - /// \param type The type to which the nullability specifier will be - /// added. On success, this type will be updated appropriately. - /// - /// \param nullability The nullability specifier to add. - /// - /// \param nullabilityLoc The location of the nullability specifier. - /// - /// \param isContextSensitive Whether this nullability specifier was - /// written as a context-sensitive keyword (in an Objective-C - /// method) or an Objective-C property attribute, rather than as an - /// underscored type specifier. - /// - /// \returns true if nullability cannot be applied, false otherwise. - bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability, - SourceLocation nullabilityLoc, - bool isContextSensitive); - - /// \brief Stmt attributes - this routine is the top level dispatcher. - StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs, - SourceRange Range); - - void WarnConflictingTypedMethods(ObjCMethodDecl *Method, - ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl); - - void CheckConflictingOverridingMethod(ObjCMethodDecl *Method, - ObjCMethodDecl *Overridden, - bool IsProtocolMethodDecl); - - /// WarnExactTypedMethods - This routine issues a warning if method - /// implementation declaration matches exactly that of its declaration. - void WarnExactTypedMethods(ObjCMethodDecl *Method, - ObjCMethodDecl *MethodDecl, - bool IsProtocolMethodDecl); - - typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; - typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap; - - /// CheckImplementationIvars - This routine checks if the instance variables - /// listed in the implelementation match those listed in the interface. - void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl, - ObjCIvarDecl **Fields, unsigned nIvars, - SourceLocation Loc); - - /// ImplMethodsVsClassMethods - This is main routine to warn if any method - /// remains unimplemented in the class or category \@implementation. - void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, - ObjCContainerDecl* IDecl, - bool IncompleteImpl = false); - - /// DiagnoseUnimplementedProperties - This routine warns on those properties - /// which must be implemented by this implementation. - void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, - ObjCContainerDecl *CDecl, - bool SynthesizeProperties); - - /// Diagnose any null-resettable synthesized setters. - void diagnoseNullResettableSynthesizedSetters(const ObjCImplDecl *impDecl); - - /// DefaultSynthesizeProperties - This routine default synthesizes all - /// properties which must be synthesized in the class's \@implementation. - void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, - ObjCInterfaceDecl *IDecl); - void DefaultSynthesizeProperties(Scope *S, Decl *D); - - /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is - /// an ivar synthesized for 'Method' and 'Method' is a property accessor - /// declared in class 'IFace'. - bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, - ObjCMethodDecl *Method, ObjCIvarDecl *IV); - - /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which - /// backs the property is not used in the property's accessor. - void DiagnoseUnusedBackingIvarInAccessor(Scope *S, - const ObjCImplementationDecl *ImplD); - - /// GetIvarBackingPropertyAccessor - If method is a property setter/getter and - /// it property has a backing ivar, returns this ivar; otherwise, returns NULL. - /// It also returns ivar's property on success. - ObjCIvarDecl *GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method, - const ObjCPropertyDecl *&PDecl) const; - - /// Called by ActOnProperty to handle \@property declarations in - /// class extensions. - ObjCPropertyDecl *HandlePropertyInClassExtension(Scope *S, - SourceLocation AtLoc, - SourceLocation LParenLoc, - FieldDeclarator &FD, - Selector GetterSel, - Selector SetterSel, - const bool isReadWrite, - unsigned &Attributes, - const unsigned AttributesAsWritten, - QualType T, - TypeSourceInfo *TSI, - tok::ObjCKeywordKind MethodImplKind); - - /// Called by ActOnProperty and HandlePropertyInClassExtension to - /// handle creating the ObjcPropertyDecl for a category or \@interface. - ObjCPropertyDecl *CreatePropertyDecl(Scope *S, - ObjCContainerDecl *CDecl, - SourceLocation AtLoc, - SourceLocation LParenLoc, - FieldDeclarator &FD, - Selector GetterSel, - Selector SetterSel, - const bool isReadWrite, - const unsigned Attributes, - const unsigned AttributesAsWritten, - QualType T, - TypeSourceInfo *TSI, - tok::ObjCKeywordKind MethodImplKind, - DeclContext *lexicalDC = nullptr); - - /// AtomicPropertySetterGetterRules - This routine enforces the rule (via - /// warning) when atomic property has one but not the other user-declared - /// setter or getter. - void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl, - ObjCInterfaceDecl* IDecl); - - void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); - - void DiagnoseMissingDesignatedInitOverrides( - const ObjCImplementationDecl *ImplD, - const ObjCInterfaceDecl *IFD); - - void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID); - - enum MethodMatchStrategy { - MMS_loose, - MMS_strict - }; - - /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns - /// true, or false, accordingly. - bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, - const ObjCMethodDecl *PrevMethod, - MethodMatchStrategy strategy = MMS_strict); - - /// MatchAllMethodDeclarations - Check methods declaraed in interface or - /// or protocol against those declared in their implementations. - void MatchAllMethodDeclarations(const SelectorSet &InsMap, - const SelectorSet &ClsMap, - SelectorSet &InsMapSeen, - SelectorSet &ClsMapSeen, - ObjCImplDecl* IMPDecl, - ObjCContainerDecl* IDecl, - bool &IncompleteImpl, - bool ImmediateClass, - bool WarnCategoryMethodImpl=false); - - /// CheckCategoryVsClassMethodMatches - Checks that methods implemented in - /// category matches with those implemented in its primary class and - /// warns each time an exact match is found. - void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); - - /// \brief Add the given method to the list of globally-known methods. - void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); - -private: - /// AddMethodToGlobalPool - Add an instance or factory method to the global - /// pool. See descriptoin of AddInstanceMethodToGlobalPool. - void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); - - /// LookupMethodInGlobalPool - Returns the instance or factory method and - /// optionally warns if there are multiple signatures. - ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass, - bool instance); - -public: - /// \brief - Returns instance or factory methods in global method pool for - /// given selector. If no such method or only one method found, function returns - /// false; otherwise, it returns true - bool CollectMultipleMethodsInGlobalPool(Selector Sel, - SmallVectorImpl<ObjCMethodDecl*>& Methods, - bool instance); - - bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, - SourceRange R, - bool receiverIdOrClass); - - void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, - Selector Sel, SourceRange R, - bool receiverIdOrClass); - -private: - /// \brief - Returns a selector which best matches given argument list or - /// nullptr if none could be found - ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, - bool IsInstance); - - - /// \brief Record the typo correction failure and return an empty correction. - TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, - bool RecordFailure = true) { - if (RecordFailure) - TypoCorrectionFailures[Typo].insert(TypoLoc); - return TypoCorrection(); - } - -public: - /// AddInstanceMethodToGlobalPool - All instance methods in a translation - /// unit are added to a global pool. This allows us to efficiently associate - /// a selector with a method declaraation for purposes of typechecking - /// messages sent to "id" (where the class of the object is unknown). - void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { - AddMethodToGlobalPool(Method, impl, /*instance*/true); - } - - /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. - void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { - AddMethodToGlobalPool(Method, impl, /*instance*/false); - } - - /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global - /// pool. - void AddAnyMethodToGlobalPool(Decl *D); - - /// LookupInstanceMethodInGlobalPool - Returns the method and warns if - /// there are multiple signatures. - ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass=false) { - return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, - /*instance*/true); - } - - /// LookupFactoryMethodInGlobalPool - Returns the method and warns if - /// there are multiple signatures. - ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass=false) { - return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, - /*instance*/false); - } - - const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel, - QualType ObjectType=QualType()); - /// LookupImplementedMethodInGlobalPool - Returns the method which has an - /// implementation. - ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); - - /// CollectIvarsToConstructOrDestruct - Collect those ivars which require - /// initialization. - void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, - SmallVectorImpl<ObjCIvarDecl*> &Ivars); - - //===--------------------------------------------------------------------===// - // Statement Parsing Callbacks: SemaStmt.cpp. -public: - class FullExprArg { - public: - FullExprArg(Sema &actions) : E(nullptr) { } - - ExprResult release() { - return E; - } - - Expr *get() const { return E; } - - Expr *operator->() { - return E; - } - - private: - // FIXME: No need to make the entire Sema class a friend when it's just - // Sema::MakeFullExpr that needs access to the constructor below. - friend class Sema; - - explicit FullExprArg(Expr *expr) : E(expr) {} - - Expr *E; - }; - - FullExprArg MakeFullExpr(Expr *Arg) { - return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); - } - FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { - return FullExprArg(ActOnFinishFullExpr(Arg, CC).get()); - } - FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) { - ExprResult FE = - ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), - /*DiscardedValue*/ true); - return FullExprArg(FE.get()); - } - - StmtResult ActOnExprStmt(ExprResult Arg); - StmtResult ActOnExprStmtError(); - - StmtResult ActOnNullStmt(SourceLocation SemiLoc, - bool HasLeadingEmptyMacro = false); - - void ActOnStartOfCompoundStmt(); - void ActOnFinishOfCompoundStmt(); - StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, - ArrayRef<Stmt *> Elts, bool isStmtExpr); - - /// \brief A RAII object to enter scope of a compound statement. - class CompoundScopeRAII { - public: - CompoundScopeRAII(Sema &S): S(S) { - S.ActOnStartOfCompoundStmt(); - } - - ~CompoundScopeRAII() { - S.ActOnFinishOfCompoundStmt(); - } - - private: - Sema &S; - }; - - /// An RAII helper that pops function a function scope on exit. - struct FunctionScopeRAII { - Sema &S; - bool Active; - FunctionScopeRAII(Sema &S) : S(S), Active(true) {} - ~FunctionScopeRAII() { - if (Active) - S.PopFunctionScopeInfo(); - } - void disable() { Active = false; } - }; - - StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, - SourceLocation StartLoc, - SourceLocation EndLoc); - void ActOnForEachDeclStmt(DeclGroupPtrTy Decl); - StmtResult ActOnForEachLValueExpr(Expr *E); - StmtResult ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal, - SourceLocation DotDotDotLoc, Expr *RHSVal, - SourceLocation ColonLoc); - void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt); - - StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, - SourceLocation ColonLoc, - Stmt *SubStmt, Scope *CurScope); - StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, - SourceLocation ColonLoc, Stmt *SubStmt); - - StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, - ArrayRef<const Attr*> Attrs, - Stmt *SubStmt); - - StmtResult ActOnIfStmt(SourceLocation IfLoc, - FullExprArg CondVal, Decl *CondVar, - Stmt *ThenVal, - SourceLocation ElseLoc, Stmt *ElseVal); - StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, - Expr *Cond, - Decl *CondVar); - StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, - Stmt *Switch, Stmt *Body); - StmtResult ActOnWhileStmt(SourceLocation WhileLoc, - FullExprArg Cond, - Decl *CondVar, Stmt *Body); - StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, - SourceLocation WhileLoc, - SourceLocation CondLParen, Expr *Cond, - SourceLocation CondRParen); - - StmtResult ActOnForStmt(SourceLocation ForLoc, - SourceLocation LParenLoc, - Stmt *First, FullExprArg Second, - Decl *SecondVar, - FullExprArg Third, - SourceLocation RParenLoc, - Stmt *Body); - ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, - Expr *collection); - StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, - Stmt *First, Expr *collection, - SourceLocation RParenLoc); - StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); - - enum BuildForRangeKind { - /// Initial building of a for-range statement. - BFRK_Build, - /// Instantiation or recovery rebuild of a for-range statement. Don't - /// attempt any typo-correction. - BFRK_Rebuild, - /// Determining whether a for-range statement could be built. Avoid any - /// unnecessary or irreversible actions. - BFRK_Check - }; - - StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, - SourceLocation CoawaitLoc, - Stmt *LoopVar, - SourceLocation ColonLoc, Expr *Collection, - SourceLocation RParenLoc, - BuildForRangeKind Kind); - StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, - SourceLocation CoawaitLoc, - SourceLocation ColonLoc, - Stmt *RangeDecl, Stmt *BeginEndDecl, - Expr *Cond, Expr *Inc, - Stmt *LoopVarDecl, - SourceLocation RParenLoc, - BuildForRangeKind Kind); - StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body); - - StmtResult ActOnGotoStmt(SourceLocation GotoLoc, - SourceLocation LabelLoc, - LabelDecl *TheDecl); - StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, - SourceLocation StarLoc, - Expr *DestExp); - StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope); - StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); - - void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, - CapturedRegionKind Kind, unsigned NumParams); - typedef std::pair<StringRef, QualType> CapturedParamNameType; - void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, - CapturedRegionKind Kind, - ArrayRef<CapturedParamNameType> Params); - StmtResult ActOnCapturedRegionEnd(Stmt *S); - void ActOnCapturedRegionError(); - RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, - SourceLocation Loc, - unsigned NumParams); - VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, - bool AllowFunctionParameters); - bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, - bool AllowFunctionParameters); - - StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, - Scope *CurScope); - StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); - StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); - - StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, - bool IsVolatile, unsigned NumOutputs, - unsigned NumInputs, IdentifierInfo **Names, - MultiExprArg Constraints, MultiExprArg Exprs, - Expr *AsmString, MultiExprArg Clobbers, - SourceLocation RParenLoc); - - ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Id, - llvm::InlineAsmIdentifierInfo &Info, - bool IsUnevaluatedContext); - bool LookupInlineAsmField(StringRef Base, StringRef Member, - unsigned &Offset, SourceLocation AsmLoc); - ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, - llvm::InlineAsmIdentifierInfo &Info, - SourceLocation AsmLoc); - StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, - ArrayRef<Token> AsmToks, - StringRef AsmString, - unsigned NumOutputs, unsigned NumInputs, - ArrayRef<StringRef> Constraints, - ArrayRef<StringRef> Clobbers, - ArrayRef<Expr*> Exprs, - SourceLocation EndLoc); - LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName, - SourceLocation Location, - bool AlwaysCreate); - - VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, - SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - bool Invalid = false); - - Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D); - - StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, - Decl *Parm, Stmt *Body); - - StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body); - - StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, - MultiStmtArg Catch, Stmt *Finally); - - StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw); - StmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, - Scope *CurScope); - ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, - Expr *operand); - StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, - Expr *SynchExpr, - Stmt *SynchBody); - - StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body); - - VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, - SourceLocation StartLoc, - SourceLocation IdLoc, - IdentifierInfo *Id); - - Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D); - - StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, - Decl *ExDecl, Stmt *HandlerBlock); - StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, - ArrayRef<Stmt *> Handlers); - - StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? - SourceLocation TryLoc, Stmt *TryBlock, - Stmt *Handler); - StmtResult ActOnSEHExceptBlock(SourceLocation Loc, - Expr *FilterExpr, - Stmt *Block); - void ActOnStartSEHFinallyBlock(); - void ActOnAbortSEHFinallyBlock(); - StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block); - StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); - - void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); - - bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const; - - /// \brief If it's a file scoped decl that must warn if not used, keep track - /// of it. - void MarkUnusedFileScopedDecl(const DeclaratorDecl *D); - - /// DiagnoseUnusedExprResult - If the statement passed in is an expression - /// whose result is unused, warn. - void DiagnoseUnusedExprResult(const Stmt *S); - void DiagnoseUnusedNestedTypedefs(const RecordDecl *D); - void DiagnoseUnusedDecl(const NamedDecl *ND); - - /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null - /// statement as a \p Body, and it is located on the same line. - /// - /// This helps prevent bugs due to typos, such as: - /// if (condition); - /// do_stuff(); - void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, - const Stmt *Body, - unsigned DiagID); - - /// Warn if a for/while loop statement \p S, which is followed by - /// \p PossibleBody, has a suspicious null statement as a body. - void DiagnoseEmptyLoopBody(const Stmt *S, - const Stmt *PossibleBody); - - /// Warn if a value is moved to itself. - void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, - SourceLocation OpLoc); - - /// \brief Warn if we're implicitly casting from a _Nullable pointer type to a - /// _Nonnull one. - void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType, - SourceLocation Loc); - - ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) { - return DelayedDiagnostics.push(pool); - } - void PopParsingDeclaration(ParsingDeclState state, Decl *decl); - - typedef ProcessingContextState ParsingClassState; - ParsingClassState PushParsingClass() { - return DelayedDiagnostics.pushUndelayed(); - } - void PopParsingClass(ParsingClassState state) { - DelayedDiagnostics.popUndelayed(state); - } - - void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); - - enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial }; - - void EmitAvailabilityWarning(AvailabilityDiagnostic AD, - NamedDecl *D, StringRef Message, - SourceLocation Loc, - const ObjCInterfaceDecl *UnknownObjCClass, - const ObjCPropertyDecl *ObjCProperty, - bool ObjCPropertyAccess); - - bool makeUnavailableInSystemHeader(SourceLocation loc, - UnavailableAttr::ImplicitReason reason); - - //===--------------------------------------------------------------------===// - // Expression Parsing Callbacks: SemaExpr.cpp. - - bool CanUseDecl(NamedDecl *D); - bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, - const ObjCInterfaceDecl *UnknownObjCClass=nullptr, - bool ObjCPropertyAccess=false); - void NoteDeletedFunction(FunctionDecl *FD); - std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); - bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, - ObjCMethodDecl *Getter, - SourceLocation Loc); - void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, - ArrayRef<Expr *> Args); - - void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, - Decl *LambdaContextDecl = nullptr, - bool IsDecltype = false); - enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl }; - void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, - ReuseLambdaContextDecl_t, - bool IsDecltype = false); - void PopExpressionEvaluationContext(); - - void DiscardCleanupsInEvaluationContext(); - - ExprResult TransformToPotentiallyEvaluated(Expr *E); - ExprResult HandleExprEvaluationContextForTypeof(Expr *E); - - ExprResult ActOnConstantExpression(ExprResult Res); - - // Functions for marking a declaration referenced. These functions also - // contain the relevant logic for marking if a reference to a function or - // variable is an odr-use (in the C++11 sense). There are separate variants - // for expressions referring to a decl; these exist because odr-use marking - // needs to be delayed for some constant variables when we build one of the - // named expressions. - void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse); - void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, - bool OdrUse = true); - void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); - void MarkDeclRefReferenced(DeclRefExpr *E); - void MarkMemberReferenced(MemberExpr *E); - - void UpdateMarkingForLValueToRValue(Expr *E); - void CleanupVarDeclMarking(); - - enum TryCaptureKind { - TryCapture_Implicit, TryCapture_ExplicitByVal, TryCapture_ExplicitByRef - }; - - /// \brief Try to capture the given variable. - /// - /// \param Var The variable to capture. - /// - /// \param Loc The location at which the capture occurs. - /// - /// \param Kind The kind of capture, which may be implicit (for either a - /// block or a lambda), or explicit by-value or by-reference (for a lambda). - /// - /// \param EllipsisLoc The location of the ellipsis, if one is provided in - /// an explicit lambda capture. - /// - /// \param BuildAndDiagnose Whether we are actually supposed to add the - /// captures or diagnose errors. If false, this routine merely check whether - /// the capture can occur without performing the capture itself or complaining - /// if the variable cannot be captured. - /// - /// \param CaptureType Will be set to the type of the field used to capture - /// this variable in the innermost block or lambda. Only valid when the - /// variable can be captured. - /// - /// \param DeclRefType Will be set to the type of a reference to the capture - /// from within the current scope. Only valid when the variable can be - /// captured. - /// - /// \param FunctionScopeIndexToStopAt If non-null, it points to the index - /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. - /// This is useful when enclosing lambdas must speculatively capture - /// variables that may or may not be used in certain specializations of - /// a nested generic lambda. - /// - /// \returns true if an error occurred (i.e., the variable cannot be - /// captured) and false if the capture succeeded. - bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, - SourceLocation EllipsisLoc, bool BuildAndDiagnose, - QualType &CaptureType, - QualType &DeclRefType, - const unsigned *const FunctionScopeIndexToStopAt); - - /// \brief Try to capture the given variable. - bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, - TryCaptureKind Kind = TryCapture_Implicit, - SourceLocation EllipsisLoc = SourceLocation()); - - /// \brief Checks if the variable must be captured. - bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc); - - /// \brief Given a variable, determine the type that a reference to that - /// variable will have in the given scope. - QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc); - - void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); - void MarkDeclarationsReferencedInExpr(Expr *E, - bool SkipLocalVariables = false); - - /// \brief Try to recover by turning the given expression into a - /// call. Returns true if recovery was attempted or an error was - /// emitted; this may also leave the ExprResult invalid. - bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, - bool ForceComplain = false, - bool (*IsPlausibleResult)(QualType) = nullptr); - - /// \brief Figure out if an expression could be turned into a call. - bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, - UnresolvedSetImpl &NonTemplateOverloads); - - /// \brief Conditionally issue a diagnostic based on the current - /// evaluation context. - /// - /// \param Statement If Statement is non-null, delay reporting the - /// diagnostic until the function body is parsed, and then do a basic - /// reachability analysis to determine if the statement is reachable. - /// If it is unreachable, the diagnostic will not be emitted. - bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, - const PartialDiagnostic &PD); - - // Primary Expressions. - SourceRange getExprRange(Expr *E) const; - - ExprResult ActOnIdExpression( - Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr, - bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); - - void DecomposeUnqualifiedId(const UnqualifiedId &Id, - TemplateArgumentListInfo &Buffer, - DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *&TemplateArgs); - - bool - DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - std::unique_ptr<CorrectionCandidateCallback> CCC, - TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, - ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr); - - ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, - IdentifierInfo *II, - bool AllowBuiltinCreation=false); - - ExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - bool isAddressOfOperand, - const TemplateArgumentListInfo *TemplateArgs); - - ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, - ExprValueKind VK, - SourceLocation Loc, - const CXXScopeSpec *SS = nullptr); - ExprResult - BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, - const DeclarationNameInfo &NameInfo, - const CXXScopeSpec *SS = nullptr, - NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr); - ExprResult - BuildAnonymousStructUnionMemberReference( - const CXXScopeSpec &SS, - SourceLocation nameLoc, - IndirectFieldDecl *indirectField, - DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none), - Expr *baseObjectExpr = nullptr, - SourceLocation opLoc = SourceLocation()); - - ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, - const Scope *S); - ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, - bool IsDefiniteInstance, - const Scope *S); - bool UseArgumentDependentLookup(const CXXScopeSpec &SS, - const LookupResult &R, - bool HasTrailingLParen); - - ExprResult - BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - bool IsAddressOfOperand, const Scope *S, - TypeSourceInfo **RecoveryTSI = nullptr); - - ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs); - - ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool NeedsADL, - bool AcceptInvalidDecl = false); - ExprResult BuildDeclarationNameExpr( - const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, - NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr, - bool AcceptInvalidDecl = false); - - ExprResult BuildLiteralOperatorCall(LookupResult &R, - DeclarationNameInfo &SuffixInfo, - ArrayRef<Expr *> Args, - SourceLocation LitEndLoc, - TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr); - - ExprResult BuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT); - ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); - ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); - - bool CheckLoopHintExpr(Expr *E, SourceLocation Loc); - - ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr); - ExprResult ActOnCharacterConstant(const Token &Tok, - Scope *UDLScope = nullptr); - ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E); - ExprResult ActOnParenListExpr(SourceLocation L, - SourceLocation R, - MultiExprArg Val); - - /// ActOnStringLiteral - The specified tokens were lexed as pasted string - /// fragments (e.g. "foo" "bar" L"baz"). - ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks, - Scope *UDLScope = nullptr); - - ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, - SourceLocation DefaultLoc, - SourceLocation RParenLoc, - Expr *ControllingExpr, - ArrayRef<ParsedType> ArgTypes, - ArrayRef<Expr *> ArgExprs); - ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, - SourceLocation DefaultLoc, - SourceLocation RParenLoc, - Expr *ControllingExpr, - ArrayRef<TypeSourceInfo *> Types, - ArrayRef<Expr *> Exprs); - - // Binary/Unary Operators. 'Tok' is the token for the operator. - ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, - Expr *InputExpr); - ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, - UnaryOperatorKind Opc, Expr *Input); - ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, Expr *Input); - - QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc); - - ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, - SourceLocation OpLoc, - UnaryExprOrTypeTrait ExprKind, - SourceRange R); - ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, - UnaryExprOrTypeTrait ExprKind); - ExprResult - ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, - UnaryExprOrTypeTrait ExprKind, - bool IsType, void *TyOrEx, - SourceRange ArgRange); - - ExprResult CheckPlaceholderExpr(Expr *E); - bool CheckVecStepExpr(Expr *E); - - bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind); - bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc, - SourceRange ExprRange, - UnaryExprOrTypeTrait ExprKind); - ExprResult ActOnSizeofParameterPackExpr(Scope *S, - SourceLocation OpLoc, - IdentifierInfo &Name, - SourceLocation NameLoc, - SourceLocation RParenLoc); - ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, Expr *Input); - - ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, - Expr *Idx, SourceLocation RLoc); - ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, - Expr *Idx, SourceLocation RLoc); - ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, - Expr *LowerBound, SourceLocation ColonLoc, - Expr *Length, SourceLocation RBLoc); - - // This struct is for use by ActOnMemberAccess to allow - // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after - // changing the access operator from a '.' to a '->' (to see if that is the - // change needed to fix an error about an unknown member, e.g. when the class - // defines a custom operator->). - struct ActOnMemberAccessExtraArgs { - Scope *S; - UnqualifiedId &Id; - Decl *ObjCImpDecl; - }; - - ExprResult BuildMemberReferenceExpr( - Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, - CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs, - const Scope *S, - ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); - - ExprResult - BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, - bool IsArrow, const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierInScope, LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs, - const Scope *S, - bool SuppressQualifierCheck = false, - ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); - - ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow); - - bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, - const CXXScopeSpec &SS, - const LookupResult &R); - - ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType, - bool IsArrow, SourceLocation OpLoc, - const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierInScope, - const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs); - - ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Member, - Decl *ObjCImpDecl); - - void ActOnDefaultCtorInitializers(Decl *CDtorDecl); - bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, - FunctionDecl *FDecl, - const FunctionProtoType *Proto, - ArrayRef<Expr *> Args, - SourceLocation RParenLoc, - bool ExecConfig = false); - void CheckStaticArrayArgument(SourceLocation CallLoc, - ParmVarDecl *Param, - const Expr *ArgExpr); - - /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. - /// This provides the location of the left/right parens and a list of comma - /// locations. - ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, - MultiExprArg ArgExprs, SourceLocation RParenLoc, - Expr *ExecConfig = nullptr, - bool IsExecConfig = false); - ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, - SourceLocation LParenLoc, - ArrayRef<Expr *> Arg, - SourceLocation RParenLoc, - Expr *Config = nullptr, - bool IsExecConfig = false); - - ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, - MultiExprArg ExecConfig, - SourceLocation GGGLoc); - - ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, - Declarator &D, ParsedType &Ty, - SourceLocation RParenLoc, Expr *CastExpr); - ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, - TypeSourceInfo *Ty, - SourceLocation RParenLoc, - Expr *Op); - CastKind PrepareScalarCast(ExprResult &src, QualType destType); - - /// \brief Build an altivec or OpenCL literal. - ExprResult BuildVectorLiteral(SourceLocation LParenLoc, - SourceLocation RParenLoc, Expr *E, - TypeSourceInfo *TInfo); - - ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME); - - ExprResult ActOnCompoundLiteral(SourceLocation LParenLoc, - ParsedType Ty, - SourceLocation RParenLoc, - Expr *InitExpr); - - ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, - TypeSourceInfo *TInfo, - SourceLocation RParenLoc, - Expr *LiteralExpr); - - ExprResult ActOnInitList(SourceLocation LBraceLoc, - MultiExprArg InitArgList, - SourceLocation RBraceLoc); - - ExprResult ActOnDesignatedInitializer(Designation &Desig, - SourceLocation Loc, - bool GNUSyntax, - ExprResult Init); - -private: - static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind); - -public: - ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, - tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr); - ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, - BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); - ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, - Expr *LHSExpr, Expr *RHSExpr); - - /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null - /// in the case of a the GNU conditional expr extension. - ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, - SourceLocation ColonLoc, - Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr); - - /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". - ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, - LabelDecl *TheDecl); - - void ActOnStartStmtExpr(); - ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, - SourceLocation RPLoc); // "({..})" - void ActOnStmtExprError(); - - // __builtin_offsetof(type, identifier(.identifier|[expr])*) - struct OffsetOfComponent { - SourceLocation LocStart, LocEnd; - bool isBrackets; // true if [expr], false if .ident - union { - IdentifierInfo *IdentInfo; - Expr *E; - } U; - }; - - /// __builtin_offsetof(type, a.b[123][456].c) - ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, - TypeSourceInfo *TInfo, - ArrayRef<OffsetOfComponent> Components, - SourceLocation RParenLoc); - ExprResult ActOnBuiltinOffsetOf(Scope *S, - SourceLocation BuiltinLoc, - SourceLocation TypeLoc, - ParsedType ParsedArgTy, - ArrayRef<OffsetOfComponent> Components, - SourceLocation RParenLoc); - - // __builtin_choose_expr(constExpr, expr1, expr2) - ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, - Expr *CondExpr, Expr *LHSExpr, - Expr *RHSExpr, SourceLocation RPLoc); - - // __builtin_va_arg(expr, type) - ExprResult ActOnVAArg(SourceLocation BuiltinLoc, Expr *E, ParsedType Ty, - SourceLocation RPLoc); - ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, - TypeSourceInfo *TInfo, SourceLocation RPLoc); - - // __null - ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); - - bool CheckCaseExpression(Expr *E); - - /// \brief Describes the result of an "if-exists" condition check. - enum IfExistsResult { - /// \brief The symbol exists. - IER_Exists, - - /// \brief The symbol does not exist. - IER_DoesNotExist, - - /// \brief The name is a dependent name, so the results will differ - /// from one instantiation to the next. - IER_Dependent, - - /// \brief An error occurred. - IER_Error - }; - - IfExistsResult - CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, - const DeclarationNameInfo &TargetNameInfo); - - IfExistsResult - CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc, - bool IsIfExists, CXXScopeSpec &SS, - UnqualifiedId &Name); - - StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc, - bool IsIfExists, - NestedNameSpecifierLoc QualifierLoc, - DeclarationNameInfo NameInfo, - Stmt *Nested); - StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, - bool IsIfExists, - CXXScopeSpec &SS, UnqualifiedId &Name, - Stmt *Nested); - - //===------------------------- "Block" Extension ------------------------===// - - /// ActOnBlockStart - This callback is invoked when a block literal is - /// started. - void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope); - - /// ActOnBlockArguments - This callback allows processing of block arguments. - /// If there are no arguments, this is still invoked. - void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, - Scope *CurScope); - - /// ActOnBlockError - If there is an error parsing a block, this callback - /// is invoked to pop the information about the block from the action impl. - void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope); - - /// ActOnBlockStmtExpr - This is called when the body of a block statement - /// literal was successfully completed. ^(int x){...} - ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, - Scope *CurScope); - - //===---------------------------- Clang Extensions ----------------------===// - - /// __builtin_convertvector(...) - ExprResult ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, - SourceLocation BuiltinLoc, - SourceLocation RParenLoc); - - //===---------------------------- OpenCL Features -----------------------===// - - /// __builtin_astype(...) - ExprResult ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, - SourceLocation BuiltinLoc, - SourceLocation RParenLoc); - - //===---------------------------- C++ Features --------------------------===// - - // Act on C++ namespaces - Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, - SourceLocation NamespaceLoc, - SourceLocation IdentLoc, - IdentifierInfo *Ident, - SourceLocation LBrace, - AttributeList *AttrList, - UsingDirectiveDecl * &UsingDecl); - void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); - - NamespaceDecl *getStdNamespace() const; - NamespaceDecl *getOrCreateStdNamespace(); - - CXXRecordDecl *getStdBadAlloc() const; - - /// \brief Tests whether Ty is an instance of std::initializer_list and, if - /// it is and Element is not NULL, assigns the element type to Element. - bool isStdInitializerList(QualType Ty, QualType *Element); - - /// \brief Looks for the std::initializer_list template and instantiates it - /// with Element, or emits an error if it's not found. - /// - /// \returns The instantiated template, or null on error. - QualType BuildStdInitializerList(QualType Element, SourceLocation Loc); - - /// \brief Determine whether Ctor is an initializer-list constructor, as - /// defined in [dcl.init.list]p2. - bool isInitListConstructor(const CXXConstructorDecl *Ctor); - - Decl *ActOnUsingDirective(Scope *CurScope, - SourceLocation UsingLoc, - SourceLocation NamespcLoc, - CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *NamespcName, - AttributeList *AttrList); - - void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir); - - Decl *ActOnNamespaceAliasDef(Scope *CurScope, - SourceLocation NamespaceLoc, - SourceLocation AliasLoc, - IdentifierInfo *Alias, - CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *Ident); - - void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow); - bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target, - const LookupResult &PreviousDecls, - UsingShadowDecl *&PrevShadow); - UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD, - NamedDecl *Target, - UsingShadowDecl *PrevDecl); - - bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc, - bool HasTypenameKeyword, - const CXXScopeSpec &SS, - SourceLocation NameLoc, - const LookupResult &Previous); - bool CheckUsingDeclQualifier(SourceLocation UsingLoc, - const CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - SourceLocation NameLoc); - - NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS, - SourceLocation UsingLoc, - CXXScopeSpec &SS, - DeclarationNameInfo NameInfo, - AttributeList *AttrList, - bool IsInstantiation, - bool HasTypenameKeyword, - SourceLocation TypenameLoc); - - bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); - - Decl *ActOnUsingDeclaration(Scope *CurScope, - AccessSpecifier AS, - bool HasUsingKeyword, - SourceLocation UsingLoc, - CXXScopeSpec &SS, - UnqualifiedId &Name, - AttributeList *AttrList, - bool HasTypenameKeyword, - SourceLocation TypenameLoc); - Decl *ActOnAliasDeclaration(Scope *CurScope, - AccessSpecifier AS, - MultiTemplateParamsArg TemplateParams, - SourceLocation UsingLoc, - UnqualifiedId &Name, - AttributeList *AttrList, - TypeResult Type, - Decl *DeclFromDeclSpec); - - /// BuildCXXConstructExpr - Creates a complete call to a constructor, - /// including handling of its default argument expressions. - /// - /// \param ConstructKind - a CXXConstructExpr::ConstructionKind - ExprResult - BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, - CXXConstructorDecl *Constructor, MultiExprArg Exprs, - bool HadMultipleCandidates, bool IsListInitialization, - bool IsStdInitListInitialization, - bool RequiresZeroInit, unsigned ConstructKind, - SourceRange ParenRange); - - // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if - // the constructor can be elidable? - ExprResult - BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, - CXXConstructorDecl *Constructor, bool Elidable, - MultiExprArg Exprs, bool HadMultipleCandidates, - bool IsListInitialization, - bool IsStdInitListInitialization, bool RequiresZeroInit, - unsigned ConstructKind, SourceRange ParenRange); - - ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field); - - /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating - /// the default expr if needed. - ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, - FunctionDecl *FD, - ParmVarDecl *Param); - - /// FinalizeVarWithDestructor - Prepare for calling destructor on the - /// constructed variable. - void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType); - - /// \brief Helper class that collects exception specifications for - /// implicitly-declared special member functions. - class ImplicitExceptionSpecification { - // Pointer to allow copying - Sema *Self; - // We order exception specifications thus: - // noexcept is the most restrictive, but is only used in C++11. - // throw() comes next. - // Then a throw(collected exceptions) - // Finally no specification, which is expressed as noexcept(false). - // throw(...) is used instead if any called function uses it. - ExceptionSpecificationType ComputedEST; - llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen; - SmallVector<QualType, 4> Exceptions; - - void ClearExceptions() { - ExceptionsSeen.clear(); - Exceptions.clear(); - } - - public: - explicit ImplicitExceptionSpecification(Sema &Self) - : Self(&Self), ComputedEST(EST_BasicNoexcept) { - if (!Self.getLangOpts().CPlusPlus11) - ComputedEST = EST_DynamicNone; - } - - /// \brief Get the computed exception specification type. - ExceptionSpecificationType getExceptionSpecType() const { - assert(ComputedEST != EST_ComputedNoexcept && - "noexcept(expr) should not be a possible result"); - return ComputedEST; - } - - /// \brief The number of exceptions in the exception specification. - unsigned size() const { return Exceptions.size(); } - - /// \brief The set of exceptions in the exception specification. - const QualType *data() const { return Exceptions.data(); } - - /// \brief Integrate another called method into the collected data. - void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method); - - /// \brief Integrate an invoked expression into the collected data. - void CalledExpr(Expr *E); - - /// \brief Overwrite an EPI's exception specification with this - /// computed exception specification. - FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const { - FunctionProtoType::ExceptionSpecInfo ESI; - ESI.Type = getExceptionSpecType(); - if (ESI.Type == EST_Dynamic) { - ESI.Exceptions = Exceptions; - } else if (ESI.Type == EST_None) { - /// C++11 [except.spec]p14: - /// The exception-specification is noexcept(false) if the set of - /// potential exceptions of the special member function contains "any" - ESI.Type = EST_ComputedNoexcept; - ESI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(), - tok::kw_false).get(); - } - return ESI; - } - }; - - /// \brief Determine what sort of exception specification a defaulted - /// copy constructor of a class will have. - ImplicitExceptionSpecification - ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc, - CXXMethodDecl *MD); - - /// \brief Determine what sort of exception specification a defaulted - /// default constructor of a class will have, and whether the parameter - /// will be const. - ImplicitExceptionSpecification - ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD); - - /// \brief Determine what sort of exception specification a defautled - /// copy assignment operator of a class will have, and whether the - /// parameter will be const. - ImplicitExceptionSpecification - ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD); - - /// \brief Determine what sort of exception specification a defaulted move - /// constructor of a class will have. - ImplicitExceptionSpecification - ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD); - - /// \brief Determine what sort of exception specification a defaulted move - /// assignment operator of a class will have. - ImplicitExceptionSpecification - ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD); - - /// \brief Determine what sort of exception specification a defaulted - /// destructor of a class will have. - ImplicitExceptionSpecification - ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD); - - /// \brief Determine what sort of exception specification an inheriting - /// constructor of a class will have. - ImplicitExceptionSpecification - ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD); - - /// \brief Evaluate the implicit exception specification for a defaulted - /// special member function. - void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD); - - /// \brief Check the given exception-specification and update the - /// exception specification information with the results. - void checkExceptionSpecification(bool IsTopLevel, - ExceptionSpecificationType EST, - ArrayRef<ParsedType> DynamicExceptions, - ArrayRef<SourceRange> DynamicExceptionRanges, - Expr *NoexceptExpr, - SmallVectorImpl<QualType> &Exceptions, - FunctionProtoType::ExceptionSpecInfo &ESI); - - /// \brief Determine if we're in a case where we need to (incorrectly) eagerly - /// parse an exception specification to work around a libstdc++ bug. - bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D); - - /// \brief Add an exception-specification to the given member function - /// (or member function template). The exception-specification was parsed - /// after the method itself was declared. - void actOnDelayedExceptionSpecification(Decl *Method, - ExceptionSpecificationType EST, - SourceRange SpecificationRange, - ArrayRef<ParsedType> DynamicExceptions, - ArrayRef<SourceRange> DynamicExceptionRanges, - Expr *NoexceptExpr); - - /// \brief Determine if a special member function should have a deleted - /// definition when it is defaulted. - bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, - bool Diagnose = false); - - /// \brief Declare the implicit default constructor for the given class. - /// - /// \param ClassDecl The class declaration into which the implicit - /// default constructor will be added. - /// - /// \returns The implicitly-declared default constructor. - CXXConstructorDecl *DeclareImplicitDefaultConstructor( - CXXRecordDecl *ClassDecl); - - /// DefineImplicitDefaultConstructor - Checks for feasibility of - /// defining this constructor as the default constructor. - void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, - CXXConstructorDecl *Constructor); - - /// \brief Declare the implicit destructor for the given class. - /// - /// \param ClassDecl The class declaration into which the implicit - /// destructor will be added. - /// - /// \returns The implicitly-declared destructor. - CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl); - - /// DefineImplicitDestructor - Checks for feasibility of - /// defining this destructor as the default destructor. - void DefineImplicitDestructor(SourceLocation CurrentLocation, - CXXDestructorDecl *Destructor); - - /// \brief Build an exception spec for destructors that don't have one. - /// - /// C++11 says that user-defined destructors with no exception spec get one - /// that looks as if the destructor was implicitly declared. - void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, - CXXDestructorDecl *Destructor); - - /// \brief Declare all inheriting constructors for the given class. - /// - /// \param ClassDecl The class declaration into which the inheriting - /// constructors will be added. - void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl); - - /// \brief Define the specified inheriting constructor. - void DefineInheritingConstructor(SourceLocation UseLoc, - CXXConstructorDecl *Constructor); - - /// \brief Declare the implicit copy constructor for the given class. - /// - /// \param ClassDecl The class declaration into which the implicit - /// copy constructor will be added. - /// - /// \returns The implicitly-declared copy constructor. - CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl); - - /// DefineImplicitCopyConstructor - Checks for feasibility of - /// defining this constructor as the copy constructor. - void DefineImplicitCopyConstructor(SourceLocation CurrentLocation, - CXXConstructorDecl *Constructor); - - /// \brief Declare the implicit move constructor for the given class. - /// - /// \param ClassDecl The Class declaration into which the implicit - /// move constructor will be added. - /// - /// \returns The implicitly-declared move constructor, or NULL if it wasn't - /// declared. - CXXConstructorDecl *DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl); - - /// DefineImplicitMoveConstructor - Checks for feasibility of - /// defining this constructor as the move constructor. - void DefineImplicitMoveConstructor(SourceLocation CurrentLocation, - CXXConstructorDecl *Constructor); - - /// \brief Declare the implicit copy assignment operator for the given class. - /// - /// \param ClassDecl The class declaration into which the implicit - /// copy assignment operator will be added. - /// - /// \returns The implicitly-declared copy assignment operator. - CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl); - - /// \brief Defines an implicitly-declared copy assignment operator. - void DefineImplicitCopyAssignment(SourceLocation CurrentLocation, - CXXMethodDecl *MethodDecl); - - /// \brief Declare the implicit move assignment operator for the given class. - /// - /// \param ClassDecl The Class declaration into which the implicit - /// move assignment operator will be added. - /// - /// \returns The implicitly-declared move assignment operator, or NULL if it - /// wasn't declared. - CXXMethodDecl *DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl); - - /// \brief Defines an implicitly-declared move assignment operator. - void DefineImplicitMoveAssignment(SourceLocation CurrentLocation, - CXXMethodDecl *MethodDecl); - - /// \brief Force the declaration of any implicitly-declared members of this - /// class. - void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class); - - /// \brief Determine whether the given function is an implicitly-deleted - /// special member function. - bool isImplicitlyDeleted(FunctionDecl *FD); - - /// \brief Check whether 'this' shows up in the type of a static member - /// function after the (naturally empty) cv-qualifier-seq would be. - /// - /// \returns true if an error occurred. - bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method); - - /// \brief Whether this' shows up in the exception specification of a static - /// member function. - bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method); - - /// \brief Check whether 'this' shows up in the attributes of the given - /// static member function. - /// - /// \returns true if an error occurred. - bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method); - - /// MaybeBindToTemporary - If the passed in expression has a record type with - /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise - /// it simply returns the passed in expression. - ExprResult MaybeBindToTemporary(Expr *E); - - bool CompleteConstructorCall(CXXConstructorDecl *Constructor, - MultiExprArg ArgsPtr, - SourceLocation Loc, - SmallVectorImpl<Expr*> &ConvertedArgs, - bool AllowExplicit = false, - bool IsListInitialization = false); - - ParsedType getInheritingConstructorName(CXXScopeSpec &SS, - SourceLocation NameLoc, - IdentifierInfo &Name); - - ParsedType getDestructorName(SourceLocation TildeLoc, - IdentifierInfo &II, SourceLocation NameLoc, - Scope *S, CXXScopeSpec &SS, - ParsedType ObjectType, - bool EnteringContext); - - ParsedType getDestructorType(const DeclSpec& DS, ParsedType ObjectType); - - // Checks that reinterpret casts don't have undefined behavior. - void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, - bool IsDereference, SourceRange Range); - - /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. - ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, - tok::TokenKind Kind, - SourceLocation LAngleBracketLoc, - Declarator &D, - SourceLocation RAngleBracketLoc, - SourceLocation LParenLoc, - Expr *E, - SourceLocation RParenLoc); - - ExprResult BuildCXXNamedCast(SourceLocation OpLoc, - tok::TokenKind Kind, - TypeSourceInfo *Ty, - Expr *E, - SourceRange AngleBrackets, - SourceRange Parens); - - ExprResult BuildCXXTypeId(QualType TypeInfoType, - SourceLocation TypeidLoc, - TypeSourceInfo *Operand, - SourceLocation RParenLoc); - ExprResult BuildCXXTypeId(QualType TypeInfoType, - SourceLocation TypeidLoc, - Expr *Operand, - SourceLocation RParenLoc); - - /// ActOnCXXTypeid - Parse typeid( something ). - ExprResult ActOnCXXTypeid(SourceLocation OpLoc, - SourceLocation LParenLoc, bool isType, - void *TyOrExpr, - SourceLocation RParenLoc); - - ExprResult BuildCXXUuidof(QualType TypeInfoType, - SourceLocation TypeidLoc, - TypeSourceInfo *Operand, - SourceLocation RParenLoc); - ExprResult BuildCXXUuidof(QualType TypeInfoType, - SourceLocation TypeidLoc, - Expr *Operand, - SourceLocation RParenLoc); - - /// ActOnCXXUuidof - Parse __uuidof( something ). - ExprResult ActOnCXXUuidof(SourceLocation OpLoc, - SourceLocation LParenLoc, bool isType, - void *TyOrExpr, - SourceLocation RParenLoc); - - /// \brief Handle a C++1z fold-expression: ( expr op ... op expr ). - ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, - tok::TokenKind Operator, - SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc); - ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, - BinaryOperatorKind Operator, - SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc); - ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, - BinaryOperatorKind Operator); - - //// ActOnCXXThis - Parse 'this' pointer. - ExprResult ActOnCXXThis(SourceLocation loc); - - /// \brief Try to retrieve the type of the 'this' pointer. - /// - /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. - QualType getCurrentThisType(); - - /// \brief When non-NULL, the C++ 'this' expression is allowed despite the - /// current context not being a non-static member function. In such cases, - /// this provides the type used for 'this'. - QualType CXXThisTypeOverride; - - /// \brief RAII object used to temporarily allow the C++ 'this' expression - /// to be used, with the given qualifiers on the current class type. - class CXXThisScopeRAII { - Sema &S; - QualType OldCXXThisTypeOverride; - bool Enabled; - - public: - /// \brief Introduce a new scope where 'this' may be allowed (when enabled), - /// using the given declaration (which is either a class template or a - /// class) along with the given qualifiers. - /// along with the qualifiers placed on '*this'. - CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals, - bool Enabled = true); - - ~CXXThisScopeRAII(); - }; - - /// \brief Make sure the value of 'this' is actually available in the current - /// context, if it is a potentially evaluated context. - /// - /// \param Loc The location at which the capture of 'this' occurs. - /// - /// \param Explicit Whether 'this' is explicitly captured in a lambda - /// capture list. - /// - /// \param FunctionScopeIndexToStopAt If non-null, it points to the index - /// of the FunctionScopeInfo stack beyond which we do not attempt to capture. - /// This is useful when enclosing lambdas must speculatively capture - /// 'this' that may or may not be used in certain specializations of - /// a nested generic lambda (depending on whether the name resolves to - /// a non-static member function or a static function). - /// \return returns 'true' if failed, 'false' if success. - bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, - bool BuildAndDiagnose = true, - const unsigned *const FunctionScopeIndexToStopAt = nullptr); - - /// \brief Determine whether the given type is the type of *this that is used - /// outside of the body of a member function for a type that is currently - /// being defined. - bool isThisOutsideMemberFunctionBody(QualType BaseType); - - /// ActOnCXXBoolLiteral - Parse {true,false} literals. - ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); - - - /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. - ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); - - /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. - ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); - - //// ActOnCXXThrow - Parse throw expressions. - ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr); - ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, - bool IsThrownVarInScope); - bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E); - - /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. - /// Can be interpreted either as function-style casting ("int(x)") - /// or class type construction ("ClassType(x,y,z)") - /// or creation of a value-initialized type ("int()"). - ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, - SourceLocation LParenLoc, - MultiExprArg Exprs, - SourceLocation RParenLoc); - - ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, - SourceLocation LParenLoc, - MultiExprArg Exprs, - SourceLocation RParenLoc); - - /// ActOnCXXNew - Parsed a C++ 'new' expression. - ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, - SourceLocation PlacementLParen, - MultiExprArg PlacementArgs, - SourceLocation PlacementRParen, - SourceRange TypeIdParens, Declarator &D, - Expr *Initializer); - ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal, - SourceLocation PlacementLParen, - MultiExprArg PlacementArgs, - SourceLocation PlacementRParen, - SourceRange TypeIdParens, - QualType AllocType, - TypeSourceInfo *AllocTypeInfo, - Expr *ArraySize, - SourceRange DirectInitRange, - Expr *Initializer, - bool TypeMayContainAuto = true); - - bool CheckAllocatedType(QualType AllocType, SourceLocation Loc, - SourceRange R); - bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, - bool UseGlobal, QualType AllocType, bool IsArray, - MultiExprArg PlaceArgs, - FunctionDecl *&OperatorNew, - FunctionDecl *&OperatorDelete); - bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, - DeclarationName Name, MultiExprArg Args, - DeclContext *Ctx, - bool AllowMissing, FunctionDecl *&Operator, - bool Diagnose = true); - void DeclareGlobalNewDelete(); - void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, - QualType Param1, - QualType Param2 = QualType(), - bool addRestrictAttr = false); - - bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, - DeclarationName Name, FunctionDecl* &Operator, - bool Diagnose = true); - FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc, - bool CanProvideSize, - DeclarationName Name); - - /// ActOnCXXDelete - Parsed a C++ 'delete' expression - ExprResult ActOnCXXDelete(SourceLocation StartLoc, - bool UseGlobal, bool ArrayForm, - Expr *Operand); - - DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); - ExprResult CheckConditionVariable(VarDecl *ConditionVar, - SourceLocation StmtLoc, - bool ConvertToBoolean); - - ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, - Expr *Operand, SourceLocation RParen); - ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, - SourceLocation RParen); - - /// \brief Parsed one of the type trait support pseudo-functions. - ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, - ArrayRef<ParsedType> Args, - SourceLocation RParenLoc); - ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, - ArrayRef<TypeSourceInfo *> Args, - SourceLocation RParenLoc); - - /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support - /// pseudo-functions. - ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, - SourceLocation KWLoc, - ParsedType LhsTy, - Expr *DimExpr, - SourceLocation RParen); - - ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, - SourceLocation KWLoc, - TypeSourceInfo *TSInfo, - Expr *DimExpr, - SourceLocation RParen); - - /// ActOnExpressionTrait - Parsed one of the unary type trait support - /// pseudo-functions. - ExprResult ActOnExpressionTrait(ExpressionTrait OET, - SourceLocation KWLoc, - Expr *Queried, - SourceLocation RParen); - - ExprResult BuildExpressionTrait(ExpressionTrait OET, - SourceLocation KWLoc, - Expr *Queried, - SourceLocation RParen); - - ExprResult ActOnStartCXXMemberReference(Scope *S, - Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - ParsedType &ObjectType, - bool &MayBePseudoDestructor); - - ExprResult BuildPseudoDestructorExpr(Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - const CXXScopeSpec &SS, - TypeSourceInfo *ScopeType, - SourceLocation CCLoc, - SourceLocation TildeLoc, - PseudoDestructorTypeStorage DestroyedType); - - ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - CXXScopeSpec &SS, - UnqualifiedId &FirstTypeName, - SourceLocation CCLoc, - SourceLocation TildeLoc, - UnqualifiedId &SecondTypeName); - - ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - SourceLocation TildeLoc, - const DeclSpec& DS); - - /// MaybeCreateExprWithCleanups - If the current full-expression - /// requires any cleanups, surround it with a ExprWithCleanups node. - /// Otherwise, just returns the passed-in expression. - Expr *MaybeCreateExprWithCleanups(Expr *SubExpr); - Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); - ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); - - ExprResult ActOnFinishFullExpr(Expr *Expr) { - return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() - : SourceLocation()); - } - ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, - bool DiscardedValue = false, - bool IsConstexpr = false, - bool IsLambdaInitCaptureInitializer = false); - StmtResult ActOnFinishFullStmt(Stmt *Stmt); - - // Marks SS invalid if it represents an incomplete type. - bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC); - - DeclContext *computeDeclContext(QualType T); - DeclContext *computeDeclContext(const CXXScopeSpec &SS, - bool EnteringContext = false); - bool isDependentScopeSpecifier(const CXXScopeSpec &SS); - CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS); - - /// \brief The parser has parsed a global nested-name-specifier '::'. - /// - /// \param CCLoc The location of the '::'. - /// - /// \param SS The nested-name-specifier, which will be updated in-place - /// to reflect the parsed nested-name-specifier. - /// - /// \returns true if an error occurred, false otherwise. - bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS); - - /// \brief The parser has parsed a '__super' nested-name-specifier. - /// - /// \param SuperLoc The location of the '__super' keyword. - /// - /// \param ColonColonLoc The location of the '::'. - /// - /// \param SS The nested-name-specifier, which will be updated in-place - /// to reflect the parsed nested-name-specifier. - /// - /// \returns true if an error occurred, false otherwise. - bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, - SourceLocation ColonColonLoc, CXXScopeSpec &SS); - - bool isAcceptableNestedNameSpecifier(const NamedDecl *SD, - bool *CanCorrect = nullptr); - NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS); - - bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, - SourceLocation IdLoc, - IdentifierInfo &II, - ParsedType ObjectType); - - bool BuildCXXNestedNameSpecifier(Scope *S, - IdentifierInfo &Identifier, - SourceLocation IdentifierLoc, - SourceLocation CCLoc, - QualType ObjectType, - bool EnteringContext, - CXXScopeSpec &SS, - NamedDecl *ScopeLookupResult, - bool ErrorRecoveryLookup, - bool *IsCorrectedToColon = nullptr); - - /// \brief The parser has parsed a nested-name-specifier 'identifier::'. - /// - /// \param S The scope in which this nested-name-specifier occurs. - /// - /// \param Identifier The identifier preceding the '::'. - /// - /// \param IdentifierLoc The location of the identifier. - /// - /// \param CCLoc The location of the '::'. - /// - /// \param ObjectType The type of the object, if we're parsing - /// nested-name-specifier in a member access expression. - /// - /// \param EnteringContext Whether we're entering the context nominated by - /// this nested-name-specifier. - /// - /// \param SS The nested-name-specifier, which is both an input - /// parameter (the nested-name-specifier before this type) and an - /// output parameter (containing the full nested-name-specifier, - /// including this new type). - /// - /// \param ErrorRecoveryLookup If true, then this method is called to improve - /// error recovery. In this case do not emit error message. - /// - /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':' - /// are allowed. The bool value pointed by this parameter is set to 'true' - /// if the identifier is treated as if it was followed by ':', not '::'. - /// - /// \returns true if an error occurred, false otherwise. - bool ActOnCXXNestedNameSpecifier(Scope *S, - IdentifierInfo &Identifier, - SourceLocation IdentifierLoc, - SourceLocation CCLoc, - ParsedType ObjectType, - bool EnteringContext, - CXXScopeSpec &SS, - bool ErrorRecoveryLookup = false, - bool *IsCorrectedToColon = nullptr); - - ExprResult ActOnDecltypeExpression(Expr *E); - - bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, - const DeclSpec &DS, - SourceLocation ColonColonLoc); - - bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, - IdentifierInfo &Identifier, - SourceLocation IdentifierLoc, - SourceLocation ColonLoc, - ParsedType ObjectType, - bool EnteringContext); - - /// \brief The parser has parsed a nested-name-specifier - /// 'template[opt] template-name < template-args >::'. - /// - /// \param S The scope in which this nested-name-specifier occurs. - /// - /// \param SS The nested-name-specifier, which is both an input - /// parameter (the nested-name-specifier before this type) and an - /// output parameter (containing the full nested-name-specifier, - /// including this new type). - /// - /// \param TemplateKWLoc the location of the 'template' keyword, if any. - /// \param TemplateName the template name. - /// \param TemplateNameLoc The location of the template name. - /// \param LAngleLoc The location of the opening angle bracket ('<'). - /// \param TemplateArgs The template arguments. - /// \param RAngleLoc The location of the closing angle bracket ('>'). - /// \param CCLoc The location of the '::'. - /// - /// \param EnteringContext Whether we're entering the context of the - /// nested-name-specifier. - /// - /// - /// \returns true if an error occurred, false otherwise. - bool ActOnCXXNestedNameSpecifier(Scope *S, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - TemplateTy TemplateName, - SourceLocation TemplateNameLoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgs, - SourceLocation RAngleLoc, - SourceLocation CCLoc, - bool EnteringContext); - - /// \brief Given a C++ nested-name-specifier, produce an annotation value - /// that the parser can use later to reconstruct the given - /// nested-name-specifier. - /// - /// \param SS A nested-name-specifier. - /// - /// \returns A pointer containing all of the information in the - /// nested-name-specifier \p SS. - void *SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS); - - /// \brief Given an annotation pointer for a nested-name-specifier, restore - /// the nested-name-specifier structure. - /// - /// \param Annotation The annotation pointer, produced by - /// \c SaveNestedNameSpecifierAnnotation(). - /// - /// \param AnnotationRange The source range corresponding to the annotation. - /// - /// \param SS The nested-name-specifier that will be updated with the contents - /// of the annotation pointer. - void RestoreNestedNameSpecifierAnnotation(void *Annotation, - SourceRange AnnotationRange, - CXXScopeSpec &SS); - - bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS); - - /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global - /// scope or nested-name-specifier) is parsed, part of a declarator-id. - /// After this method is called, according to [C++ 3.4.3p3], names should be - /// looked up in the declarator-id's scope, until the declarator is parsed and - /// ActOnCXXExitDeclaratorScope is called. - /// The 'SS' should be a non-empty valid CXXScopeSpec. - bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS); - - /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously - /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same - /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well. - /// Used to indicate that names should revert to being looked up in the - /// defining scope. - void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS); - - /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an - /// initializer for the declaration 'Dcl'. - /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a - /// static data member of class X, names should be looked up in the scope of - /// class X. - void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl); - - /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an - /// initializer for the declaration 'Dcl'. - void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl); - - /// \brief Create a new lambda closure type. - CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, - TypeSourceInfo *Info, - bool KnownDependent, - LambdaCaptureDefault CaptureDefault); - - /// \brief Start the definition of a lambda expression. - CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, - SourceRange IntroducerRange, - TypeSourceInfo *MethodType, - SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params); - - /// \brief Endow the lambda scope info with the relevant properties. - void buildLambdaScope(sema::LambdaScopeInfo *LSI, - CXXMethodDecl *CallOperator, - SourceRange IntroducerRange, - LambdaCaptureDefault CaptureDefault, - SourceLocation CaptureDefaultLoc, - bool ExplicitParams, - bool ExplicitResultType, - bool Mutable); - - /// \brief Perform initialization analysis of the init-capture and perform - /// any implicit conversions such as an lvalue-to-rvalue conversion if - /// not being used to initialize a reference. - ParsedType actOnLambdaInitCaptureInitialization( - SourceLocation Loc, bool ByRef, IdentifierInfo *Id, - LambdaCaptureInitKind InitKind, Expr *&Init) { - return ParsedType::make(buildLambdaInitCaptureInitialization( - Loc, ByRef, Id, InitKind != LambdaCaptureInitKind::CopyInit, Init)); - } - QualType buildLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, - IdentifierInfo *Id, - bool DirectInit, Expr *&Init); - - /// \brief Create a dummy variable within the declcontext of the lambda's - /// call operator, for name lookup purposes for a lambda init capture. - /// - /// CodeGen handles emission of lambda captures, ignoring these dummy - /// variables appropriately. - VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, - QualType InitCaptureType, - IdentifierInfo *Id, - unsigned InitStyle, Expr *Init); - - /// \brief Build the implicit field for an init-capture. - FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var); - - /// \brief Note that we have finished the explicit captures for the - /// given lambda. - void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); - - /// \brief Introduce the lambda parameters into scope. - void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope); - - /// \brief Deduce a block or lambda's return type based on the return - /// statements present in the body. - void deduceClosureReturnType(sema::CapturingScopeInfo &CSI); - - /// ActOnStartOfLambdaDefinition - This is called just before we start - /// parsing the body of a lambda; it analyzes the explicit captures and - /// arguments, and sets up various data-structures for the body of the - /// lambda. - void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, - Declarator &ParamInfo, Scope *CurScope); - - /// ActOnLambdaError - If there is an error parsing a lambda, this callback - /// is invoked to pop the information about the lambda. - void ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, - bool IsInstantiation = false); - - /// ActOnLambdaExpr - This is called when the body of a lambda expression - /// was successfully completed. - ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, - Scope *CurScope); - - /// \brief Complete a lambda-expression having processed and attached the - /// lambda body. - ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, - sema::LambdaScopeInfo *LSI); - - /// \brief Define the "body" of the conversion from a lambda object to a - /// function pointer. - /// - /// This routine doesn't actually define a sensible body; rather, it fills - /// in the initialization expression needed to copy the lambda object into - /// the block, and IR generation actually generates the real body of the - /// block pointer conversion. - void DefineImplicitLambdaToFunctionPointerConversion( - SourceLocation CurrentLoc, CXXConversionDecl *Conv); - - /// \brief Define the "body" of the conversion from a lambda object to a - /// block pointer. - /// - /// This routine doesn't actually define a sensible body; rather, it fills - /// in the initialization expression needed to copy the lambda object into - /// the block, and IR generation actually generates the real body of the - /// block pointer conversion. - void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc, - CXXConversionDecl *Conv); - - ExprResult BuildBlockForLambdaConversion(SourceLocation CurrentLocation, - SourceLocation ConvLocation, - CXXConversionDecl *Conv, - Expr *Src); - - // ParseObjCStringLiteral - Parse Objective-C string literals. - ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, - ArrayRef<Expr *> Strings); - - ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); - - /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the - /// numeric literal expression. Type of the expression will be "NSNumber *" - /// or "id" if NSNumber is unavailable. - ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number); - ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, - bool Value); - ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements); - - /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the - /// '@' prefixed parenthesized expression. The type of the expression will - /// either be "NSNumber *", "NSString *" or "NSValue *" depending on the type - /// of ValueType, which is allowed to be a built-in numeric type, "char *", - /// "const char *" or C structure with attribute 'objc_boxable'. - ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr); - - ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, - Expr *IndexExpr, - ObjCMethodDecl *getterMethod, - ObjCMethodDecl *setterMethod); - - ExprResult BuildObjCDictionaryLiteral(SourceRange SR, - MutableArrayRef<ObjCDictionaryElement> Elements); - - ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, - TypeSourceInfo *EncodedTypeInfo, - SourceLocation RParenLoc); - ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, - CXXConversionDecl *Method, - bool HadMultipleCandidates); - - ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, - SourceLocation EncodeLoc, - SourceLocation LParenLoc, - ParsedType Ty, - SourceLocation RParenLoc); - - /// ParseObjCSelectorExpression - Build selector expression for \@selector - ExprResult ParseObjCSelectorExpression(Selector Sel, - SourceLocation AtLoc, - SourceLocation SelLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc, - bool WarnMultipleSelectors); - - /// ParseObjCProtocolExpression - Build protocol expression for \@protocol - ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName, - SourceLocation AtLoc, - SourceLocation ProtoLoc, - SourceLocation LParenLoc, - SourceLocation ProtoIdLoc, - SourceLocation RParenLoc); - - //===--------------------------------------------------------------------===// - // C++ Declarations - // - Decl *ActOnStartLinkageSpecification(Scope *S, - SourceLocation ExternLoc, - Expr *LangStr, - SourceLocation LBraceLoc); - Decl *ActOnFinishLinkageSpecification(Scope *S, - Decl *LinkageSpec, - SourceLocation RBraceLoc); - - - //===--------------------------------------------------------------------===// - // C++ Classes - // - bool isCurrentClassName(const IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS = nullptr); - bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS); - - bool ActOnAccessSpecifier(AccessSpecifier Access, - SourceLocation ASLoc, - SourceLocation ColonLoc, - AttributeList *Attrs = nullptr); - - NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, - Declarator &D, - MultiTemplateParamsArg TemplateParameterLists, - Expr *BitfieldWidth, const VirtSpecifiers &VS, - InClassInitStyle InitStyle); - - void ActOnStartCXXInClassMemberInitializer(); - void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, - SourceLocation EqualLoc, - Expr *Init); - - MemInitResult ActOnMemInitializer(Decl *ConstructorD, - Scope *S, - CXXScopeSpec &SS, - IdentifierInfo *MemberOrBase, - ParsedType TemplateTypeTy, - const DeclSpec &DS, - SourceLocation IdLoc, - SourceLocation LParenLoc, - ArrayRef<Expr *> Args, - SourceLocation RParenLoc, - SourceLocation EllipsisLoc); - - MemInitResult ActOnMemInitializer(Decl *ConstructorD, - Scope *S, - CXXScopeSpec &SS, - IdentifierInfo *MemberOrBase, - ParsedType TemplateTypeTy, - const DeclSpec &DS, - SourceLocation IdLoc, - Expr *InitList, - SourceLocation EllipsisLoc); - - MemInitResult BuildMemInitializer(Decl *ConstructorD, - Scope *S, - CXXScopeSpec &SS, - IdentifierInfo *MemberOrBase, - ParsedType TemplateTypeTy, - const DeclSpec &DS, - SourceLocation IdLoc, - Expr *Init, - SourceLocation EllipsisLoc); - - MemInitResult BuildMemberInitializer(ValueDecl *Member, - Expr *Init, - SourceLocation IdLoc); - - MemInitResult BuildBaseInitializer(QualType BaseType, - TypeSourceInfo *BaseTInfo, - Expr *Init, - CXXRecordDecl *ClassDecl, - SourceLocation EllipsisLoc); - - MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, - Expr *Init, - CXXRecordDecl *ClassDecl); - - bool SetDelegatingInitializer(CXXConstructorDecl *Constructor, - CXXCtorInitializer *Initializer); - - bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, - ArrayRef<CXXCtorInitializer *> Initializers = None); - - void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); - - - /// MarkBaseAndMemberDestructorsReferenced - Given a record decl, - /// mark all the non-trivial destructors of its members and bases as - /// referenced. - void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc, - CXXRecordDecl *Record); - - /// \brief The list of classes whose vtables have been used within - /// this translation unit, and the source locations at which the - /// first use occurred. - typedef std::pair<CXXRecordDecl*, SourceLocation> VTableUse; - - /// \brief The list of vtables that are required but have not yet been - /// materialized. - SmallVector<VTableUse, 16> VTableUses; - - /// \brief The set of classes whose vtables have been used within - /// this translation unit, and a bit that will be true if the vtable is - /// required to be emitted (otherwise, it should be emitted only if needed - /// by code generation). - llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed; - - /// \brief Load any externally-stored vtable uses. - void LoadExternalVTableUses(); - - /// \brief Note that the vtable for the given class was used at the - /// given location. - void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, - bool DefinitionRequired = false); - - /// \brief Mark the exception specifications of all virtual member functions - /// in the given class as needed. - void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc, - const CXXRecordDecl *RD); - - /// MarkVirtualMembersReferenced - Will mark all members of the given - /// CXXRecordDecl referenced. - void MarkVirtualMembersReferenced(SourceLocation Loc, - const CXXRecordDecl *RD); - - /// \brief Define all of the vtables that have been used in this - /// translation unit and reference any virtual members used by those - /// vtables. - /// - /// \returns true if any work was done, false otherwise. - bool DefineUsedVTables(); - - void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl); - - void ActOnMemInitializers(Decl *ConstructorDecl, - SourceLocation ColonLoc, - ArrayRef<CXXCtorInitializer*> MemInits, - bool AnyErrors); - - void checkClassLevelDLLAttribute(CXXRecordDecl *Class); - void propagateDLLAttrToBaseClassTemplate( - CXXRecordDecl *Class, Attr *ClassAttr, - ClassTemplateSpecializationDecl *BaseTemplateSpec, - SourceLocation BaseLoc); - void CheckCompletedCXXClass(CXXRecordDecl *Record); - void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, - Decl *TagDecl, - SourceLocation LBrac, - SourceLocation RBrac, - AttributeList *AttrList); - void ActOnFinishCXXMemberDecls(); - void ActOnFinishCXXNonNestedClass(Decl *D); - - void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); - unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template); - void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); - void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); - void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); - void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); - void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); - void ActOnFinishDelayedMemberInitializers(Decl *Record); - void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, - CachedTokens &Toks); - void UnmarkAsLateParsedTemplate(FunctionDecl *FD); - bool IsInsideALocalClassWithinATemplateFunction(); - - Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, - Expr *AssertExpr, - Expr *AssertMessageExpr, - SourceLocation RParenLoc); - Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, - Expr *AssertExpr, - StringLiteral *AssertMessageExpr, - SourceLocation RParenLoc, - bool Failed); - - FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart, - SourceLocation FriendLoc, - TypeSourceInfo *TSInfo); - Decl *ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, - MultiTemplateParamsArg TemplateParams); - NamedDecl *ActOnFriendFunctionDecl(Scope *S, Declarator &D, - MultiTemplateParamsArg TemplateParams); - - QualType CheckConstructorDeclarator(Declarator &D, QualType R, - StorageClass& SC); - void CheckConstructor(CXXConstructorDecl *Constructor); - QualType CheckDestructorDeclarator(Declarator &D, QualType R, - StorageClass& SC); - bool CheckDestructor(CXXDestructorDecl *Destructor); - void CheckConversionDeclarator(Declarator &D, QualType &R, - StorageClass& SC); - Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); - - void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); - void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD, - const FunctionProtoType *T); - void CheckDelayedMemberExceptionSpecs(); - - //===--------------------------------------------------------------------===// - // C++ Derived Classes - // - - /// ActOnBaseSpecifier - Parsed a base specifier - CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class, - SourceRange SpecifierRange, - bool Virtual, AccessSpecifier Access, - TypeSourceInfo *TInfo, - SourceLocation EllipsisLoc); - - BaseResult ActOnBaseSpecifier(Decl *classdecl, - SourceRange SpecifierRange, - ParsedAttributes &Attrs, - bool Virtual, AccessSpecifier Access, - ParsedType basetype, - SourceLocation BaseLoc, - SourceLocation EllipsisLoc); - - bool AttachBaseSpecifiers(CXXRecordDecl *Class, - MutableArrayRef<CXXBaseSpecifier *> Bases); - void ActOnBaseSpecifiers(Decl *ClassDecl, - MutableArrayRef<CXXBaseSpecifier *> Bases); - - bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base); - bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, - CXXBasePaths &Paths); - - // FIXME: I don't like this name. - void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); - - bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, - SourceLocation Loc, SourceRange Range, - CXXCastPath *BasePath = nullptr, - bool IgnoreAccess = false); - bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, - unsigned InaccessibleBaseID, - unsigned AmbigiousBaseConvID, - SourceLocation Loc, SourceRange Range, - DeclarationName Name, - CXXCastPath *BasePath); - - std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths); - - bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New, - const CXXMethodDecl *Old); - - /// CheckOverridingFunctionReturnType - Checks whether the return types are - /// covariant, according to C++ [class.virtual]p5. - bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New, - const CXXMethodDecl *Old); - - /// CheckOverridingFunctionExceptionSpec - Checks whether the exception - /// spec is a subset of base spec. - bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, - const CXXMethodDecl *Old); - - bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); - - /// CheckOverrideControl - Check C++11 override control semantics. - void CheckOverrideControl(NamedDecl *D); - - /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was - /// not used in the declaration of an overriding method. - void DiagnoseAbsenceOfOverrideControl(NamedDecl *D); - - /// CheckForFunctionMarkedFinal - Checks whether a virtual member function - /// overrides a virtual member function marked 'final', according to - /// C++11 [class.virtual]p4. - bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, - const CXXMethodDecl *Old); - - - //===--------------------------------------------------------------------===// - // C++ Access Control - // - - enum AccessResult { - AR_accessible, - AR_inaccessible, - AR_dependent, - AR_delayed - }; - - bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, - NamedDecl *PrevMemberDecl, - AccessSpecifier LexicalAS); - - AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, - DeclAccessPair FoundDecl); - AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, - DeclAccessPair FoundDecl); - AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, - SourceRange PlacementRange, - CXXRecordDecl *NamingClass, - DeclAccessPair FoundDecl, - bool Diagnose = true); - AccessResult CheckConstructorAccess(SourceLocation Loc, - CXXConstructorDecl *D, - const InitializedEntity &Entity, - AccessSpecifier Access, - bool IsCopyBindingRefToTemp = false); - AccessResult CheckConstructorAccess(SourceLocation Loc, - CXXConstructorDecl *D, - const InitializedEntity &Entity, - AccessSpecifier Access, - const PartialDiagnostic &PDiag); - AccessResult CheckDestructorAccess(SourceLocation Loc, - CXXDestructorDecl *Dtor, - const PartialDiagnostic &PDiag, - QualType objectType = QualType()); - AccessResult CheckFriendAccess(NamedDecl *D); - AccessResult CheckMemberAccess(SourceLocation UseLoc, - CXXRecordDecl *NamingClass, - DeclAccessPair Found); - AccessResult CheckMemberOperatorAccess(SourceLocation Loc, - Expr *ObjectExpr, - Expr *ArgExpr, - DeclAccessPair FoundDecl); - AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, - DeclAccessPair FoundDecl); - AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, - QualType Base, QualType Derived, - const CXXBasePath &Path, - unsigned DiagID, - bool ForceCheck = false, - bool ForceUnprivileged = false); - void CheckLookupAccess(const LookupResult &R); - bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx); - bool isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl, - AccessSpecifier access, - QualType objectType); - - void HandleDependentAccessCheck(const DependentDiagnostic &DD, - const MultiLevelTemplateArgumentList &TemplateArgs); - void PerformDependentDiagnostics(const DeclContext *Pattern, - const MultiLevelTemplateArgumentList &TemplateArgs); - - void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); - - /// \brief When true, access checking violations are treated as SFINAE - /// failures rather than hard errors. - bool AccessCheckingSFINAE; - - enum AbstractDiagSelID { - AbstractNone = -1, - AbstractReturnType, - AbstractParamType, - AbstractVariableType, - AbstractFieldType, - AbstractIvarType, - AbstractSynthesizedIvarType, - AbstractArrayType - }; - - bool isAbstractType(SourceLocation Loc, QualType T); - bool RequireNonAbstractType(SourceLocation Loc, QualType T, - TypeDiagnoser &Diagnoser); - template <typename... Ts> - bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, - const Ts &...Args) { - BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); - return RequireNonAbstractType(Loc, T, Diagnoser); - } - - void DiagnoseAbstractType(const CXXRecordDecl *RD); - - //===--------------------------------------------------------------------===// - // C++ Overloaded Operators [C++ 13.5] - // - - bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl); - - bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl); - - //===--------------------------------------------------------------------===// - // C++ Templates [C++ 14] - // - void FilterAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates = true); - bool hasAnyAcceptableTemplateNames(LookupResult &R, - bool AllowFunctionTemplates = true); - - void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, - QualType ObjectType, bool EnteringContext, - bool &MemberOfUnknownSpecialization); - - TemplateNameKind isTemplateName(Scope *S, - CXXScopeSpec &SS, - bool hasTemplateKeyword, - UnqualifiedId &Name, - ParsedType ObjectType, - bool EnteringContext, - TemplateTy &Template, - bool &MemberOfUnknownSpecialization); - - bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, - SourceLocation IILoc, - Scope *S, - const CXXScopeSpec *SS, - TemplateTy &SuggestedTemplate, - TemplateNameKind &SuggestedKind); - - void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl); - TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl); - - Decl *ActOnTypeParameter(Scope *S, bool Typename, - SourceLocation EllipsisLoc, - SourceLocation KeyLoc, - IdentifierInfo *ParamName, - SourceLocation ParamNameLoc, - unsigned Depth, unsigned Position, - SourceLocation EqualLoc, - ParsedType DefaultArg); - - QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); - Decl *ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, - unsigned Depth, - unsigned Position, - SourceLocation EqualLoc, - Expr *DefaultArg); - Decl *ActOnTemplateTemplateParameter(Scope *S, - SourceLocation TmpLoc, - TemplateParameterList *Params, - SourceLocation EllipsisLoc, - IdentifierInfo *ParamName, - SourceLocation ParamNameLoc, - unsigned Depth, - unsigned Position, - SourceLocation EqualLoc, - ParsedTemplateArgument DefaultArg); - - TemplateParameterList * - ActOnTemplateParameterList(unsigned Depth, - SourceLocation ExportLoc, - SourceLocation TemplateLoc, - SourceLocation LAngleLoc, - ArrayRef<Decl *> Params, - SourceLocation RAngleLoc); - - /// \brief The context in which we are checking a template parameter list. - enum TemplateParamListContext { - TPC_ClassTemplate, - TPC_VarTemplate, - TPC_FunctionTemplate, - TPC_ClassTemplateMember, - TPC_FriendClassTemplate, - TPC_FriendFunctionTemplate, - TPC_FriendFunctionTemplateDefinition, - TPC_TypeAliasTemplate - }; - - bool CheckTemplateParameterList(TemplateParameterList *NewParams, - TemplateParameterList *OldParams, - TemplateParamListContext TPC); - TemplateParameterList *MatchTemplateParametersToScopeSpecifier( - SourceLocation DeclStartLoc, SourceLocation DeclLoc, - const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, - ArrayRef<TemplateParameterList *> ParamLists, - bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid); - - DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, - SourceLocation KWLoc, CXXScopeSpec &SS, - IdentifierInfo *Name, SourceLocation NameLoc, - AttributeList *Attr, - TemplateParameterList *TemplateParams, - AccessSpecifier AS, - SourceLocation ModulePrivateLoc, - SourceLocation FriendLoc, - unsigned NumOuterTemplateParamLists, - TemplateParameterList **OuterTemplateParamLists, - SkipBodyInfo *SkipBody = nullptr); - - void translateTemplateArguments(const ASTTemplateArgsPtr &In, - TemplateArgumentListInfo &Out); - - void NoteAllFoundTemplates(TemplateName Name); - - QualType CheckTemplateIdType(TemplateName Template, - SourceLocation TemplateLoc, - TemplateArgumentListInfo &TemplateArgs); - - TypeResult - ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - TemplateTy Template, SourceLocation TemplateLoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgs, - SourceLocation RAngleLoc, - bool IsCtorOrDtorName = false); - - /// \brief Parsed an elaborated-type-specifier that refers to a template-id, - /// such as \c class T::template apply<U>. - TypeResult ActOnTagTemplateIdType(TagUseKind TUK, - TypeSpecifierType TagSpec, - SourceLocation TagLoc, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - TemplateTy TemplateD, - SourceLocation TemplateLoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation RAngleLoc); - - DeclResult ActOnVarTemplateSpecialization( - Scope *S, Declarator &D, TypeSourceInfo *DI, - SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, - StorageClass SC, bool IsPartialSpecialization); - - DeclResult CheckVarTemplateId(VarTemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation TemplateNameLoc, - const TemplateArgumentListInfo &TemplateArgs); - - ExprResult CheckVarTemplateId(const CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - VarTemplateDecl *Template, - SourceLocation TemplateLoc, - const TemplateArgumentListInfo *TemplateArgs); - - ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - LookupResult &R, - bool RequiresADL, - const TemplateArgumentListInfo *TemplateArgs); - - ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs); - - TemplateNameKind ActOnDependentTemplateName(Scope *S, - CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Name, - ParsedType ObjectType, - bool EnteringContext, - TemplateTy &Template); - - DeclResult - ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, - SourceLocation KWLoc, - SourceLocation ModulePrivateLoc, - TemplateIdAnnotation &TemplateId, - AttributeList *Attr, - MultiTemplateParamsArg TemplateParameterLists, - SkipBodyInfo *SkipBody = nullptr); - - Decl *ActOnTemplateDeclarator(Scope *S, - MultiTemplateParamsArg TemplateParameterLists, - Declarator &D); - - bool - CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, - TemplateSpecializationKind NewTSK, - NamedDecl *PrevDecl, - TemplateSpecializationKind PrevTSK, - SourceLocation PrevPtOfInstantiation, - bool &SuppressNew); - - bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, - const TemplateArgumentListInfo &ExplicitTemplateArgs, - LookupResult &Previous); - - bool CheckFunctionTemplateSpecialization(FunctionDecl *FD, - TemplateArgumentListInfo *ExplicitTemplateArgs, - LookupResult &Previous); - bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous); - - DeclResult - ActOnExplicitInstantiation(Scope *S, - SourceLocation ExternLoc, - SourceLocation TemplateLoc, - unsigned TagSpec, - SourceLocation KWLoc, - const CXXScopeSpec &SS, - TemplateTy Template, - SourceLocation TemplateNameLoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgs, - SourceLocation RAngleLoc, - AttributeList *Attr); - - DeclResult - ActOnExplicitInstantiation(Scope *S, - SourceLocation ExternLoc, - SourceLocation TemplateLoc, - unsigned TagSpec, - SourceLocation KWLoc, - CXXScopeSpec &SS, - IdentifierInfo *Name, - SourceLocation NameLoc, - AttributeList *Attr); - - DeclResult ActOnExplicitInstantiation(Scope *S, - SourceLocation ExternLoc, - SourceLocation TemplateLoc, - Declarator &D); - - TemplateArgumentLoc - SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - Decl *Param, - SmallVectorImpl<TemplateArgument> - &Converted, - bool &HasDefaultArg); - - /// \brief Specifies the context in which a particular template - /// argument is being checked. - enum CheckTemplateArgumentKind { - /// \brief The template argument was specified in the code or was - /// instantiated with some deduced template arguments. - CTAK_Specified, - - /// \brief The template argument was deduced via template argument - /// deduction. - CTAK_Deduced, - - /// \brief The template argument was deduced from an array bound - /// via template argument deduction. - CTAK_DeducedFromArrayBound - }; - - bool CheckTemplateArgument(NamedDecl *Param, - TemplateArgumentLoc &Arg, - NamedDecl *Template, - SourceLocation TemplateLoc, - SourceLocation RAngleLoc, - unsigned ArgumentPackIndex, - SmallVectorImpl<TemplateArgument> &Converted, - CheckTemplateArgumentKind CTAK = CTAK_Specified); - - /// \brief Check that the given template arguments can be be provided to - /// the given template, converting the arguments along the way. - /// - /// \param Template The template to which the template arguments are being - /// provided. - /// - /// \param TemplateLoc The location of the template name in the source. - /// - /// \param TemplateArgs The list of template arguments. If the template is - /// a template template parameter, this function may extend the set of - /// template arguments to also include substituted, defaulted template - /// arguments. - /// - /// \param PartialTemplateArgs True if the list of template arguments is - /// intentionally partial, e.g., because we're checking just the initial - /// set of template arguments. - /// - /// \param Converted Will receive the converted, canonicalized template - /// arguments. - /// - /// \returns true if an error occurred, false otherwise. - bool CheckTemplateArgumentList(TemplateDecl *Template, - SourceLocation TemplateLoc, - TemplateArgumentListInfo &TemplateArgs, - bool PartialTemplateArgs, - SmallVectorImpl<TemplateArgument> &Converted); - - bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, - TemplateArgumentLoc &Arg, - SmallVectorImpl<TemplateArgument> &Converted); - - bool CheckTemplateArgument(TemplateTypeParmDecl *Param, - TypeSourceInfo *Arg); - ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param, - QualType InstantiatedParamType, Expr *Arg, - TemplateArgument &Converted, - CheckTemplateArgumentKind CTAK = CTAK_Specified); - bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, - TemplateArgumentLoc &Arg, - unsigned ArgumentPackIndex); - - ExprResult - BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, - QualType ParamType, - SourceLocation Loc); - ExprResult - BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, - SourceLocation Loc); - - /// \brief Enumeration describing how template parameter lists are compared - /// for equality. - enum TemplateParameterListEqualKind { - /// \brief We are matching the template parameter lists of two templates - /// that might be redeclarations. - /// - /// \code - /// template<typename T> struct X; - /// template<typename T> struct X; - /// \endcode - TPL_TemplateMatch, - - /// \brief We are matching the template parameter lists of two template - /// template parameters as part of matching the template parameter lists - /// of two templates that might be redeclarations. - /// - /// \code - /// template<template<int I> class TT> struct X; - /// template<template<int Value> class Other> struct X; - /// \endcode - TPL_TemplateTemplateParmMatch, - - /// \brief We are matching the template parameter lists of a template - /// template argument against the template parameter lists of a template - /// template parameter. - /// - /// \code - /// template<template<int Value> class Metafun> struct X; - /// template<int Value> struct integer_c; - /// X<integer_c> xic; - /// \endcode - TPL_TemplateTemplateArgumentMatch - }; - - bool TemplateParameterListsAreEqual(TemplateParameterList *New, - TemplateParameterList *Old, - bool Complain, - TemplateParameterListEqualKind Kind, - SourceLocation TemplateArgLoc - = SourceLocation()); - - bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams); - - /// \brief Called when the parser has parsed a C++ typename - /// specifier, e.g., "typename T::type". - /// - /// \param S The scope in which this typename type occurs. - /// \param TypenameLoc the location of the 'typename' keyword - /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). - /// \param II the identifier we're retrieving (e.g., 'type' in the example). - /// \param IdLoc the location of the identifier. - TypeResult - ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, - const CXXScopeSpec &SS, const IdentifierInfo &II, - SourceLocation IdLoc); - - /// \brief Called when the parser has parsed a C++ typename - /// specifier that ends in a template-id, e.g., - /// "typename MetaFun::template apply<T1, T2>". - /// - /// \param S The scope in which this typename type occurs. - /// \param TypenameLoc the location of the 'typename' keyword - /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). - /// \param TemplateLoc the location of the 'template' keyword, if any. - /// \param TemplateName The template name. - /// \param TemplateNameLoc The location of the template name. - /// \param LAngleLoc The location of the opening angle bracket ('<'). - /// \param TemplateArgs The template arguments. - /// \param RAngleLoc The location of the closing angle bracket ('>'). - TypeResult - ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, - const CXXScopeSpec &SS, - SourceLocation TemplateLoc, - TemplateTy TemplateName, - SourceLocation TemplateNameLoc, - SourceLocation LAngleLoc, - ASTTemplateArgsPtr TemplateArgs, - SourceLocation RAngleLoc); - - QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, - SourceLocation KeywordLoc, - NestedNameSpecifierLoc QualifierLoc, - const IdentifierInfo &II, - SourceLocation IILoc); - - TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, - SourceLocation Loc, - DeclarationName Name); - bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS); - - ExprResult RebuildExprInCurrentInstantiation(Expr *E); - bool RebuildTemplateParamsInCurrentInstantiation( - TemplateParameterList *Params); - - std::string - getTemplateArgumentBindingsText(const TemplateParameterList *Params, - const TemplateArgumentList &Args); - - std::string - getTemplateArgumentBindingsText(const TemplateParameterList *Params, - const TemplateArgument *Args, - unsigned NumArgs); - - //===--------------------------------------------------------------------===// - // C++ Variadic Templates (C++0x [temp.variadic]) - //===--------------------------------------------------------------------===// - - /// Determine whether an unexpanded parameter pack might be permitted in this - /// location. Useful for error recovery. - bool isUnexpandedParameterPackPermitted(); - - /// \brief The context in which an unexpanded parameter pack is - /// being diagnosed. - /// - /// Note that the values of this enumeration line up with the first - /// argument to the \c err_unexpanded_parameter_pack diagnostic. - enum UnexpandedParameterPackContext { - /// \brief An arbitrary expression. - UPPC_Expression = 0, - - /// \brief The base type of a class type. - UPPC_BaseType, - - /// \brief The type of an arbitrary declaration. - UPPC_DeclarationType, - - /// \brief The type of a data member. - UPPC_DataMemberType, - - /// \brief The size of a bit-field. - UPPC_BitFieldWidth, - - /// \brief The expression in a static assertion. - UPPC_StaticAssertExpression, - - /// \brief The fixed underlying type of an enumeration. - UPPC_FixedUnderlyingType, - - /// \brief The enumerator value. - UPPC_EnumeratorValue, - - /// \brief A using declaration. - UPPC_UsingDeclaration, - - /// \brief A friend declaration. - UPPC_FriendDeclaration, - - /// \brief A declaration qualifier. - UPPC_DeclarationQualifier, - - /// \brief An initializer. - UPPC_Initializer, - - /// \brief A default argument. - UPPC_DefaultArgument, - - /// \brief The type of a non-type template parameter. - UPPC_NonTypeTemplateParameterType, - - /// \brief The type of an exception. - UPPC_ExceptionType, - - /// \brief Partial specialization. - UPPC_PartialSpecialization, - - /// \brief Microsoft __if_exists. - UPPC_IfExists, - - /// \brief Microsoft __if_not_exists. - UPPC_IfNotExists, - - /// \brief Lambda expression. - UPPC_Lambda, - - /// \brief Block expression, - UPPC_Block - }; - - /// \brief Diagnose unexpanded parameter packs. - /// - /// \param Loc The location at which we should emit the diagnostic. - /// - /// \param UPPC The context in which we are diagnosing unexpanded - /// parameter packs. - /// - /// \param Unexpanded the set of unexpanded parameter packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc, - UnexpandedParameterPackContext UPPC, - ArrayRef<UnexpandedParameterPack> Unexpanded); - - /// \brief If the given type contains an unexpanded parameter pack, - /// diagnose the error. - /// - /// \param Loc The source location where a diagnostc should be emitted. - /// - /// \param T The type that is being checked for unexpanded parameter - /// packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, - UnexpandedParameterPackContext UPPC); - - /// \brief If the given expression contains an unexpanded parameter - /// pack, diagnose the error. - /// - /// \param E The expression that is being checked for unexpanded - /// parameter packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPack(Expr *E, - UnexpandedParameterPackContext UPPC = UPPC_Expression); - - /// \brief If the given nested-name-specifier contains an unexpanded - /// parameter pack, diagnose the error. - /// - /// \param SS The nested-name-specifier that is being checked for - /// unexpanded parameter packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, - UnexpandedParameterPackContext UPPC); - - /// \brief If the given name contains an unexpanded parameter pack, - /// diagnose the error. - /// - /// \param NameInfo The name (with source location information) that - /// is being checked for unexpanded parameter packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, - UnexpandedParameterPackContext UPPC); - - /// \brief If the given template name contains an unexpanded parameter pack, - /// diagnose the error. - /// - /// \param Loc The location of the template name. - /// - /// \param Template The template name that is being checked for unexpanded - /// parameter packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, - TemplateName Template, - UnexpandedParameterPackContext UPPC); - - /// \brief If the given template argument contains an unexpanded parameter - /// pack, diagnose the error. - /// - /// \param Arg The template argument that is being checked for unexpanded - /// parameter packs. - /// - /// \returns true if an error occurred, false otherwise. - bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, - UnexpandedParameterPackContext UPPC); - - /// \brief Collect the set of unexpanded parameter packs within the given - /// template argument. - /// - /// \param Arg The template argument that will be traversed to find - /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(TemplateArgument Arg, - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); - - /// \brief Collect the set of unexpanded parameter packs within the given - /// template argument. - /// - /// \param Arg The template argument that will be traversed to find - /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); - - /// \brief Collect the set of unexpanded parameter packs within the given - /// type. - /// - /// \param T The type that will be traversed to find - /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(QualType T, - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); - - /// \brief Collect the set of unexpanded parameter packs within the given - /// type. - /// - /// \param TL The type that will be traversed to find - /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(TypeLoc TL, - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); - - /// \brief Collect the set of unexpanded parameter packs within the given - /// nested-name-specifier. - /// - /// \param SS The nested-name-specifier that will be traversed to find - /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(CXXScopeSpec &SS, - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); - - /// \brief Collect the set of unexpanded parameter packs within the given - /// name. - /// - /// \param NameInfo The name that will be traversed to find - /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo, - SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); - - /// \brief Invoked when parsing a template argument followed by an - /// ellipsis, which creates a pack expansion. - /// - /// \param Arg The template argument preceding the ellipsis, which - /// may already be invalid. - /// - /// \param EllipsisLoc The location of the ellipsis. - ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, - SourceLocation EllipsisLoc); - - /// \brief Invoked when parsing a type followed by an ellipsis, which - /// creates a pack expansion. - /// - /// \param Type The type preceding the ellipsis, which will become - /// the pattern of the pack expansion. - /// - /// \param EllipsisLoc The location of the ellipsis. - TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc); - - /// \brief Construct a pack expansion type from the pattern of the pack - /// expansion. - TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern, - SourceLocation EllipsisLoc, - Optional<unsigned> NumExpansions); - - /// \brief Construct a pack expansion type from the pattern of the pack - /// expansion. - QualType CheckPackExpansion(QualType Pattern, - SourceRange PatternRange, - SourceLocation EllipsisLoc, - Optional<unsigned> NumExpansions); - - /// \brief Invoked when parsing an expression followed by an ellipsis, which - /// creates a pack expansion. - /// - /// \param Pattern The expression preceding the ellipsis, which will become - /// the pattern of the pack expansion. - /// - /// \param EllipsisLoc The location of the ellipsis. - ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc); - - /// \brief Invoked when parsing an expression followed by an ellipsis, which - /// creates a pack expansion. - /// - /// \param Pattern The expression preceding the ellipsis, which will become - /// the pattern of the pack expansion. - /// - /// \param EllipsisLoc The location of the ellipsis. - ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, - Optional<unsigned> NumExpansions); - - /// \brief Determine whether we could expand a pack expansion with the - /// given set of parameter packs into separate arguments by repeatedly - /// transforming the pattern. - /// - /// \param EllipsisLoc The location of the ellipsis that identifies the - /// pack expansion. - /// - /// \param PatternRange The source range that covers the entire pattern of - /// the pack expansion. - /// - /// \param Unexpanded The set of unexpanded parameter packs within the - /// pattern. - /// - /// \param ShouldExpand Will be set to \c true if the transformer should - /// expand the corresponding pack expansions into separate arguments. When - /// set, \c NumExpansions must also be set. - /// - /// \param RetainExpansion Whether the caller should add an unexpanded - /// pack expansion after all of the expanded arguments. This is used - /// when extending explicitly-specified template argument packs per - /// C++0x [temp.arg.explicit]p9. - /// - /// \param NumExpansions The number of separate arguments that will be in - /// the expanded form of the corresponding pack expansion. This is both an - /// input and an output parameter, which can be set by the caller if the - /// number of expansions is known a priori (e.g., due to a prior substitution) - /// and will be set by the callee when the number of expansions is known. - /// The callee must set this value when \c ShouldExpand is \c true; it may - /// set this value in other cases. - /// - /// \returns true if an error occurred (e.g., because the parameter packs - /// are to be instantiated with arguments of different lengths), false - /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) - /// must be set. - bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, - SourceRange PatternRange, - ArrayRef<UnexpandedParameterPack> Unexpanded, - const MultiLevelTemplateArgumentList &TemplateArgs, - bool &ShouldExpand, - bool &RetainExpansion, - Optional<unsigned> &NumExpansions); - - /// \brief Determine the number of arguments in the given pack expansion - /// type. - /// - /// This routine assumes that the number of arguments in the expansion is - /// consistent across all of the unexpanded parameter packs in its pattern. - /// - /// Returns an empty Optional if the type can't be expanded. - Optional<unsigned> getNumArgumentsInExpansion(QualType T, - const MultiLevelTemplateArgumentList &TemplateArgs); - - /// \brief Determine whether the given declarator contains any unexpanded - /// parameter packs. - /// - /// This routine is used by the parser to disambiguate function declarators - /// with an ellipsis prior to the ')', e.g., - /// - /// \code - /// void f(T...); - /// \endcode - /// - /// To determine whether we have an (unnamed) function parameter pack or - /// a variadic function. - /// - /// \returns true if the declarator contains any unexpanded parameter packs, - /// false otherwise. - bool containsUnexpandedParameterPacks(Declarator &D); - - /// \brief Returns the pattern of the pack expansion for a template argument. - /// - /// \param OrigLoc The template argument to expand. - /// - /// \param Ellipsis Will be set to the location of the ellipsis. - /// - /// \param NumExpansions Will be set to the number of expansions that will - /// be generated from this pack expansion, if known a priori. - TemplateArgumentLoc getTemplateArgumentPackExpansionPattern( - TemplateArgumentLoc OrigLoc, - SourceLocation &Ellipsis, - Optional<unsigned> &NumExpansions) const; - - //===--------------------------------------------------------------------===// - // C++ Template Argument Deduction (C++ [temp.deduct]) - //===--------------------------------------------------------------------===// - - QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType); - - /// \brief Describes the result of template argument deduction. - /// - /// The TemplateDeductionResult enumeration describes the result of - /// template argument deduction, as returned from - /// DeduceTemplateArguments(). The separate TemplateDeductionInfo - /// structure provides additional information about the results of - /// template argument deduction, e.g., the deduced template argument - /// list (if successful) or the specific template parameters or - /// deduced arguments that were involved in the failure. - enum TemplateDeductionResult { - /// \brief Template argument deduction was successful. - TDK_Success = 0, - /// \brief The declaration was invalid; do nothing. - TDK_Invalid, - /// \brief Template argument deduction exceeded the maximum template - /// instantiation depth (which has already been diagnosed). - TDK_InstantiationDepth, - /// \brief Template argument deduction did not deduce a value - /// for every template parameter. - TDK_Incomplete, - /// \brief Template argument deduction produced inconsistent - /// deduced values for the given template parameter. - TDK_Inconsistent, - /// \brief Template argument deduction failed due to inconsistent - /// cv-qualifiers on a template parameter type that would - /// otherwise be deduced, e.g., we tried to deduce T in "const T" - /// but were given a non-const "X". - TDK_Underqualified, - /// \brief Substitution of the deduced template argument values - /// resulted in an error. - TDK_SubstitutionFailure, - /// \brief After substituting deduced template arguments, a dependent - /// parameter type did not match the corresponding argument. - TDK_DeducedMismatch, - /// \brief A non-depnedent component of the parameter did not match the - /// corresponding component of the argument. - TDK_NonDeducedMismatch, - /// \brief When performing template argument deduction for a function - /// template, there were too many call arguments. - TDK_TooManyArguments, - /// \brief When performing template argument deduction for a function - /// template, there were too few call arguments. - TDK_TooFewArguments, - /// \brief The explicitly-specified template arguments were not valid - /// template arguments for the given template. - TDK_InvalidExplicitArguments, - /// \brief The arguments included an overloaded function name that could - /// not be resolved to a suitable function. - TDK_FailedOverloadResolution, - /// \brief Deduction failed; that's all we know. - TDK_MiscellaneousDeductionFailure - }; - - TemplateDeductionResult - DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, - const TemplateArgumentList &TemplateArgs, - sema::TemplateDeductionInfo &Info); - - TemplateDeductionResult - DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, - const TemplateArgumentList &TemplateArgs, - sema::TemplateDeductionInfo &Info); - - TemplateDeductionResult SubstituteExplicitTemplateArguments( - FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo &ExplicitTemplateArgs, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType, - sema::TemplateDeductionInfo &Info); - - /// brief A function argument from which we performed template argument - // deduction for a call. - struct OriginalCallArg { - OriginalCallArg(QualType OriginalParamType, - unsigned ArgIdx, - QualType OriginalArgType) - : OriginalParamType(OriginalParamType), ArgIdx(ArgIdx), - OriginalArgType(OriginalArgType) { } - - QualType OriginalParamType; - unsigned ArgIdx; - QualType OriginalArgType; - }; - - TemplateDeductionResult - FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - unsigned NumExplicitlySpecified, - FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info, - SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, - bool PartialOverloading = false); - - TemplateDeductionResult - DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef<Expr *> Args, - FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info, - bool PartialOverloading = false); - - TemplateDeductionResult - DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo *ExplicitTemplateArgs, - QualType ArgFunctionType, - FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info, - bool InOverloadResolution = false); - - TemplateDeductionResult - DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - QualType ToType, - CXXConversionDecl *&Specialization, - sema::TemplateDeductionInfo &Info); - - TemplateDeductionResult - DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo *ExplicitTemplateArgs, - FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info, - bool InOverloadResolution = false); - - /// \brief Substitute Replacement for \p auto in \p TypeWithAuto - QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); - /// \brief Substitute Replacement for auto in TypeWithAuto - TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, - QualType Replacement); - - /// \brief Result type of DeduceAutoType. - enum DeduceAutoResult { - DAR_Succeeded, - DAR_Failed, - DAR_FailedAlreadyDiagnosed - }; - - DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, - QualType &Result); - DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, - QualType &Result); - void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); - bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, - bool Diagnose = true); - - QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, - QualType Type, TypeSourceInfo *TSI, - SourceRange Range, bool DirectInit, - Expr *Init); - - TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; - - bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, - SourceLocation ReturnLoc, - Expr *&RetExpr, AutoType *AT); - - FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, - FunctionTemplateDecl *FT2, - SourceLocation Loc, - TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments1, - unsigned NumCallArguments2); - UnresolvedSetIterator - getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, - TemplateSpecCandidateSet &FailedCandidates, - SourceLocation Loc, - const PartialDiagnostic &NoneDiag, - const PartialDiagnostic &AmbigDiag, - const PartialDiagnostic &CandidateDiag, - bool Complain = true, QualType TargetType = QualType()); - - ClassTemplatePartialSpecializationDecl * - getMoreSpecializedPartialSpecialization( - ClassTemplatePartialSpecializationDecl *PS1, - ClassTemplatePartialSpecializationDecl *PS2, - SourceLocation Loc); - - VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization( - VarTemplatePartialSpecializationDecl *PS1, - VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); - - void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, - bool OnlyDeduced, - unsigned Depth, - llvm::SmallBitVector &Used); - void MarkDeducedTemplateParameters( - const FunctionTemplateDecl *FunctionTemplate, - llvm::SmallBitVector &Deduced) { - return MarkDeducedTemplateParameters(Context, FunctionTemplate, Deduced); - } - static void MarkDeducedTemplateParameters(ASTContext &Ctx, - const FunctionTemplateDecl *FunctionTemplate, - llvm::SmallBitVector &Deduced); - - //===--------------------------------------------------------------------===// - // C++ Template Instantiation - // - - MultiLevelTemplateArgumentList - getTemplateInstantiationArgs(NamedDecl *D, - const TemplateArgumentList *Innermost = nullptr, - bool RelativeToPrimary = false, - const FunctionDecl *Pattern = nullptr); - - /// \brief A template instantiation that is currently in progress. - struct ActiveTemplateInstantiation { - /// \brief The kind of template instantiation we are performing - enum InstantiationKind { - /// We are instantiating a template declaration. The entity is - /// the declaration we're instantiating (e.g., a CXXRecordDecl). - TemplateInstantiation, - - /// We are instantiating a default argument for a template - /// parameter. The Entity is the template, and - /// TemplateArgs/NumTemplateArguments provides the template - /// arguments as specified. - /// FIXME: Use a TemplateArgumentList - DefaultTemplateArgumentInstantiation, - - /// We are instantiating a default argument for a function. - /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs - /// provides the template arguments as specified. - DefaultFunctionArgumentInstantiation, - - /// We are substituting explicit template arguments provided for - /// a function template. The entity is a FunctionTemplateDecl. - ExplicitTemplateArgumentSubstitution, - - /// We are substituting template argument determined as part of - /// template argument deduction for either a class template - /// partial specialization or a function template. The - /// Entity is either a ClassTemplatePartialSpecializationDecl or - /// a FunctionTemplateDecl. - DeducedTemplateArgumentSubstitution, - - /// We are substituting prior template arguments into a new - /// template parameter. The template parameter itself is either a - /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl. - PriorTemplateArgumentSubstitution, - - /// We are checking the validity of a default template argument that - /// has been used when naming a template-id. - DefaultTemplateArgumentChecking, - - /// We are instantiating the exception specification for a function - /// template which was deferred until it was needed. - ExceptionSpecInstantiation - } Kind; - - /// \brief The point of instantiation within the source code. - SourceLocation PointOfInstantiation; - - /// \brief The template (or partial specialization) in which we are - /// performing the instantiation, for substitutions of prior template - /// arguments. - NamedDecl *Template; - - /// \brief The entity that is being instantiated. - Decl *Entity; - - /// \brief The list of template arguments we are substituting, if they - /// are not part of the entity. - const TemplateArgument *TemplateArgs; - - /// \brief The number of template arguments in TemplateArgs. - unsigned NumTemplateArgs; - - /// \brief The template deduction info object associated with the - /// substitution or checking of explicit or deduced template arguments. - sema::TemplateDeductionInfo *DeductionInfo; - - /// \brief The source range that covers the construct that cause - /// the instantiation, e.g., the template-id that causes a class - /// template instantiation. - SourceRange InstantiationRange; - - ActiveTemplateInstantiation() - : Kind(TemplateInstantiation), Template(nullptr), Entity(nullptr), - TemplateArgs(nullptr), NumTemplateArgs(0), DeductionInfo(nullptr) {} - - /// \brief Determines whether this template is an actual instantiation - /// that should be counted toward the maximum instantiation depth. - bool isInstantiationRecord() const; - - friend bool operator==(const ActiveTemplateInstantiation &X, - const ActiveTemplateInstantiation &Y) { - if (X.Kind != Y.Kind) - return false; - - if (X.Entity != Y.Entity) - return false; - - switch (X.Kind) { - case TemplateInstantiation: - case ExceptionSpecInstantiation: - return true; - - case PriorTemplateArgumentSubstitution: - case DefaultTemplateArgumentChecking: - return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs; - - case DefaultTemplateArgumentInstantiation: - case ExplicitTemplateArgumentSubstitution: - case DeducedTemplateArgumentSubstitution: - case DefaultFunctionArgumentInstantiation: - return X.TemplateArgs == Y.TemplateArgs; - - } - - llvm_unreachable("Invalid InstantiationKind!"); - } - - friend bool operator!=(const ActiveTemplateInstantiation &X, - const ActiveTemplateInstantiation &Y) { - return !(X == Y); - } - }; - - /// \brief List of active template instantiations. - /// - /// This vector is treated as a stack. As one template instantiation - /// requires another template instantiation, additional - /// instantiations are pushed onto the stack up to a - /// user-configurable limit LangOptions::InstantiationDepth. - SmallVector<ActiveTemplateInstantiation, 16> - ActiveTemplateInstantiations; - - /// \brief Extra modules inspected when performing a lookup during a template - /// instantiation. Computed lazily. - SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules; - - /// \brief Cache of additional modules that should be used for name lookup - /// within the current template instantiation. Computed lazily; use - /// getLookupModules() to get a complete set. - llvm::DenseSet<Module*> LookupModulesCache; - - /// \brief Get the set of additional modules that should be checked during - /// name lookup. A module and its imports become visible when instanting a - /// template defined within it. - llvm::DenseSet<Module*> &getLookupModules(); - - /// \brief Whether we are in a SFINAE context that is not associated with - /// template instantiation. - /// - /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside - /// of a template instantiation or template argument deduction. - bool InNonInstantiationSFINAEContext; - - /// \brief The number of ActiveTemplateInstantiation entries in - /// \c ActiveTemplateInstantiations that are not actual instantiations and, - /// therefore, should not be counted as part of the instantiation depth. - unsigned NonInstantiationEntries; - - /// \brief The last template from which a template instantiation - /// error or warning was produced. - /// - /// This value is used to suppress printing of redundant template - /// instantiation backtraces when there are multiple errors in the - /// same instantiation. FIXME: Does this belong in Sema? It's tough - /// to implement it anywhere else. - ActiveTemplateInstantiation LastTemplateInstantiationErrorContext; - - /// \brief The current index into pack expansion arguments that will be - /// used for substitution of parameter packs. - /// - /// The pack expansion index will be -1 to indicate that parameter packs - /// should be instantiated as themselves. Otherwise, the index specifies - /// which argument within the parameter pack will be used for substitution. - int ArgumentPackSubstitutionIndex; - - /// \brief RAII object used to change the argument pack substitution index - /// within a \c Sema object. - /// - /// See \c ArgumentPackSubstitutionIndex for more information. - class ArgumentPackSubstitutionIndexRAII { - Sema &Self; - int OldSubstitutionIndex; - - public: - ArgumentPackSubstitutionIndexRAII(Sema &Self, int NewSubstitutionIndex) - : Self(Self), OldSubstitutionIndex(Self.ArgumentPackSubstitutionIndex) { - Self.ArgumentPackSubstitutionIndex = NewSubstitutionIndex; - } - - ~ArgumentPackSubstitutionIndexRAII() { - Self.ArgumentPackSubstitutionIndex = OldSubstitutionIndex; - } - }; - - friend class ArgumentPackSubstitutionRAII; - - /// \brief For each declaration that involved template argument deduction, the - /// set of diagnostics that were suppressed during that template argument - /// deduction. - /// - /// FIXME: Serialize this structure to the AST file. - typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > - SuppressedDiagnosticsMap; - SuppressedDiagnosticsMap SuppressedDiagnostics; - - /// \brief A stack object to be created when performing template - /// instantiation. - /// - /// Construction of an object of type \c InstantiatingTemplate - /// pushes the current instantiation onto the stack of active - /// instantiations. If the size of this stack exceeds the maximum - /// number of recursive template instantiations, construction - /// produces an error and evaluates true. - /// - /// Destruction of this object will pop the named instantiation off - /// the stack. - struct InstantiatingTemplate { - /// \brief Note that we are instantiating a class template, - /// function template, variable template, alias template, - /// or a member thereof. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - Decl *Entity, - SourceRange InstantiationRange = SourceRange()); - - struct ExceptionSpecification {}; - /// \brief Note that we are instantiating an exception specification - /// of a function template. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - FunctionDecl *Entity, ExceptionSpecification, - SourceRange InstantiationRange = SourceRange()); - - /// \brief Note that we are instantiating a default argument in a - /// template-id. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange = SourceRange()); - - /// \brief Note that we are instantiating a default argument in a - /// template-id. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - FunctionTemplateDecl *FunctionTemplate, - ArrayRef<TemplateArgument> TemplateArgs, - ActiveTemplateInstantiation::InstantiationKind Kind, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange = SourceRange()); - - /// \brief Note that we are instantiating as part of template - /// argument deduction for a class template partial - /// specialization. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - ClassTemplatePartialSpecializationDecl *PartialSpec, - ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange = SourceRange()); - - /// \brief Note that we are instantiating as part of template - /// argument deduction for a variable template partial - /// specialization. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - VarTemplatePartialSpecializationDecl *PartialSpec, - ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange = SourceRange()); - - /// \brief Note that we are instantiating a default argument for a function - /// parameter. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - ParmVarDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange = SourceRange()); - - /// \brief Note that we are substituting prior template arguments into a - /// non-type parameter. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - NamedDecl *Template, - NonTypeTemplateParmDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange); - - /// \brief Note that we are substituting prior template arguments into a - /// template template parameter. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - NamedDecl *Template, - TemplateTemplateParmDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange); - - /// \brief Note that we are checking the default template argument - /// against the template parameter for a given template-id. - InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, - NamedDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange); - - - /// \brief Note that we have finished instantiating this template. - void Clear(); - - ~InstantiatingTemplate() { Clear(); } - - /// \brief Determines whether we have exceeded the maximum - /// recursive template instantiations. - bool isInvalid() const { return Invalid; } - - private: - Sema &SemaRef; - bool Invalid; - bool SavedInNonInstantiationSFINAEContext; - bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, - SourceRange InstantiationRange); - - InstantiatingTemplate( - Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind, - SourceLocation PointOfInstantiation, SourceRange InstantiationRange, - Decl *Entity, NamedDecl *Template = nullptr, - ArrayRef<TemplateArgument> TemplateArgs = None, - sema::TemplateDeductionInfo *DeductionInfo = nullptr); - - InstantiatingTemplate(const InstantiatingTemplate&) = delete; - - InstantiatingTemplate& - operator=(const InstantiatingTemplate&) = delete; - }; - - void PrintInstantiationStack(); - - /// \brief Determines whether we are currently in a context where - /// template argument substitution failures are not considered - /// errors. - /// - /// \returns An empty \c Optional if we're not in a SFINAE context. - /// Otherwise, contains a pointer that, if non-NULL, contains the nearest - /// template-deduction context object, which can be used to capture - /// diagnostics that will be suppressed. - Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const; - - /// \brief Determines whether we are currently in a context that - /// is not evaluated as per C++ [expr] p5. - bool isUnevaluatedContext() const { - assert(!ExprEvalContexts.empty() && - "Must be in an expression evaluation context"); - return ExprEvalContexts.back().isUnevaluated(); - } - - /// \brief RAII class used to determine whether SFINAE has - /// trapped any errors that occur during template argument - /// deduction. - class SFINAETrap { - Sema &SemaRef; - unsigned PrevSFINAEErrors; - bool PrevInNonInstantiationSFINAEContext; - bool PrevAccessCheckingSFINAE; - - public: - explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false) - : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors), - PrevInNonInstantiationSFINAEContext( - SemaRef.InNonInstantiationSFINAEContext), - PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE) - { - if (!SemaRef.isSFINAEContext()) - SemaRef.InNonInstantiationSFINAEContext = true; - SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE; - } - - ~SFINAETrap() { - SemaRef.NumSFINAEErrors = PrevSFINAEErrors; - SemaRef.InNonInstantiationSFINAEContext - = PrevInNonInstantiationSFINAEContext; - SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE; - } - - /// \brief Determine whether any SFINAE errors have been trapped. - bool hasErrorOccurred() const { - return SemaRef.NumSFINAEErrors > PrevSFINAEErrors; - } - }; - - /// \brief RAII class used to indicate that we are performing provisional - /// semantic analysis to determine the validity of a construct, so - /// typo-correction and diagnostics in the immediate context (not within - /// implicitly-instantiated templates) should be suppressed. - class TentativeAnalysisScope { - Sema &SemaRef; - // FIXME: Using a SFINAETrap for this is a hack. - SFINAETrap Trap; - bool PrevDisableTypoCorrection; - public: - explicit TentativeAnalysisScope(Sema &SemaRef) - : SemaRef(SemaRef), Trap(SemaRef, true), - PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) { - SemaRef.DisableTypoCorrection = true; - } - ~TentativeAnalysisScope() { - SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection; - } - }; - - /// \brief The current instantiation scope used to store local - /// variables. - LocalInstantiationScope *CurrentInstantiationScope; - - /// \brief Tracks whether we are in a context where typo correction is - /// disabled. - bool DisableTypoCorrection; - - /// \brief The number of typos corrected by CorrectTypo. - unsigned TyposCorrected; - - typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet; - typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations; - - /// \brief A cache containing identifiers for which typo correction failed and - /// their locations, so that repeated attempts to correct an identifier in a - /// given location are ignored if typo correction already failed for it. - IdentifierSourceLocations TypoCorrectionFailures; - - /// \brief Worker object for performing CFG-based warnings. - sema::AnalysisBasedWarnings AnalysisWarnings; - threadSafety::BeforeSet *ThreadSafetyDeclCache; - - /// \brief An entity for which implicit template instantiation is required. - /// - /// The source location associated with the declaration is the first place in - /// the source code where the declaration was "used". It is not necessarily - /// the point of instantiation (which will be either before or after the - /// namespace-scope declaration that triggered this implicit instantiation), - /// However, it is the location that diagnostics should generally refer to, - /// because users will need to know what code triggered the instantiation. - typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation; - - /// \brief The queue of implicit template instantiations that are required - /// but have not yet been performed. - std::deque<PendingImplicitInstantiation> PendingInstantiations; - - class SavePendingInstantiationsAndVTableUsesRAII { - public: - SavePendingInstantiationsAndVTableUsesRAII(Sema &S, bool Enabled) - : S(S), Enabled(Enabled) { - if (!Enabled) return; - - SavedPendingInstantiations.swap(S.PendingInstantiations); - SavedVTableUses.swap(S.VTableUses); - } - - ~SavePendingInstantiationsAndVTableUsesRAII() { - if (!Enabled) return; - - // Restore the set of pending vtables. - assert(S.VTableUses.empty() && - "VTableUses should be empty before it is discarded."); - S.VTableUses.swap(SavedVTableUses); - - // Restore the set of pending implicit instantiations. - assert(S.PendingInstantiations.empty() && - "PendingInstantiations should be empty before it is discarded."); - S.PendingInstantiations.swap(SavedPendingInstantiations); - } - - private: - Sema &S; - SmallVector<VTableUse, 16> SavedVTableUses; - std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; - bool Enabled; - }; - - /// \brief The queue of implicit template instantiations that are required - /// and must be performed within the current local scope. - /// - /// This queue is only used for member functions of local classes in - /// templates, which must be instantiated in the same scope as their - /// enclosing function, so that they can reference function-local - /// types, static variables, enumerators, etc. - std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations; - - class SavePendingLocalImplicitInstantiationsRAII { - public: - SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) { - SavedPendingLocalImplicitInstantiations.swap( - S.PendingLocalImplicitInstantiations); - } - - ~SavePendingLocalImplicitInstantiationsRAII() { - assert(S.PendingLocalImplicitInstantiations.empty() && - "there shouldn't be any pending local implicit instantiations"); - SavedPendingLocalImplicitInstantiations.swap( - S.PendingLocalImplicitInstantiations); - } - - private: - Sema &S; - std::deque<PendingImplicitInstantiation> - SavedPendingLocalImplicitInstantiations; - }; - - void PerformPendingInstantiations(bool LocalOnly = false); - - TypeSourceInfo *SubstType(TypeSourceInfo *T, - const MultiLevelTemplateArgumentList &TemplateArgs, - SourceLocation Loc, DeclarationName Entity); - - QualType SubstType(QualType T, - const MultiLevelTemplateArgumentList &TemplateArgs, - SourceLocation Loc, DeclarationName Entity); - - TypeSourceInfo *SubstType(TypeLoc TL, - const MultiLevelTemplateArgumentList &TemplateArgs, - SourceLocation Loc, DeclarationName Entity); - - TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T, - const MultiLevelTemplateArgumentList &TemplateArgs, - SourceLocation Loc, - DeclarationName Entity, - CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals); - void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, - const MultiLevelTemplateArgumentList &Args); - ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, - const MultiLevelTemplateArgumentList &TemplateArgs, - int indexAdjustment, - Optional<unsigned> NumExpansions, - bool ExpectParameterPack); - bool SubstParmTypes(SourceLocation Loc, - ParmVarDecl **Params, unsigned NumParams, - const MultiLevelTemplateArgumentList &TemplateArgs, - SmallVectorImpl<QualType> &ParamTypes, - SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr); - ExprResult SubstExpr(Expr *E, - const MultiLevelTemplateArgumentList &TemplateArgs); - - /// \brief Substitute the given template arguments into a list of - /// expressions, expanding pack expansions if required. - /// - /// \param Exprs The list of expressions to substitute into. - /// - /// \param IsCall Whether this is some form of call, in which case - /// default arguments will be dropped. - /// - /// \param TemplateArgs The set of template arguments to substitute. - /// - /// \param Outputs Will receive all of the substituted arguments. - /// - /// \returns true if an error occurred, false otherwise. - bool SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall, - const MultiLevelTemplateArgumentList &TemplateArgs, - SmallVectorImpl<Expr *> &Outputs); - - StmtResult SubstStmt(Stmt *S, - const MultiLevelTemplateArgumentList &TemplateArgs); - - Decl *SubstDecl(Decl *D, DeclContext *Owner, - const MultiLevelTemplateArgumentList &TemplateArgs); - - ExprResult SubstInitializer(Expr *E, - const MultiLevelTemplateArgumentList &TemplateArgs, - bool CXXDirectInit); - - bool - SubstBaseSpecifiers(CXXRecordDecl *Instantiation, - CXXRecordDecl *Pattern, - const MultiLevelTemplateArgumentList &TemplateArgs); - - bool - InstantiateClass(SourceLocation PointOfInstantiation, - CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, - const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateSpecializationKind TSK, - bool Complain = true); - - bool InstantiateEnum(SourceLocation PointOfInstantiation, - EnumDecl *Instantiation, EnumDecl *Pattern, - const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateSpecializationKind TSK); - - bool InstantiateInClassInitializer( - SourceLocation PointOfInstantiation, FieldDecl *Instantiation, - FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs); - - struct LateInstantiatedAttribute { - const Attr *TmplAttr; - LocalInstantiationScope *Scope; - Decl *NewDecl; - - LateInstantiatedAttribute(const Attr *A, LocalInstantiationScope *S, - Decl *D) - : TmplAttr(A), Scope(S), NewDecl(D) - { } - }; - typedef SmallVector<LateInstantiatedAttribute, 16> LateInstantiatedAttrVec; - - void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, - const Decl *Pattern, Decl *Inst, - LateInstantiatedAttrVec *LateAttrs = nullptr, - LocalInstantiationScope *OuterMostScope = nullptr); - - bool - InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation, - ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, - bool Complain = true); - - void InstantiateClassMembers(SourceLocation PointOfInstantiation, - CXXRecordDecl *Instantiation, - const MultiLevelTemplateArgumentList &TemplateArgs, - TemplateSpecializationKind TSK); - - void InstantiateClassTemplateSpecializationMembers( - SourceLocation PointOfInstantiation, - ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK); - - NestedNameSpecifierLoc - SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, - const MultiLevelTemplateArgumentList &TemplateArgs); - - DeclarationNameInfo - SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, - const MultiLevelTemplateArgumentList &TemplateArgs); - TemplateName - SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name, - SourceLocation Loc, - const MultiLevelTemplateArgumentList &TemplateArgs); - bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs, - TemplateArgumentListInfo &Result, - const MultiLevelTemplateArgumentList &TemplateArgs); - - void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, - FunctionDecl *Function); - void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, - FunctionDecl *Function, - bool Recursive = false, - bool DefinitionRequired = false); - VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( - VarTemplateDecl *VarTemplate, VarDecl *FromVar, - const TemplateArgumentList &TemplateArgList, - const TemplateArgumentListInfo &TemplateArgsInfo, - SmallVectorImpl<TemplateArgument> &Converted, - SourceLocation PointOfInstantiation, void *InsertPos, - LateInstantiatedAttrVec *LateAttrs = nullptr, - LocalInstantiationScope *StartingScope = nullptr); - VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl( - VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, - const MultiLevelTemplateArgumentList &TemplateArgs); - void - BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar, - const MultiLevelTemplateArgumentList &TemplateArgs, - LateInstantiatedAttrVec *LateAttrs, - DeclContext *Owner, - LocalInstantiationScope *StartingScope, - bool InstantiatingVarTemplate = false); - void InstantiateVariableInitializer( - VarDecl *Var, VarDecl *OldVar, - const MultiLevelTemplateArgumentList &TemplateArgs); - void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, - VarDecl *Var, bool Recursive = false, - bool DefinitionRequired = false); - void InstantiateStaticDataMemberDefinition( - SourceLocation PointOfInstantiation, - VarDecl *Var, - bool Recursive = false, - bool DefinitionRequired = false); - - void InstantiateMemInitializers(CXXConstructorDecl *New, - const CXXConstructorDecl *Tmpl, - const MultiLevelTemplateArgumentList &TemplateArgs); - - NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, - const MultiLevelTemplateArgumentList &TemplateArgs); - DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC, - const MultiLevelTemplateArgumentList &TemplateArgs); - - // Objective-C declarations. - enum ObjCContainerKind { - OCK_None = -1, - OCK_Interface = 0, - OCK_Protocol, - OCK_Category, - OCK_ClassExtension, - OCK_Implementation, - OCK_CategoryImplementation - }; - ObjCContainerKind getObjCContainerKind() const; - - DeclResult actOnObjCTypeParam(Scope *S, - ObjCTypeParamVariance variance, - SourceLocation varianceLoc, - unsigned index, - IdentifierInfo *paramName, - SourceLocation paramLoc, - SourceLocation colonLoc, - ParsedType typeBound); - - ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, - ArrayRef<Decl *> typeParams, - SourceLocation rAngleLoc); - void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList); - - Decl *ActOnStartClassInterface(Scope *S, - SourceLocation AtInterfaceLoc, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - ObjCTypeParamList *typeParamList, - IdentifierInfo *SuperName, - SourceLocation SuperLoc, - ArrayRef<ParsedType> SuperTypeArgs, - SourceRange SuperTypeArgsRange, - Decl * const *ProtoRefs, - unsigned NumProtoRefs, - const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc, - AttributeList *AttrList); - - void ActOnSuperClassOfClassInterface(Scope *S, - SourceLocation AtInterfaceLoc, - ObjCInterfaceDecl *IDecl, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - IdentifierInfo *SuperName, - SourceLocation SuperLoc, - ArrayRef<ParsedType> SuperTypeArgs, - SourceRange SuperTypeArgsRange); - - void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, - IdentifierInfo *SuperName, - SourceLocation SuperLoc); - - Decl *ActOnCompatibilityAlias( - SourceLocation AtCompatibilityAliasLoc, - IdentifierInfo *AliasName, SourceLocation AliasLocation, - IdentifierInfo *ClassName, SourceLocation ClassLocation); - - bool CheckForwardProtocolDeclarationForCircularDependency( - IdentifierInfo *PName, - SourceLocation &PLoc, SourceLocation PrevLoc, - const ObjCList<ObjCProtocolDecl> &PList); - - Decl *ActOnStartProtocolInterface( - SourceLocation AtProtoInterfaceLoc, - IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, - Decl * const *ProtoRefNames, unsigned NumProtoRefs, - const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc, - AttributeList *AttrList); - - Decl *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - ObjCTypeParamList *typeParamList, - IdentifierInfo *CategoryName, - SourceLocation CategoryLoc, - Decl * const *ProtoRefs, - unsigned NumProtoRefs, - const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc); - - Decl *ActOnStartClassImplementation( - SourceLocation AtClassImplLoc, - IdentifierInfo *ClassName, SourceLocation ClassLoc, - IdentifierInfo *SuperClassname, - SourceLocation SuperClassLoc); - - Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - IdentifierInfo *CatName, - SourceLocation CatLoc); - - DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl, - ArrayRef<Decl *> Decls); - - DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, - IdentifierInfo **IdentList, - SourceLocation *IdentLocs, - ArrayRef<ObjCTypeParamList *> TypeParamLists, - unsigned NumElts); - - DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, - ArrayRef<IdentifierLocPair> IdentList, - AttributeList *attrList); - - void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, - ArrayRef<IdentifierLocPair> ProtocolId, - SmallVectorImpl<Decl *> &Protocols); - - /// Given a list of identifiers (and their locations), resolve the - /// names to either Objective-C protocol qualifiers or type - /// arguments, as appropriate. - void actOnObjCTypeArgsOrProtocolQualifiers( - Scope *S, - ParsedType baseType, - SourceLocation lAngleLoc, - ArrayRef<IdentifierInfo *> identifiers, - ArrayRef<SourceLocation> identifierLocs, - SourceLocation rAngleLoc, - SourceLocation &typeArgsLAngleLoc, - SmallVectorImpl<ParsedType> &typeArgs, - SourceLocation &typeArgsRAngleLoc, - SourceLocation &protocolLAngleLoc, - SmallVectorImpl<Decl *> &protocols, - SourceLocation &protocolRAngleLoc, - bool warnOnIncompleteProtocols); - - /// Build a an Objective-C protocol-qualified 'id' type where no - /// base type was specified. - TypeResult actOnObjCProtocolQualifierType( - SourceLocation lAngleLoc, - ArrayRef<Decl *> protocols, - ArrayRef<SourceLocation> protocolLocs, - SourceLocation rAngleLoc); - - /// Build a specialized and/or protocol-qualified Objective-C type. - TypeResult actOnObjCTypeArgsAndProtocolQualifiers( - Scope *S, - SourceLocation Loc, - ParsedType BaseType, - SourceLocation TypeArgsLAngleLoc, - ArrayRef<ParsedType> TypeArgs, - SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, - ArrayRef<Decl *> Protocols, - ArrayRef<SourceLocation> ProtocolLocs, - SourceLocation ProtocolRAngleLoc); - - /// Build an Objective-C object pointer type. - QualType BuildObjCObjectType(QualType BaseType, - SourceLocation Loc, - SourceLocation TypeArgsLAngleLoc, - ArrayRef<TypeSourceInfo *> TypeArgs, - SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, - ArrayRef<ObjCProtocolDecl *> Protocols, - ArrayRef<SourceLocation> ProtocolLocs, - SourceLocation ProtocolRAngleLoc, - bool FailOnError = false); - - /// Check the application of the Objective-C '__kindof' qualifier to - /// the given type. - bool checkObjCKindOfType(QualType &type, SourceLocation loc); - - /// Ensure attributes are consistent with type. - /// \param [in, out] Attributes The attributes to check; they will - /// be modified to be consistent with \p PropertyTy. - void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, - SourceLocation Loc, - unsigned &Attributes, - bool propertyInPrimaryClass); - - /// Process the specified property declaration and create decls for the - /// setters and getters as needed. - /// \param property The property declaration being processed - void ProcessPropertyDecl(ObjCPropertyDecl *property); - - - void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, - ObjCPropertyDecl *SuperProperty, - const IdentifierInfo *Name, - bool OverridingProtocolProperty); - - void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, - ObjCInterfaceDecl *ID); - - Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, - ArrayRef<Decl *> allMethods = None, - ArrayRef<DeclGroupPtrTy> allTUVars = None); - - Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, - SourceLocation LParenLoc, - FieldDeclarator &FD, ObjCDeclSpec &ODS, - Selector GetterSel, Selector SetterSel, - tok::ObjCKeywordKind MethodImplKind, - DeclContext *lexicalDC = nullptr); - - Decl *ActOnPropertyImplDecl(Scope *S, - SourceLocation AtLoc, - SourceLocation PropertyLoc, - bool ImplKind, - IdentifierInfo *PropertyId, - IdentifierInfo *PropertyIvar, - SourceLocation PropertyIvarLoc); - - enum ObjCSpecialMethodKind { - OSMK_None, - OSMK_Alloc, - OSMK_New, - OSMK_Copy, - OSMK_RetainingInit, - OSMK_NonRetainingInit - }; - - struct ObjCArgInfo { - IdentifierInfo *Name; - SourceLocation NameLoc; - // The Type is null if no type was specified, and the DeclSpec is invalid - // in this case. - ParsedType Type; - ObjCDeclSpec DeclSpec; - - /// ArgAttrs - Attribute list for this argument. - AttributeList *ArgAttrs; - }; - - Decl *ActOnMethodDeclaration( - Scope *S, - SourceLocation BeginLoc, // location of the + or -. - SourceLocation EndLoc, // location of the ; or {. - tok::TokenKind MethodType, - ObjCDeclSpec &ReturnQT, ParsedType ReturnType, - ArrayRef<SourceLocation> SelectorLocs, Selector Sel, - // optional arguments. The number of types/arguments is obtained - // from the Sel.getNumArgs(). - ObjCArgInfo *ArgInfo, - DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args - AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind, - bool isVariadic, bool MethodDefinition); - - ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, - const ObjCObjectPointerType *OPT, - bool IsInstance); - ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty, - bool IsInstance); - - bool CheckARCMethodDecl(ObjCMethodDecl *method); - bool inferObjCARCLifetime(ValueDecl *decl); - - ExprResult - HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, - Expr *BaseExpr, - SourceLocation OpLoc, - DeclarationName MemberName, - SourceLocation MemberLoc, - SourceLocation SuperLoc, QualType SuperType, - bool Super); - - ExprResult - ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, - IdentifierInfo &propertyName, - SourceLocation receiverNameLoc, - SourceLocation propertyNameLoc); - - ObjCMethodDecl *tryCaptureObjCSelf(SourceLocation Loc); - - /// \brief Describes the kind of message expression indicated by a message - /// send that starts with an identifier. - enum ObjCMessageKind { - /// \brief The message is sent to 'super'. - ObjCSuperMessage, - /// \brief The message is an instance message. - ObjCInstanceMessage, - /// \brief The message is a class message, and the identifier is a type - /// name. - ObjCClassMessage - }; - - ObjCMessageKind getObjCMessageKind(Scope *S, - IdentifierInfo *Name, - SourceLocation NameLoc, - bool IsSuper, - bool HasTrailingDot, - ParsedType &ReceiverType); - - ExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args); - - ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args, - bool isImplicit = false); - - ExprResult BuildClassMessageImplicit(QualType ReceiverType, - bool isSuperReceiver, - SourceLocation Loc, - Selector Sel, - ObjCMethodDecl *Method, - MultiExprArg Args); - - ExprResult ActOnClassMessage(Scope *S, - ParsedType Receiver, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args); - - ExprResult BuildInstanceMessage(Expr *Receiver, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args, - bool isImplicit = false); - - ExprResult BuildInstanceMessageImplicit(Expr *Receiver, - QualType ReceiverType, - SourceLocation Loc, - Selector Sel, - ObjCMethodDecl *Method, - MultiExprArg Args); - - ExprResult ActOnInstanceMessage(Scope *S, - Expr *Receiver, - Selector Sel, - SourceLocation LBracLoc, - ArrayRef<SourceLocation> SelectorLocs, - SourceLocation RBracLoc, - MultiExprArg Args); - - ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - TypeSourceInfo *TSInfo, - Expr *SubExpr); - - ExprResult ActOnObjCBridgedCast(Scope *S, - SourceLocation LParenLoc, - ObjCBridgeCastKind Kind, - SourceLocation BridgeKeywordLoc, - ParsedType Type, - SourceLocation RParenLoc, - Expr *SubExpr); - - void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr); - - void CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr); - - bool CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, - CastKind &Kind); - - bool checkObjCBridgeRelatedComponents(SourceLocation Loc, - QualType DestType, QualType SrcType, - ObjCInterfaceDecl *&RelatedClass, - ObjCMethodDecl *&ClassMethod, - ObjCMethodDecl *&InstanceMethod, - TypedefNameDecl *&TDNDecl, - bool CfToNs); - - bool CheckObjCBridgeRelatedConversions(SourceLocation Loc, - QualType DestType, QualType SrcType, - Expr *&SrcExpr); - - bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr); - - bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); - - /// \brief Check whether the given new method is a valid override of the - /// given overridden method, and set any properties that should be inherited. - void CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, - const ObjCMethodDecl *Overridden); - - /// \brief Describes the compatibility of a result type with its method. - enum ResultTypeCompatibilityKind { - RTC_Compatible, - RTC_Incompatible, - RTC_Unknown - }; - - void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, - ObjCInterfaceDecl *CurrentClass, - ResultTypeCompatibilityKind RTC); - - enum PragmaOptionsAlignKind { - POAK_Native, // #pragma options align=native - POAK_Natural, // #pragma options align=natural - POAK_Packed, // #pragma options align=packed - POAK_Power, // #pragma options align=power - POAK_Mac68k, // #pragma options align=mac68k - POAK_Reset // #pragma options align=reset - }; - - /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align. - void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, - SourceLocation PragmaLoc); - - enum PragmaPackKind { - PPK_Default, // #pragma pack([n]) - PPK_Show, // #pragma pack(show), only supported by MSVC. - PPK_Push, // #pragma pack(push, [identifier], [n]) - PPK_Pop // #pragma pack(pop, [identifier], [n]) - }; - - enum PragmaMSStructKind { - PMSST_OFF, // #pragms ms_struct off - PMSST_ON // #pragms ms_struct on - }; - - enum PragmaMSCommentKind { - PCK_Unknown, - PCK_Linker, // #pragma comment(linker, ...) - PCK_Lib, // #pragma comment(lib, ...) - PCK_Compiler, // #pragma comment(compiler, ...) - PCK_ExeStr, // #pragma comment(exestr, ...) - PCK_User // #pragma comment(user, ...) - }; - - /// ActOnPragmaPack - Called on well formed \#pragma pack(...). - void ActOnPragmaPack(PragmaPackKind Kind, - IdentifierInfo *Name, - Expr *Alignment, - SourceLocation PragmaLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc); - - /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. - void ActOnPragmaMSStruct(PragmaMSStructKind Kind); - - /// ActOnPragmaMSComment - Called on well formed - /// \#pragma comment(kind, "arg"). - void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg); - - /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma - /// pointers_to_members(representation method[, general purpose - /// representation]). - void ActOnPragmaMSPointersToMembers( - LangOptions::PragmaMSPointersToMembersKind Kind, - SourceLocation PragmaLoc); - - /// \brief Called on well formed \#pragma vtordisp(). - void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc, - MSVtorDispAttr::Mode Value); - - enum PragmaSectionKind { - PSK_DataSeg, - PSK_BSSSeg, - PSK_ConstSeg, - PSK_CodeSeg, - }; - - bool UnifySection(StringRef SectionName, - int SectionFlags, - DeclaratorDecl *TheDecl); - bool UnifySection(StringRef SectionName, - int SectionFlags, - SourceLocation PragmaSectionLocation); - - /// \brief Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg. - void ActOnPragmaMSSeg(SourceLocation PragmaLocation, - PragmaMsStackAction Action, - llvm::StringRef StackSlotLabel, - StringLiteral *SegmentName, - llvm::StringRef PragmaName); - - /// \brief Called on well formed \#pragma section(). - void ActOnPragmaMSSection(SourceLocation PragmaLocation, - int SectionFlags, StringLiteral *SegmentName); - - /// \brief Called on well-formed \#pragma init_seg(). - void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, - StringLiteral *SegmentName); - - /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch - void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value); - - /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. - void ActOnPragmaUnused(const Token &Identifier, - Scope *curScope, - SourceLocation PragmaLoc); - - /// ActOnPragmaVisibility - Called on well formed \#pragma GCC visibility... . - void ActOnPragmaVisibility(const IdentifierInfo* VisType, - SourceLocation PragmaLoc); - - NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, - SourceLocation Loc); - void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W); - - /// ActOnPragmaWeakID - Called on well formed \#pragma weak ident. - void ActOnPragmaWeakID(IdentifierInfo* WeakName, - SourceLocation PragmaLoc, - SourceLocation WeakNameLoc); - - /// ActOnPragmaRedefineExtname - Called on well formed - /// \#pragma redefine_extname oldname newname. - void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName, - IdentifierInfo* AliasName, - SourceLocation PragmaLoc, - SourceLocation WeakNameLoc, - SourceLocation AliasNameLoc); - - /// ActOnPragmaWeakAlias - Called on well formed \#pragma weak ident = ident. - void ActOnPragmaWeakAlias(IdentifierInfo* WeakName, - IdentifierInfo* AliasName, - SourceLocation PragmaLoc, - SourceLocation WeakNameLoc, - SourceLocation AliasNameLoc); - - /// ActOnPragmaFPContract - Called on well formed - /// \#pragma {STDC,OPENCL} FP_CONTRACT - void ActOnPragmaFPContract(tok::OnOffSwitch OOS); - - /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to - /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. - void AddAlignmentAttributesForRecord(RecordDecl *RD); - - /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record. - void AddMsStructLayoutForRecord(RecordDecl *RD); - - /// FreePackedContext - Deallocate and null out PackContext. - void FreePackedContext(); - - /// PushNamespaceVisibilityAttr - Note that we've entered a - /// namespace with a visibility attribute. - void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, - SourceLocation Loc); - - /// AddPushedVisibilityAttribute - If '\#pragma GCC visibility' was used, - /// add an appropriate visibility attribute. - void AddPushedVisibilityAttribute(Decl *RD); - - /// PopPragmaVisibility - Pop the top element of the visibility stack; used - /// for '\#pragma GCC visibility' and visibility attributes on namespaces. - void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc); - - /// FreeVisContext - Deallocate and null out VisContext. - void FreeVisContext(); - - /// AddCFAuditedAttribute - Check whether we're currently within - /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding - /// the appropriate attribute. - void AddCFAuditedAttribute(Decl *D); - - /// \brief Called on well formed \#pragma clang optimize. - void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc); - - /// \brief Get the location for the currently active "\#pragma clang optimize - /// off". If this location is invalid, then the state of the pragma is "on". - SourceLocation getOptimizeOffPragmaLocation() const { - return OptimizeOffPragmaLocation; - } - - /// \brief Only called on function definitions; if there is a pragma in scope - /// with the effect of a range-based optnone, consider marking the function - /// with attribute optnone. - void AddRangeBasedOptnone(FunctionDecl *FD); - - /// \brief Adds the 'optnone' attribute to the function declaration if there - /// are no conflicts; Loc represents the location causing the 'optnone' - /// attribute to be added (usually because of a pragma). - void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc); - - /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. - void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, - unsigned SpellingListIndex, bool IsPackExpansion); - void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T, - unsigned SpellingListIndex, bool IsPackExpansion); - - /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular - /// declaration. - void AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, Expr *OE, - unsigned SpellingListIndex); - - /// AddAlignValueAttr - Adds an align_value attribute to a particular - /// declaration. - void AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, - unsigned SpellingListIndex); - - /// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular - /// declaration. - void AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, - Expr *MinBlocks, unsigned SpellingListIndex); - - //===--------------------------------------------------------------------===// - // C++ Coroutines TS - // - ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E); - ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E); - StmtResult ActOnCoreturnStmt(SourceLocation KwLoc, Expr *E); - - ExprResult BuildCoawaitExpr(SourceLocation KwLoc, Expr *E); - ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E); - StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E); - - void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); - - //===--------------------------------------------------------------------===// - // OpenMP directives and clauses. - // -private: - void *VarDataSharingAttributesStack; - /// \brief Initialization of data-sharing attributes stack. - void InitDataSharingAttributesStack(); - void DestroyDataSharingAttributesStack(); - ExprResult - VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, - bool StrictlyPositive = true); - -public: - /// \brief Return true if the provided declaration \a VD should be captured by - /// reference in the provided scope \a RSI. This will take into account the - /// semantics of the directive and associated clauses. - bool IsOpenMPCapturedByRef(VarDecl *VD, - const sema::CapturedRegionScopeInfo *RSI); - - /// \brief Check if the specified variable is used in one of the private - /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP - /// constructs. - bool IsOpenMPCapturedVar(VarDecl *VD); - - /// \brief Check if the specified variable is used in 'private' clause. - /// \param Level Relative level of nested OpenMP construct for that the check - /// is performed. - bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level); - - /// \brief Check if the specified variable is captured by 'target' directive. - /// \param Level Relative level of nested OpenMP construct for that the check - /// is performed. - bool isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level); - - ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, - Expr *Op); - /// \brief Called on start of new data sharing attribute block. - void StartOpenMPDSABlock(OpenMPDirectiveKind K, - const DeclarationNameInfo &DirName, Scope *CurScope, - SourceLocation Loc); - /// \brief Start analysis of clauses. - void StartOpenMPClause(OpenMPClauseKind K); - /// \brief End analysis of clauses. - void EndOpenMPClause(); - /// \brief Called on end of data sharing attribute block. - void EndOpenMPDSABlock(Stmt *CurDirective); - - /// \brief Check if the current region is an OpenMP loop region and if it is, - /// mark loop control variable, used in \p Init for loop initialization, as - /// private by default. - /// \param Init First part of the for loop. - void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init); - - // OpenMP directives and clauses. - /// \brief Called on correct id-expression from the '#pragma omp - /// threadprivate'. - ExprResult ActOnOpenMPIdExpression(Scope *CurScope, - CXXScopeSpec &ScopeSpec, - const DeclarationNameInfo &Id); - /// \brief Called on well-formed '#pragma omp threadprivate'. - DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( - SourceLocation Loc, - ArrayRef<Expr *> VarList); - /// \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness. - OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl( - SourceLocation Loc, - ArrayRef<Expr *> VarList); - - /// \brief Initialization of captured region for OpenMP region. - void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); - /// \brief End of OpenMP region. - /// - /// \param S Statement associated with the current OpenMP region. - /// \param Clauses List of clauses for the current OpenMP region. - /// - /// \returns Statement for finished OpenMP region. - StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses); - StmtResult ActOnOpenMPExecutableDirective( - OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, - OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp parallel' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, - SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp simd' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPSimdDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp for' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPForDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp for simd' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPForSimdDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp sections' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp section' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp single' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp master' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp critical' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, - ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp parallel for' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPParallelForDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp parallel for simd' after - /// parsing of the associated statement. - StmtResult ActOnOpenMPParallelForSimdDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp parallel sections' after - /// parsing of the associated statement. - StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, - SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp task' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp taskyield'. - StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp barrier'. - StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp taskwait'. - StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp taskgroup'. - StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp flush'. - StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, - SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp ordered' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp atomic' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp target' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp target data' after parsing of - /// the associated statement. - StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp teams' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed '\#pragma omp cancellation point'. - StmtResult - ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, - SourceLocation EndLoc, - OpenMPDirectiveKind CancelRegion); - /// \brief Called on well-formed '\#pragma omp cancel'. - StmtResult ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, - SourceLocation StartLoc, - SourceLocation EndLoc, - OpenMPDirectiveKind CancelRegion); - /// \brief Called on well-formed '\#pragma omp taskloop' after parsing of the - /// associated statement. - StmtResult ActOnOpenMPTaskLoopDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp taskloop simd' after parsing of - /// the associated statement. - StmtResult ActOnOpenMPTaskLoopSimdDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - /// \brief Called on well-formed '\#pragma omp distribute' after parsing - /// of the associated statement. - StmtResult ActOnOpenMPDistributeDirective( - ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); - - OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, - Expr *Expr, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'if' clause. - OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, - Expr *Condition, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation NameModifierLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'final' clause. - OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'num_threads' clause. - OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'safelen' clause. - OMPClause *ActOnOpenMPSafelenClause(Expr *Length, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'simdlen' clause. - OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'collapse' clause. - OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'ordered' clause. - OMPClause * - ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, - SourceLocation LParenLoc = SourceLocation(), - Expr *NumForLoops = nullptr); - /// \brief Called on well-formed 'grainsize' clause. - OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'num_tasks' clause. - OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'hint' clause. - OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - - OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, - unsigned Argument, - SourceLocation ArgumentLoc, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'default' clause. - OMPClause *ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, - SourceLocation KindLoc, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'proc_bind' clause. - OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, - SourceLocation KindLoc, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - - OMPClause *ActOnOpenMPSingleExprWithArgClause( - OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, - SourceLocation StartLoc, SourceLocation LParenLoc, - ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'schedule' clause. - OMPClause *ActOnOpenMPScheduleClause( - OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, - OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, - SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc); - - OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'nowait' clause. - OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'untied' clause. - OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'mergeable' clause. - OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'read' clause. - OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'write' clause. - OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'update' clause. - OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'capture' clause. - OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'seq_cst' clause. - OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'threads' clause. - OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'simd' clause. - OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'nogroup' clause. - OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc, - SourceLocation EndLoc); - - OMPClause *ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, - OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc); - /// \brief Called on well-formed 'private' clause. - OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'firstprivate' clause. - OMPClause *ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'lastprivate' clause. - OMPClause *ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'shared' clause. - OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'reduction' clause. - OMPClause * - ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation ColonLoc, - SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId); - /// \brief Called on well-formed 'linear' clause. - OMPClause * - ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, - SourceLocation StartLoc, SourceLocation LParenLoc, - OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, - SourceLocation ColonLoc, SourceLocation EndLoc); - /// \brief Called on well-formed 'aligned' clause. - OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList, - Expr *Alignment, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'copyin' clause. - OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'copyprivate' clause. - OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'flush' pseudo clause. - OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'depend' clause. - OMPClause * - ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'device' clause. - OMPClause *ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'map' clause. - OMPClause *ActOnOpenMPMapClause( - OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, - SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); - /// \brief Called on well-formed 'num_teams' clause. - OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'thread_limit' clause. - OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - /// \brief Called on well-formed 'priority' clause. - OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc); - - /// \brief The kind of conversion being performed. - enum CheckedConversionKind { - /// \brief An implicit conversion. - CCK_ImplicitConversion, - /// \brief A C-style cast. - CCK_CStyleCast, - /// \brief A functional-style cast. - CCK_FunctionalCast, - /// \brief A cast other than a C-style cast. - CCK_OtherCast - }; - - /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit - /// cast. If there is already an implicit cast, merge into the existing one. - /// If isLvalue, the result of the cast is an lvalue. - ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, - ExprValueKind VK = VK_RValue, - const CXXCastPath *BasePath = nullptr, - CheckedConversionKind CCK - = CCK_ImplicitConversion); - - /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding - /// to the conversion from scalar type ScalarTy to the Boolean type. - static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy); - - /// IgnoredValueConversions - Given that an expression's result is - /// syntactically ignored, perform any conversions that are - /// required. - ExprResult IgnoredValueConversions(Expr *E); - - // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts - // functions and arrays to their respective pointers (C99 6.3.2.1). - ExprResult UsualUnaryConversions(Expr *E); - - /// CallExprUnaryConversions - a special case of an unary conversion - /// performed on a function designator of a call expression. - ExprResult CallExprUnaryConversions(Expr *E); - - // DefaultFunctionArrayConversion - converts functions and arrays - // to their respective pointers (C99 6.3.2.1). - ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose = true); - - // DefaultFunctionArrayLvalueConversion - converts functions and - // arrays to their respective pointers and performs the - // lvalue-to-rvalue conversion. - ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, - bool Diagnose = true); - - // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on - // the operand. This is DefaultFunctionArrayLvalueConversion, - // except that it assumes the operand isn't of function or array - // type. - ExprResult DefaultLvalueConversion(Expr *E); - - // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that - // do not have a prototype. Integer promotions are performed on each - // argument, and arguments that have type float are promoted to double. - ExprResult DefaultArgumentPromotion(Expr *E); - - // Used for emitting the right warning by DefaultVariadicArgumentPromotion - enum VariadicCallType { - VariadicFunction, - VariadicBlock, - VariadicMethod, - VariadicConstructor, - VariadicDoesNotApply - }; - - VariadicCallType getVariadicCallType(FunctionDecl *FDecl, - const FunctionProtoType *Proto, - Expr *Fn); - - // Used for determining in which context a type is allowed to be passed to a - // vararg function. - enum VarArgKind { - VAK_Valid, - VAK_ValidInCXX11, - VAK_Undefined, - VAK_MSVCUndefined, - VAK_Invalid - }; - - // Determines which VarArgKind fits an expression. - VarArgKind isValidVarArgType(const QualType &Ty); - - /// Check to see if the given expression is a valid argument to a variadic - /// function, issuing a diagnostic if not. - void checkVariadicArgument(const Expr *E, VariadicCallType CT); - - /// Check to see if a given expression could have '.c_str()' called on it. - bool hasCStrMethod(const Expr *E); - - /// GatherArgumentsForCall - Collector argument expressions for various - /// form of call prototypes. - bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, - const FunctionProtoType *Proto, - unsigned FirstParam, ArrayRef<Expr *> Args, - SmallVectorImpl<Expr *> &AllArgs, - VariadicCallType CallType = VariadicDoesNotApply, - bool AllowExplicit = false, - bool IsListInitialization = false); - - // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but - // will create a runtime trap if the resulting type is not a POD type. - ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, - FunctionDecl *FDecl); - - // UsualArithmeticConversions - performs the UsualUnaryConversions on it's - // operands and then handles various conversions that are common to binary - // operators (C99 6.3.1.8). If both operands aren't arithmetic, this - // routine returns the first non-arithmetic type found. The client is - // responsible for emitting appropriate error diagnostics. - QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, - bool IsCompAssign = false); - - /// AssignConvertType - All of the 'assignment' semantic checks return this - /// enum to indicate whether the assignment was allowed. These checks are - /// done for simple assignments, as well as initialization, return from - /// function, argument passing, etc. The query is phrased in terms of a - /// source and destination type. - enum AssignConvertType { - /// Compatible - the types are compatible according to the standard. - Compatible, - - /// PointerToInt - The assignment converts a pointer to an int, which we - /// accept as an extension. - PointerToInt, - - /// IntToPointer - The assignment converts an int to a pointer, which we - /// accept as an extension. - IntToPointer, - - /// FunctionVoidPointer - The assignment is between a function pointer and - /// void*, which the standard doesn't allow, but we accept as an extension. - FunctionVoidPointer, - - /// IncompatiblePointer - The assignment is between two pointers types that - /// are not compatible, but we accept them as an extension. - IncompatiblePointer, - - /// IncompatiblePointer - The assignment is between two pointers types which - /// point to integers which have a different sign, but are otherwise - /// identical. This is a subset of the above, but broken out because it's by - /// far the most common case of incompatible pointers. - IncompatiblePointerSign, - - /// CompatiblePointerDiscardsQualifiers - The assignment discards - /// c/v/r qualifiers, which we accept as an extension. - CompatiblePointerDiscardsQualifiers, - - /// IncompatiblePointerDiscardsQualifiers - The assignment - /// discards qualifiers that we don't permit to be discarded, - /// like address spaces. - IncompatiblePointerDiscardsQualifiers, - - /// IncompatibleNestedPointerQualifiers - The assignment is between two - /// nested pointer types, and the qualifiers other than the first two - /// levels differ e.g. char ** -> const char **, but we accept them as an - /// extension. - IncompatibleNestedPointerQualifiers, - - /// IncompatibleVectors - The assignment is between two vector types that - /// have the same size, which we accept as an extension. - IncompatibleVectors, - - /// IntToBlockPointer - The assignment converts an int to a block - /// pointer. We disallow this. - IntToBlockPointer, - - /// IncompatibleBlockPointer - The assignment is between two block - /// pointers types that are not compatible. - IncompatibleBlockPointer, - - /// IncompatibleObjCQualifiedId - The assignment is between a qualified - /// id type and something else (that is incompatible with it). For example, - /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol. - IncompatibleObjCQualifiedId, - - /// IncompatibleObjCWeakRef - Assigning a weak-unavailable object to an - /// object with __weak qualifier. - IncompatibleObjCWeakRef, - - /// Incompatible - We reject this conversion outright, it is invalid to - /// represent it in the AST. - Incompatible - }; - - /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the - /// assignment conversion type specified by ConvTy. This returns true if the - /// conversion was invalid or false if the conversion was accepted. - bool DiagnoseAssignmentResult(AssignConvertType ConvTy, - SourceLocation Loc, - QualType DstType, QualType SrcType, - Expr *SrcExpr, AssignmentAction Action, - bool *Complained = nullptr); - - /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag - /// enum. If AllowMask is true, then we also allow the complement of a valid - /// value, to be used as a mask. - bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, - bool AllowMask) const; - - /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant - /// integer not in the range of enum values. - void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, - Expr *SrcExpr); - - /// CheckAssignmentConstraints - Perform type checking for assignment, - /// argument passing, variable initialization, and function return values. - /// C99 6.5.16. - AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, - QualType LHSType, - QualType RHSType); - - /// Check assignment constraints and optionally prepare for a conversion of - /// the RHS to the LHS type. The conversion is prepared for if ConvertRHS - /// is true. - AssignConvertType CheckAssignmentConstraints(QualType LHSType, - ExprResult &RHS, - CastKind &Kind, - bool ConvertRHS = true); - - // CheckSingleAssignmentConstraints - Currently used by - // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, - // this routine performs the default function/array converions, if ConvertRHS - // is true. - AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, - ExprResult &RHS, - bool Diagnose = true, - bool DiagnoseCFAudited = false, - bool ConvertRHS = true); - - // \brief If the lhs type is a transparent union, check whether we - // can initialize the transparent union with the given expression. - AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType, - ExprResult &RHS); - - bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType); - - bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType); - - ExprResult PerformImplicitConversion(Expr *From, QualType ToType, - AssignmentAction Action, - bool AllowExplicit = false); - ExprResult PerformImplicitConversion(Expr *From, QualType ToType, - AssignmentAction Action, - bool AllowExplicit, - ImplicitConversionSequence& ICS); - ExprResult PerformImplicitConversion(Expr *From, QualType ToType, - const ImplicitConversionSequence& ICS, - AssignmentAction Action, - CheckedConversionKind CCK - = CCK_ImplicitConversion); - ExprResult PerformImplicitConversion(Expr *From, QualType ToType, - const StandardConversionSequence& SCS, - AssignmentAction Action, - CheckedConversionKind CCK); - - /// the following "Check" methods will return a valid/converted QualType - /// or a null QualType (indicating an error diagnostic was issued). - - /// type checking binary operators (subroutines of CreateBuiltinBinOp). - QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS, - ExprResult &RHS); - QualType CheckPointerToMemberOperands( // C++ 5.5 - ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, - SourceLocation OpLoc, bool isIndirect); - QualType CheckMultiplyDivideOperands( // C99 6.5.5 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, - bool IsDivide); - QualType CheckRemainderOperands( // C99 6.5.5 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - bool IsCompAssign = false); - QualType CheckAdditionOperands( // C99 6.5.6 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - BinaryOperatorKind Opc, QualType* CompLHSTy = nullptr); - QualType CheckSubtractionOperands( // C99 6.5.6 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - QualType* CompLHSTy = nullptr); - QualType CheckShiftOperands( // C99 6.5.7 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - BinaryOperatorKind Opc, bool IsCompAssign = false); - QualType CheckCompareOperands( // C99 6.5.8/9 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - BinaryOperatorKind Opc, bool isRelational); - QualType CheckBitwiseOperands( // C99 6.5.[10...12] - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - bool IsCompAssign = false); - QualType CheckLogicalOperands( // C99 6.5.[13,14] - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, - BinaryOperatorKind Opc); - // CheckAssignmentOperands is used for both simple and compound assignment. - // For simple assignment, pass both expressions and a null converted type. - // For compound assignment, pass both expressions and the converted type. - QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] - Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType); - - ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc, - UnaryOperatorKind Opcode, Expr *Op); - ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, - BinaryOperatorKind Opcode, - Expr *LHS, Expr *RHS); - ExprResult checkPseudoObjectRValue(Expr *E); - Expr *recreateSyntacticForm(PseudoObjectExpr *E); - - QualType CheckConditionalOperands( // C99 6.5.15 - ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, - ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc); - QualType CXXCheckConditionalOperands( // C++ 5.16 - ExprResult &cond, ExprResult &lhs, ExprResult &rhs, - ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); - QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, - bool *NonStandardCompositeType = nullptr); - QualType FindCompositePointerType(SourceLocation Loc, - ExprResult &E1, ExprResult &E2, - bool *NonStandardCompositeType = nullptr) { - Expr *E1Tmp = E1.get(), *E2Tmp = E2.get(); - QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp, - NonStandardCompositeType); - E1 = E1Tmp; - E2 = E2Tmp; - return Composite; - } - - QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, - SourceLocation QuestionLoc); - - bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr, - SourceLocation QuestionLoc); - - void DiagnoseAlwaysNonNullPointer(Expr *E, - Expr::NullPointerConstantKind NullType, - bool IsEqual, SourceRange Range); - - /// type checking for vector binary operators. - QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc, bool IsCompAssign, - bool AllowBothBool, bool AllowBoolConversion); - QualType GetSignedVectorType(QualType V); - QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc, bool isRelational); - QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc); - - bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); - bool isLaxVectorConversion(QualType srcType, QualType destType); - - /// type checking declaration initializers (C99 6.7.8) - bool CheckForConstantInitializer(Expr *e, QualType t); - - // type checking C++ declaration initializers (C++ [dcl.init]). - - /// ReferenceCompareResult - Expresses the result of comparing two - /// types (cv1 T1 and cv2 T2) to determine their compatibility for the - /// purposes of initialization by reference (C++ [dcl.init.ref]p4). - enum ReferenceCompareResult { - /// Ref_Incompatible - The two types are incompatible, so direct - /// reference binding is not possible. - Ref_Incompatible = 0, - /// Ref_Related - The two types are reference-related, which means - /// that their unqualified forms (T1 and T2) are either the same - /// or T1 is a base class of T2. - Ref_Related, - /// Ref_Compatible_With_Added_Qualification - The two types are - /// reference-compatible with added qualification, meaning that - /// they are reference-compatible and the qualifiers on T1 (cv1) - /// are greater than the qualifiers on T2 (cv2). - Ref_Compatible_With_Added_Qualification, - /// Ref_Compatible - The two types are reference-compatible and - /// have equivalent qualifiers (cv1 == cv2). - Ref_Compatible - }; - - ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc, - QualType T1, QualType T2, - bool &DerivedToBase, - bool &ObjCConversion, - bool &ObjCLifetimeConversion); - - ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, - Expr *CastExpr, CastKind &CastKind, - ExprValueKind &VK, CXXCastPath &Path); - - /// \brief Force an expression with unknown-type to an expression of the - /// given type. - ExprResult forceUnknownAnyToType(Expr *E, QualType ToType); - - /// \brief Type-check an expression that's being passed to an - /// __unknown_anytype parameter. - ExprResult checkUnknownAnyArg(SourceLocation callLoc, - Expr *result, QualType ¶mType); - - // CheckVectorCast - check type constraints for vectors. - // Since vectors are an extension, there are no C standard reference for this. - // We allow casting between vectors and integer datatypes of the same size. - // returns true if the cast is invalid - bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty, - CastKind &Kind); - - // CheckExtVectorCast - check type constraints for extended vectors. - // Since vectors are an extension, there are no C standard reference for this. - // We allow casting between vectors and integer datatypes of the same size, - // or vectors and the element type of that vector. - // returns the cast expr - ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr, - CastKind &Kind); - - ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, - SourceLocation LParenLoc, - Expr *CastExpr, - SourceLocation RParenLoc); - - enum ARCConversionResult { ACR_okay, ACR_unbridged }; - - /// \brief Checks for invalid conversions and casts between - /// retainable pointers and other pointer kinds. - ARCConversionResult CheckObjCARCConversion(SourceRange castRange, - QualType castType, Expr *&op, - CheckedConversionKind CCK, - bool DiagnoseCFAudited = false, - BinaryOperatorKind Opc = BO_PtrMemD - ); - - Expr *stripARCUnbridgedCast(Expr *e); - void diagnoseARCUnbridgedCast(Expr *e); - - bool CheckObjCARCUnavailableWeakConversion(QualType castType, - QualType ExprType); - - /// checkRetainCycles - Check whether an Objective-C message send - /// might create an obvious retain cycle. - void checkRetainCycles(ObjCMessageExpr *msg); - void checkRetainCycles(Expr *receiver, Expr *argument); - void checkRetainCycles(VarDecl *Var, Expr *Init); - - /// checkUnsafeAssigns - Check whether +1 expr is being assigned - /// to weak/__unsafe_unretained type. - bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS); - - /// checkUnsafeExprAssigns - Check whether +1 expr is being assigned - /// to weak/__unsafe_unretained expression. - void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS); - - /// CheckMessageArgumentTypes - Check types in an Obj-C message send. - /// \param Method - May be null. - /// \param [out] ReturnType - The return type of the send. - /// \return true iff there were any incompatible types. - bool CheckMessageArgumentTypes(QualType ReceiverType, - MultiExprArg Args, Selector Sel, - ArrayRef<SourceLocation> SelectorLocs, - ObjCMethodDecl *Method, bool isClassMessage, - bool isSuperMessage, - SourceLocation lbrac, SourceLocation rbrac, - SourceRange RecRange, - QualType &ReturnType, ExprValueKind &VK); - - /// \brief Determine the result of a message send expression based on - /// the type of the receiver, the method expected to receive the message, - /// and the form of the message send. - QualType getMessageSendResultType(QualType ReceiverType, - ObjCMethodDecl *Method, - bool isClassMessage, bool isSuperMessage); - - /// \brief If the given expression involves a message send to a method - /// with a related result type, emit a note describing what happened. - void EmitRelatedResultTypeNote(const Expr *E); - - /// \brief Given that we had incompatible pointer types in a return - /// statement, check whether we're in a method with a related result - /// type, and if so, emit a note describing what happened. - void EmitRelatedResultTypeNoteForReturn(QualType destType); - - /// CheckBooleanCondition - Diagnose problems involving the use of - /// the given expression as a boolean condition (e.g. in an if - /// statement). Also performs the standard function and array - /// decays, possibly changing the input variable. - /// - /// \param Loc - A location associated with the condition, e.g. the - /// 'if' keyword. - /// \return true iff there were any errors - ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc); - - ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr); - - /// DiagnoseAssignmentAsCondition - Given that an expression is - /// being used as a boolean condition, warn if it's an assignment. - void DiagnoseAssignmentAsCondition(Expr *E); - - /// \brief Redundant parentheses over an equality comparison can indicate - /// that the user intended an assignment used as condition. - void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE); - - /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. - ExprResult CheckCXXBooleanCondition(Expr *CondExpr); - - /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have - /// the specified width and sign. If an overflow occurs, detect it and emit - /// the specified diagnostic. - void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal, - unsigned NewWidth, bool NewSign, - SourceLocation Loc, unsigned DiagID); - - /// Checks that the Objective-C declaration is declared in the global scope. - /// Emits an error and marks the declaration as invalid if it's not declared - /// in the global scope. - bool CheckObjCDeclScope(Decl *D); - - /// \brief Abstract base class used for diagnosing integer constant - /// expression violations. - class VerifyICEDiagnoser { - public: - bool Suppress; - - VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { } - - virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) =0; - virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR); - virtual ~VerifyICEDiagnoser() { } - }; - - /// VerifyIntegerConstantExpression - Verifies that an expression is an ICE, - /// and reports the appropriate diagnostics. Returns false on success. - /// Can optionally return the value of the expression. - ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - VerifyICEDiagnoser &Diagnoser, - bool AllowFold = true); - ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - unsigned DiagID, - bool AllowFold = true); - ExprResult VerifyIntegerConstantExpression(Expr *E, - llvm::APSInt *Result = nullptr); - - /// VerifyBitField - verifies that a bit field expression is an ICE and has - /// the correct width, and that the field type is valid. - /// Returns false on success. - /// Can optionally return whether the bit-field is of width 0 - ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, - QualType FieldTy, bool IsMsStruct, - Expr *BitWidth, bool *ZeroWidth = nullptr); - - enum CUDAFunctionTarget { - CFT_Device, - CFT_Global, - CFT_Host, - CFT_HostDevice, - CFT_InvalidTarget - }; - - CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); - - enum CUDAFunctionPreference { - CFP_Never, // Invalid caller/callee combination. - CFP_LastResort, // Lowest priority. Only in effect if - // LangOpts.CUDADisableTargetCallChecks is true. - CFP_Fallback, // Low priority caller/callee combination - CFP_Best, // Preferred caller/callee combination - }; - - /// Identifies relative preference of a given Caller/Callee - /// combination, based on their host/device attributes. - /// \param Caller function which needs address of \p Callee. - /// nullptr in case of global context. - /// \param Callee target function - /// - /// \returns preference value for particular Caller/Callee combination. - CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller, - const FunctionDecl *Callee); - - bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee); - - /// Finds a function in \p Matches with highest calling priority - /// from \p Caller context and erases all functions with lower - /// calling priority. - void EraseUnwantedCUDAMatches(const FunctionDecl *Caller, - SmallVectorImpl<FunctionDecl *> &Matches); - void EraseUnwantedCUDAMatches(const FunctionDecl *Caller, - SmallVectorImpl<DeclAccessPair> &Matches); - void EraseUnwantedCUDAMatches( - const FunctionDecl *Caller, - SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches); - - /// Given a implicit special member, infer its CUDA target from the - /// calls it needs to make to underlying base/field special members. - /// \param ClassDecl the class for which the member is being created. - /// \param CSM the kind of special member. - /// \param MemberDecl the special member itself. - /// \param ConstRHS true if this is a copy operation with a const object on - /// its RHS. - /// \param Diagnose true if this call should emit diagnostics. - /// \return true if there was an error inferring. - /// The result of this call is implicit CUDA target attribute(s) attached to - /// the member declaration. - bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, - CXXSpecialMember CSM, - CXXMethodDecl *MemberDecl, - bool ConstRHS, - bool Diagnose); - - /// \name Code completion - //@{ - /// \brief Describes the context in which code completion occurs. - enum ParserCompletionContext { - /// \brief Code completion occurs at top-level or namespace context. - PCC_Namespace, - /// \brief Code completion occurs within a class, struct, or union. - PCC_Class, - /// \brief Code completion occurs within an Objective-C interface, protocol, - /// or category. - PCC_ObjCInterface, - /// \brief Code completion occurs within an Objective-C implementation or - /// category implementation - PCC_ObjCImplementation, - /// \brief Code completion occurs within the list of instance variables - /// in an Objective-C interface, protocol, category, or implementation. - PCC_ObjCInstanceVariableList, - /// \brief Code completion occurs following one or more template - /// headers. - PCC_Template, - /// \brief Code completion occurs following one or more template - /// headers within a class. - PCC_MemberTemplate, - /// \brief Code completion occurs within an expression. - PCC_Expression, - /// \brief Code completion occurs within a statement, which may - /// also be an expression or a declaration. - PCC_Statement, - /// \brief Code completion occurs at the beginning of the - /// initialization statement (or expression) in a for loop. - PCC_ForInit, - /// \brief Code completion occurs within the condition of an if, - /// while, switch, or for statement. - PCC_Condition, - /// \brief Code completion occurs within the body of a function on a - /// recovery path, where we do not have a specific handle on our position - /// in the grammar. - PCC_RecoveryInFunction, - /// \brief Code completion occurs where only a type is permitted. - PCC_Type, - /// \brief Code completion occurs in a parenthesized expression, which - /// might also be a type cast. - PCC_ParenthesizedExpression, - /// \brief Code completion occurs within a sequence of declaration - /// specifiers within a function, method, or block. - PCC_LocalDeclarationSpecifiers - }; - - void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path); - void CodeCompleteOrdinaryName(Scope *S, - ParserCompletionContext CompletionContext); - void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, - bool AllowNonIdentifiers, - bool AllowNestedNameSpecifiers); - - struct CodeCompleteExpressionData; - void CodeCompleteExpression(Scope *S, - const CodeCompleteExpressionData &Data); - void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, - SourceLocation OpLoc, - bool IsArrow); - void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); - void CodeCompleteTag(Scope *S, unsigned TagSpec); - void CodeCompleteTypeQualifiers(DeclSpec &DS); - void CodeCompleteCase(Scope *S); - void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args); - void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, - ArrayRef<Expr *> Args); - void CodeCompleteInitializer(Scope *S, Decl *D); - void CodeCompleteReturn(Scope *S); - void CodeCompleteAfterIf(Scope *S); - void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS); - - void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, - bool EnteringContext); - void CodeCompleteUsing(Scope *S); - void CodeCompleteUsingDirective(Scope *S); - void CodeCompleteNamespaceDecl(Scope *S); - void CodeCompleteNamespaceAliasDecl(Scope *S); - void CodeCompleteOperatorName(Scope *S); - void CodeCompleteConstructorInitializer( - Decl *Constructor, - ArrayRef<CXXCtorInitializer *> Initializers); - - void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, - bool AfterAmpersand); - - void CodeCompleteObjCAtDirective(Scope *S); - void CodeCompleteObjCAtVisibility(Scope *S); - void CodeCompleteObjCAtStatement(Scope *S); - void CodeCompleteObjCAtExpression(Scope *S); - void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS); - void CodeCompleteObjCPropertyGetter(Scope *S); - void CodeCompleteObjCPropertySetter(Scope *S); - void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, - bool IsParameter); - void CodeCompleteObjCMessageReceiver(Scope *S); - void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, - ArrayRef<IdentifierInfo *> SelIdents, - bool AtArgumentExpression); - void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, - ArrayRef<IdentifierInfo *> SelIdents, - bool AtArgumentExpression, - bool IsSuper = false); - void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, - ArrayRef<IdentifierInfo *> SelIdents, - bool AtArgumentExpression, - ObjCInterfaceDecl *Super = nullptr); - void CodeCompleteObjCForCollection(Scope *S, - DeclGroupPtrTy IterationVar); - void CodeCompleteObjCSelector(Scope *S, - ArrayRef<IdentifierInfo *> SelIdents); - void CodeCompleteObjCProtocolReferences( - ArrayRef<IdentifierLocPair> Protocols); - void CodeCompleteObjCProtocolDecl(Scope *S); - void CodeCompleteObjCInterfaceDecl(Scope *S); - void CodeCompleteObjCSuperclass(Scope *S, - IdentifierInfo *ClassName, - SourceLocation ClassNameLoc); - void CodeCompleteObjCImplementationDecl(Scope *S); - void CodeCompleteObjCInterfaceCategory(Scope *S, - IdentifierInfo *ClassName, - SourceLocation ClassNameLoc); - void CodeCompleteObjCImplementationCategory(Scope *S, - IdentifierInfo *ClassName, - SourceLocation ClassNameLoc); - void CodeCompleteObjCPropertyDefinition(Scope *S); - void CodeCompleteObjCPropertySynthesizeIvar(Scope *S, - IdentifierInfo *PropertyName); - void CodeCompleteObjCMethodDecl(Scope *S, - bool IsInstanceMethod, - ParsedType ReturnType); - void CodeCompleteObjCMethodDeclSelector(Scope *S, - bool IsInstanceMethod, - bool AtParameterName, - ParsedType ReturnType, - ArrayRef<IdentifierInfo *> SelIdents); - void CodeCompletePreprocessorDirective(bool InConditional); - void CodeCompleteInPreprocessorConditionalExclusion(Scope *S); - void CodeCompletePreprocessorMacroName(bool IsDefinition); - void CodeCompletePreprocessorExpression(); - void CodeCompletePreprocessorMacroArgument(Scope *S, - IdentifierInfo *Macro, - MacroInfo *MacroInfo, - unsigned Argument); - void CodeCompleteNaturalLanguage(); - void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - SmallVectorImpl<CodeCompletionResult> &Results); - //@} - - //===--------------------------------------------------------------------===// - // Extra semantic analysis beyond the C type system - -public: - SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, - unsigned ByteNo) const; - -private: - void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, - const ArraySubscriptExpr *ASE=nullptr, - bool AllowOnePastEnd=true, bool IndexNegated=false); - void CheckArrayAccess(const Expr *E); - // Used to grab the relevant information from a FormatAttr and a - // FunctionDeclaration. - struct FormatStringInfo { - unsigned FormatIdx; - unsigned FirstDataArg; - bool HasVAListArg; - }; - - static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, - FormatStringInfo *FSI); - bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, - const FunctionProtoType *Proto); - bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, - ArrayRef<const Expr *> Args); - bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, - const FunctionProtoType *Proto); - bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto); - void CheckConstructorCall(FunctionDecl *FDecl, - ArrayRef<const Expr *> Args, - const FunctionProtoType *Proto, - SourceLocation Loc); - - void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, - ArrayRef<const Expr *> Args, bool IsMemberFunction, - SourceLocation Loc, SourceRange Range, - VariadicCallType CallType); - - bool CheckObjCString(Expr *Arg); - - ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, - unsigned BuiltinID, CallExpr *TheCall); - - bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, - unsigned MaxWidth); - bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - - bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - - bool SemaBuiltinVAStartImpl(CallExpr *TheCall); - bool SemaBuiltinVAStart(CallExpr *TheCall); - bool SemaBuiltinMSVAStart(CallExpr *TheCall); - bool SemaBuiltinVAStartARM(CallExpr *Call); - bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); - bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); - -public: - // Used by C++ template instantiation. - ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); - ExprResult SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, - SourceLocation BuiltinLoc, - SourceLocation RParenLoc); - -private: - bool SemaBuiltinPrefetch(CallExpr *TheCall); - bool SemaBuiltinAssume(CallExpr *TheCall); - bool SemaBuiltinAssumeAligned(CallExpr *TheCall); - bool SemaBuiltinLongjmp(CallExpr *TheCall); - bool SemaBuiltinSetjmp(CallExpr *TheCall); - ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); - ExprResult SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult); - ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, - AtomicExpr::AtomicOp Op); - bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, - llvm::APSInt &Result); - bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, - int Low, int High); - bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, - int ArgNum, unsigned ExpectedFieldNum, - bool AllowName); -public: - enum FormatStringType { - FST_Scanf, - FST_Printf, - FST_NSString, - FST_Strftime, - FST_Strfmon, - FST_Kprintf, - FST_FreeBSDKPrintf, - FST_OSTrace, - FST_Unknown - }; - static FormatStringType GetFormatStringType(const FormatAttr *Format); - - void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr, - ArrayRef<const Expr *> Args, bool HasVAListArg, - unsigned format_idx, unsigned firstDataArg, - FormatStringType Type, bool inFunctionCall, - VariadicCallType CallType, - llvm::SmallBitVector &CheckedVarArgs); - - bool FormatStringHasSArg(const StringLiteral *FExpr); - - static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); - -private: - bool CheckFormatArguments(const FormatAttr *Format, - ArrayRef<const Expr *> Args, - bool IsCXXMember, - VariadicCallType CallType, - SourceLocation Loc, SourceRange Range, - llvm::SmallBitVector &CheckedVarArgs); - bool CheckFormatArguments(ArrayRef<const Expr *> Args, - bool HasVAListArg, unsigned format_idx, - unsigned firstDataArg, FormatStringType Type, - VariadicCallType CallType, - SourceLocation Loc, SourceRange range, - llvm::SmallBitVector &CheckedVarArgs); - - void CheckAbsoluteValueFunction(const CallExpr *Call, - const FunctionDecl *FDecl, - IdentifierInfo *FnInfo); - - void CheckMemaccessArguments(const CallExpr *Call, - unsigned BId, - IdentifierInfo *FnName); - - void CheckStrlcpycatArguments(const CallExpr *Call, - IdentifierInfo *FnName); - - void CheckStrncatArguments(const CallExpr *Call, - IdentifierInfo *FnName); - - void CheckReturnValExpr(Expr *RetValExp, QualType lhsType, - SourceLocation ReturnLoc, - bool isObjCMethod = false, - const AttrVec *Attrs = nullptr, - const FunctionDecl *FD = nullptr); - - void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS); - void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); - void CheckBoolLikeConversion(Expr *E, SourceLocation CC); - void CheckForIntOverflow(Expr *E); - void CheckUnsequencedOperations(Expr *E); - - /// \brief Perform semantic checks on a completed expression. This will either - /// be a full-expression or a default argument expression. - void CheckCompletedExpr(Expr *E, SourceLocation CheckLoc = SourceLocation(), - bool IsConstexpr = false); - - void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, - Expr *Init); - - /// \brief Check if the given expression contains 'break' or 'continue' - /// statement that produces control flow different from GCC. - void CheckBreakContinueBinding(Expr *E); - - /// \brief Check whether receiver is mutable ObjC container which - /// attempts to add itself into the container - void CheckObjCCircularContainer(ObjCMessageExpr *Message); - - void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE); - void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, - bool DeleteWasArrayForm); -public: - /// \brief Register a magic integral constant to be used as a type tag. - void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, - uint64_t MagicValue, QualType Type, - bool LayoutCompatible, bool MustBeNull); - - struct TypeTagData { - TypeTagData() {} - - TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) : - Type(Type), LayoutCompatible(LayoutCompatible), - MustBeNull(MustBeNull) - {} - - QualType Type; - - /// If true, \c Type should be compared with other expression's types for - /// layout-compatibility. - unsigned LayoutCompatible : 1; - unsigned MustBeNull : 1; - }; - - /// A pair of ArgumentKind identifier and magic value. This uniquely - /// identifies the magic value. - typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue; - -private: - /// \brief A map from magic value to type information. - std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>> - TypeTagForDatatypeMagicValues; - - /// \brief Peform checks on a call of a function with argument_with_type_tag - /// or pointer_with_type_tag attributes. - void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, - const Expr * const *ExprArgs); - - /// \brief The parser's current scope. - /// - /// The parser maintains this state here. - Scope *CurScope; - - mutable IdentifierInfo *Ident_super; - mutable IdentifierInfo *Ident___float128; - - /// Nullability type specifiers. - IdentifierInfo *Ident__Nonnull = nullptr; - IdentifierInfo *Ident__Nullable = nullptr; - IdentifierInfo *Ident__Null_unspecified = nullptr; - - IdentifierInfo *Ident_NSError = nullptr; - -protected: - friend class Parser; - friend class InitializationSequence; - friend class ASTReader; - friend class ASTDeclReader; - friend class ASTWriter; - -public: - /// Retrieve the keyword associated - IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability); - - /// The struct behind the CFErrorRef pointer. - RecordDecl *CFError = nullptr; - - /// Retrieve the identifier "NSError". - IdentifierInfo *getNSErrorIdent(); - - /// \brief Retrieve the parser's current scope. - /// - /// This routine must only be used when it is certain that semantic analysis - /// and the parser are in precisely the same context, which is not the case - /// when, e.g., we are performing any kind of template instantiation. - /// Therefore, the only safe places to use this scope are in the parser - /// itself and in routines directly invoked from the parser and *never* from - /// template substitution or instantiation. - Scope *getCurScope() const { return CurScope; } - - void incrementMSManglingNumber() const { - return CurScope->incrementMSManglingNumber(); - } - - IdentifierInfo *getSuperIdentifier() const; - IdentifierInfo *getFloat128Identifier() const; - - Decl *getObjCDeclContext() const; - - DeclContext *getCurLexicalContext() const { - return OriginalLexicalContext ? OriginalLexicalContext : CurContext; - } - - AvailabilityResult getCurContextAvailability() const; - - const DeclContext *getCurObjCLexicalContext() const { - const DeclContext *DC = getCurLexicalContext(); - // A category implicitly has the attribute of the interface. - if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) - DC = CatD->getClassInterface(); - return DC; - } - - /// \brief To be used for checking whether the arguments being passed to - /// function exceeds the number of parameters expected for it. - static bool TooManyArguments(size_t NumParams, size_t NumArgs, - bool PartialOverloading = false) { - // We check whether we're just after a comma in code-completion. - if (NumArgs > 0 && PartialOverloading) - return NumArgs + 1 > NumParams; // If so, we view as an extra argument. - return NumArgs > NumParams; - } - - // Emitting members of dllexported classes is delayed until the class - // (including field initializers) is fully parsed. - SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; -}; - -/// \brief RAII object that enters a new expression evaluation context. -class EnterExpressionEvaluationContext { - Sema &Actions; - -public: - EnterExpressionEvaluationContext(Sema &Actions, - Sema::ExpressionEvaluationContext NewContext, - Decl *LambdaContextDecl = nullptr, - bool IsDecltype = false) - : Actions(Actions) { - Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, - IsDecltype); - } - EnterExpressionEvaluationContext(Sema &Actions, - Sema::ExpressionEvaluationContext NewContext, - Sema::ReuseLambdaContextDecl_t, - bool IsDecltype = false) - : Actions(Actions) { - Actions.PushExpressionEvaluationContext(NewContext, - Sema::ReuseLambdaContextDecl, - IsDecltype); - } - - ~EnterExpressionEvaluationContext() { - Actions.PopExpressionEvaluationContext(); - } -}; - -DeductionFailureInfo -MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK, - sema::TemplateDeductionInfo &Info); - -/// \brief Contains a late templated function. -/// Will be parsed at the end of the translation unit, used by Sema & Parser. -struct LateParsedTemplate { - CachedTokens Toks; - /// \brief The template function declaration to be late parsed. - Decl *D; -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h deleted file mode 100644 index 676646a..0000000 --- a/include/clang/Sema/SemaConsumer.h +++ /dev/null @@ -1,48 +0,0 @@ -//===--- SemaConsumer.h - Abstract interface for AST semantics --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the SemaConsumer class, a subclass of -// ASTConsumer that is used by AST clients that also require -// additional semantic analysis. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_SEMACONSUMER_H -#define LLVM_CLANG_SEMA_SEMACONSUMER_H - -#include "clang/AST/ASTConsumer.h" - -namespace clang { - class Sema; - - /// \brief An abstract interface that should be implemented by - /// clients that read ASTs and then require further semantic - /// analysis of the entities in those ASTs. - class SemaConsumer : public ASTConsumer { - virtual void anchor(); - public: - SemaConsumer() { - ASTConsumer::SemaConsumer = true; - } - - /// \brief Initialize the semantic consumer with the Sema instance - /// being used to perform semantic analysis on the abstract syntax - /// tree. - virtual void InitializeSema(Sema &S) {} - - /// \brief Inform the semantic consumer that Sema is no longer available. - virtual void ForgetSema() {} - - // isa/cast/dyn_cast support - static bool classof(const ASTConsumer *Consumer) { - return Consumer->SemaConsumer; - } - }; -} - -#endif diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h deleted file mode 100644 index 7740d5e..0000000 --- a/include/clang/Sema/SemaDiagnostic.h +++ /dev/null @@ -1,28 +0,0 @@ -//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H -#define LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H - -#include "clang/Basic/Diagnostic.h" - -namespace clang { - namespace diag { - enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, -#define SEMASTART -#include "clang/Basic/DiagnosticSemaKinds.inc" -#undef DIAG - NUM_BUILTIN_SEMA_DIAGNOSTICS - }; - } // end namespace diag -} // end namespace clang - -#endif diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h deleted file mode 100644 index 343ccfb..0000000 --- a/include/clang/Sema/SemaFixItUtils.h +++ /dev/null @@ -1,91 +0,0 @@ -//===--- SemaFixItUtils.h - Sema FixIts -----------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines helper classes for generation of Sema FixItHints. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_SEMAFIXITUTILS_H -#define LLVM_CLANG_SEMA_SEMAFIXITUTILS_H - -#include "clang/AST/Expr.h" - -namespace clang { - -enum OverloadFixItKind { - OFIK_Undefined = 0, - OFIK_Dereference, - OFIK_TakeAddress, - OFIK_RemoveDereference, - OFIK_RemoveTakeAddress -}; - -class Sema; - -/// The class facilities generation and storage of conversion FixIts. Hints for -/// new conversions are added using TryToFixConversion method. The default type -/// conversion checker can be reset. -struct ConversionFixItGenerator { - /// Performs a simple check to see if From type can be converted to To type. - static bool compareTypesSimple(CanQualType From, - CanQualType To, - Sema &S, - SourceLocation Loc, - ExprValueKind FromVK); - - /// The list of Hints generated so far. - std::vector<FixItHint> Hints; - - /// The number of Conversions fixed. This can be different from the size - /// of the Hints vector since we allow multiple FixIts per conversion. - unsigned NumConversionsFixed; - - /// The type of fix applied. If multiple conversions are fixed, corresponds - /// to the kid of the very first conversion. - OverloadFixItKind Kind; - - typedef bool (*TypeComparisonFuncTy) (const CanQualType FromTy, - const CanQualType ToTy, - Sema &S, - SourceLocation Loc, - ExprValueKind FromVK); - /// The type comparison function used to decide if expression FromExpr of - /// type FromTy can be converted to ToTy. For example, one could check if - /// an implicit conversion exists. Returns true if comparison exists. - TypeComparisonFuncTy CompareTypes; - - ConversionFixItGenerator(TypeComparisonFuncTy Foo): NumConversionsFixed(0), - Kind(OFIK_Undefined), - CompareTypes(Foo) {} - - ConversionFixItGenerator(): NumConversionsFixed(0), - Kind(OFIK_Undefined), - CompareTypes(compareTypesSimple) {} - - /// Resets the default conversion checker method. - void setConversionChecker(TypeComparisonFuncTy Foo) { - CompareTypes = Foo; - } - - /// If possible, generates and stores a fix for the given conversion. - bool tryToFixConversion(const Expr *FromExpr, - const QualType FromQTy, const QualType ToQTy, - Sema &S); - - void clear() { - Hints.clear(); - NumConversionsFixed = 0; - } - - bool isNull() { - return (NumConversionsFixed == 0); - } -}; - -} // endof namespace clang -#endif diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h deleted file mode 100644 index 60c6598..0000000 --- a/include/clang/Sema/SemaInternal.h +++ /dev/null @@ -1,346 +0,0 @@ -//===--- SemaInternal.h - Internal Sema Interfaces --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides common API and #includes for the internal -// implementation of Sema. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_SEMAINTERNAL_H -#define LLVM_CLANG_SEMA_SEMAINTERNAL_H - -#include "clang/AST/ASTContext.h" -#include "clang/Sema/Lookup.h" -#include "clang/Sema/Sema.h" -#include "clang/Sema/SemaDiagnostic.h" - -namespace clang { - -inline PartialDiagnostic Sema::PDiag(unsigned DiagID) { - return PartialDiagnostic(DiagID, Context.getDiagAllocator()); -} - -inline bool -FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) { - return FTI.NumParams == 1 && !FTI.isVariadic && - FTI.Params[0].Ident == nullptr && FTI.Params[0].Param && - cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType(); -} - -inline bool -FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI) { - // Assume FTI is well-formed. - return FTI.NumParams && !FTIHasSingleVoidParameter(FTI); -} - -// This requires the variable to be non-dependent and the initializer -// to not be value dependent. -inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) { - const VarDecl *DefVD = nullptr; - return !isa<ParmVarDecl>(Var) && - Var->isUsableInConstantExpressions(Context) && - Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); -} - -// Helper function to check whether D's attributes match current CUDA mode. -// Decls with mismatched attributes and related diagnostics may have to be -// ignored during this CUDA compilation pass. -inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) { - if (!LangOpts.CUDA || !D) - return true; - bool isDeviceSideDecl = D->hasAttr<CUDADeviceAttr>() || - D->hasAttr<CUDASharedAttr>() || - D->hasAttr<CUDAGlobalAttr>(); - return isDeviceSideDecl == LangOpts.CUDAIsDevice; -} - -// Directly mark a variable odr-used. Given a choice, prefer to use -// MarkVariableReferenced since it does additional checks and then -// calls MarkVarDeclODRUsed. -// If the variable must be captured: -// - if FunctionScopeIndexToStopAt is null, capture it in the CurContext -// - else capture it in the DeclContext that maps to the -// *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack. -inline void MarkVarDeclODRUsed(VarDecl *Var, - SourceLocation Loc, Sema &SemaRef, - const unsigned *const FunctionScopeIndexToStopAt) { - // Keep track of used but undefined variables. - // FIXME: We shouldn't suppress this warning for static data members. - if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && - !Var->isExternallyVisible() && - !(Var->isStaticDataMember() && Var->hasInit())) { - SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()]; - if (old.isInvalid()) old = Loc; - } - QualType CaptureType, DeclRefType; - SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit, - /*EllipsisLoc*/ SourceLocation(), - /*BuildAndDiagnose*/ true, - CaptureType, DeclRefType, - FunctionScopeIndexToStopAt); - - Var->markUsed(SemaRef.Context); -} - -/// Return a DLL attribute from the declaration. -inline InheritableAttr *getDLLAttr(Decl *D) { - assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) && - "A declaration cannot be both dllimport and dllexport."); - if (auto *Import = D->getAttr<DLLImportAttr>()) - return Import; - if (auto *Export = D->getAttr<DLLExportAttr>()) - return Export; - return nullptr; -} - -class TypoCorrectionConsumer : public VisibleDeclConsumer { - typedef SmallVector<TypoCorrection, 1> TypoResultList; - typedef llvm::StringMap<TypoResultList> TypoResultsMap; - typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap; - -public: - TypoCorrectionConsumer(Sema &SemaRef, - const DeclarationNameInfo &TypoName, - Sema::LookupNameKind LookupKind, - Scope *S, CXXScopeSpec *SS, - std::unique_ptr<CorrectionCandidateCallback> CCC, - DeclContext *MemberContext, - bool EnteringContext) - : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0), - SavedTCIndex(0), SemaRef(SemaRef), S(S), - SS(SS ? llvm::make_unique<CXXScopeSpec>(*SS) : nullptr), - CorrectionValidator(std::move(CCC)), MemberContext(MemberContext), - Result(SemaRef, TypoName, LookupKind), - Namespaces(SemaRef.Context, SemaRef.CurContext, SS), - EnteringContext(EnteringContext), SearchNamespaces(false) { - Result.suppressDiagnostics(); - // Arrange for ValidatedCorrections[0] to always be an empty correction. - ValidatedCorrections.push_back(TypoCorrection()); - } - - bool includeHiddenDecls() const override { return true; } - - // Methods for adding potential corrections to the consumer. - void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, - bool InBaseClass) override; - void FoundName(StringRef Name); - void addKeywordResult(StringRef Keyword); - void addCorrection(TypoCorrection Correction); - - bool empty() const { - return CorrectionResults.empty() && ValidatedCorrections.size() == 1; - } - - /// \brief Return the list of TypoCorrections for the given identifier from - /// the set of corrections that have the closest edit distance, if any. - TypoResultList &operator[](StringRef Name) { - return CorrectionResults.begin()->second[Name]; - } - - /// \brief Return the edit distance of the corrections that have the - /// closest/best edit distance from the original typop. - unsigned getBestEditDistance(bool Normalized) { - if (CorrectionResults.empty()) - return (std::numeric_limits<unsigned>::max)(); - - unsigned BestED = CorrectionResults.begin()->first; - return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED; - } - - /// \brief Set-up method to add to the consumer the set of namespaces to use - /// in performing corrections to nested name specifiers. This method also - /// implicitly adds all of the known classes in the current AST context to the - /// to the consumer for correcting nested name specifiers. - void - addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces); - - /// \brief Return the next typo correction that passes all internal filters - /// and is deemed valid by the consumer's CorrectionCandidateCallback, - /// starting with the corrections that have the closest edit distance. An - /// empty TypoCorrection is returned once no more viable corrections remain - /// in the consumer. - const TypoCorrection &getNextCorrection(); - - /// \brief Get the last correction returned by getNextCorrection(). - const TypoCorrection &getCurrentCorrection() { - return CurrentTCIndex < ValidatedCorrections.size() - ? ValidatedCorrections[CurrentTCIndex] - : ValidatedCorrections[0]; // The empty correction. - } - - /// \brief Return the next typo correction like getNextCorrection, but keep - /// the internal state pointed to the current correction (i.e. the next time - /// getNextCorrection is called, it will return the same correction returned - /// by peekNextcorrection). - const TypoCorrection &peekNextCorrection() { - auto Current = CurrentTCIndex; - const TypoCorrection &TC = getNextCorrection(); - CurrentTCIndex = Current; - return TC; - } - - /// \brief Reset the consumer's position in the stream of viable corrections - /// (i.e. getNextCorrection() will return each of the previously returned - /// corrections in order before returning any new corrections). - void resetCorrectionStream() { - CurrentTCIndex = 0; - } - - /// \brief Return whether the end of the stream of corrections has been - /// reached. - bool finished() { - return CorrectionResults.empty() && - CurrentTCIndex >= ValidatedCorrections.size(); - } - - /// \brief Save the current position in the correction stream (overwriting any - /// previously saved position). - void saveCurrentPosition() { - SavedTCIndex = CurrentTCIndex; - } - - /// \brief Restore the saved position in the correction stream. - void restoreSavedPosition() { - CurrentTCIndex = SavedTCIndex; - } - - ASTContext &getContext() const { return SemaRef.Context; } - const LookupResult &getLookupResult() const { return Result; } - - bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; } - const CXXScopeSpec *getSS() const { return SS.get(); } - Scope *getScope() const { return S; } - -private: - class NamespaceSpecifierSet { - struct SpecifierInfo { - DeclContext* DeclCtx; - NestedNameSpecifier* NameSpecifier; - unsigned EditDistance; - }; - - typedef SmallVector<DeclContext*, 4> DeclContextList; - typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList; - - ASTContext &Context; - DeclContextList CurContextChain; - std::string CurNameSpecifier; - SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers; - SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers; - - std::map<unsigned, SpecifierInfoList> DistanceMap; - - /// \brief Helper for building the list of DeclContexts between the current - /// context and the top of the translation unit - static DeclContextList buildContextChain(DeclContext *Start); - - unsigned buildNestedNameSpecifier(DeclContextList &DeclChain, - NestedNameSpecifier *&NNS); - - public: - NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext, - CXXScopeSpec *CurScopeSpec); - - /// \brief Add the DeclContext (a namespace or record) to the set, computing - /// the corresponding NestedNameSpecifier and its distance in the process. - void addNameSpecifier(DeclContext *Ctx); - - /// \brief Provides flat iteration over specifiers, sorted by distance. - class iterator - : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag, - SpecifierInfo> { - /// Always points to the last element in the distance map. - const std::map<unsigned, SpecifierInfoList>::iterator OuterBack; - /// Iterator on the distance map. - std::map<unsigned, SpecifierInfoList>::iterator Outer; - /// Iterator on an element in the distance map. - SpecifierInfoList::iterator Inner; - - public: - iterator(NamespaceSpecifierSet &Set, bool IsAtEnd) - : OuterBack(std::prev(Set.DistanceMap.end())), - Outer(Set.DistanceMap.begin()), - Inner(!IsAtEnd ? Outer->second.begin() : OuterBack->second.end()) { - assert(!Set.DistanceMap.empty()); - } - - iterator &operator++() { - ++Inner; - if (Inner == Outer->second.end() && Outer != OuterBack) { - ++Outer; - Inner = Outer->second.begin(); - } - return *this; - } - - SpecifierInfo &operator*() { return *Inner; } - bool operator==(const iterator &RHS) const { return Inner == RHS.Inner; } - }; - - iterator begin() { return iterator(*this, /*IsAtEnd=*/false); } - iterator end() { return iterator(*this, /*IsAtEnd=*/true); } - }; - - void addName(StringRef Name, NamedDecl *ND, - NestedNameSpecifier *NNS = nullptr, bool isKeyword = false); - - /// \brief Find any visible decls for the given typo correction candidate. - /// If none are found, it to the set of candidates for which qualified lookups - /// will be performed to find possible nested name specifier changes. - bool resolveCorrection(TypoCorrection &Candidate); - - /// \brief Perform qualified lookups on the queued set of typo correction - /// candidates and add the nested name specifier changes to each candidate if - /// a lookup succeeds (at which point the candidate will be returned to the - /// main pool of potential corrections). - void performQualifiedLookups(); - - /// \brief The name written that is a typo in the source. - IdentifierInfo *Typo; - - /// \brief The results found that have the smallest edit distance - /// found (so far) with the typo name. - /// - /// The pointer value being set to the current DeclContext indicates - /// whether there is a keyword with this name. - TypoEditDistanceMap CorrectionResults; - - SmallVector<TypoCorrection, 4> ValidatedCorrections; - size_t CurrentTCIndex; - size_t SavedTCIndex; - - Sema &SemaRef; - Scope *S; - std::unique_ptr<CXXScopeSpec> SS; - std::unique_ptr<CorrectionCandidateCallback> CorrectionValidator; - DeclContext *MemberContext; - LookupResult Result; - NamespaceSpecifierSet Namespaces; - SmallVector<TypoCorrection, 2> QualifiedResults; - bool EnteringContext; - bool SearchNamespaces; -}; - -inline Sema::TypoExprState::TypoExprState() {} - -inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT { - *this = std::move(other); -} - -inline Sema::TypoExprState &Sema::TypoExprState::operator=( - Sema::TypoExprState &&other) LLVM_NOEXCEPT { - Consumer = std::move(other.Consumer); - DiagHandler = std::move(other.DiagHandler); - RecoveryHandler = std::move(other.RecoveryHandler); - return *this; -} - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h deleted file mode 100644 index d043e2c..0000000 --- a/include/clang/Sema/SemaLambda.h +++ /dev/null @@ -1,36 +0,0 @@ -//===--- SemaLambda.h - Lambda Helper Functions --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief This file provides some common utility functions for processing -/// Lambdas. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_SEMALAMBDA_H -#define LLVM_CLANG_SEMA_SEMALAMBDA_H -#include "clang/AST/ASTLambda.h" -#include "clang/Sema/ScopeInfo.h" -namespace clang { - - -/// \brief Examines the FunctionScopeInfo stack to determine the nearest -/// enclosing lambda (to the current lambda) that is 'capture-capable' for -/// the variable referenced in the current lambda (i.e. \p VarToCapture). -/// If successful, returns the index into Sema's FunctionScopeInfo stack -/// of the capture-capable lambda's LambdaScopeInfo. -/// See Implementation for more detailed comments. - -Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda( - ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes, - VarDecl *VarToCapture, Sema &S); - -} // clang - -#endif diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h deleted file mode 100644 index c092630..0000000 --- a/include/clang/Sema/Template.h +++ /dev/null @@ -1,519 +0,0 @@ -//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/ -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -//===----------------------------------------------------------------------===/ -// -// This file provides types used in the semantic analysis of C++ templates. -// -//===----------------------------------------------------------------------===/ -#ifndef LLVM_CLANG_SEMA_TEMPLATE_H -#define LLVM_CLANG_SEMA_TEMPLATE_H - -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/Sema/Sema.h" -#include "llvm/ADT/SmallVector.h" -#include <cassert> -#include <utility> - -namespace clang { - /// \brief Data structure that captures multiple levels of template argument - /// lists for use in template instantiation. - /// - /// Multiple levels of template arguments occur when instantiating the - /// definitions of member templates. For example: - /// - /// \code - /// template<typename T> - /// struct X { - /// template<T Value> - /// struct Y { - /// void f(); - /// }; - /// }; - /// \endcode - /// - /// When instantiating X<int>::Y<17>::f, the multi-level template argument - /// list will contain a template argument list (int) at depth 0 and a - /// template argument list (17) at depth 1. - class MultiLevelTemplateArgumentList { - /// \brief The template argument list at a certain template depth - typedef ArrayRef<TemplateArgument> ArgList; - - /// \brief The template argument lists, stored from the innermost template - /// argument list (first) to the outermost template argument list (last). - SmallVector<ArgList, 4> TemplateArgumentLists; - - public: - /// \brief Construct an empty set of template argument lists. - MultiLevelTemplateArgumentList() { } - - /// \brief Construct a single-level template argument list. - explicit - MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { - addOuterTemplateArguments(&TemplateArgs); - } - - /// \brief Determine the number of levels in this template argument - /// list. - unsigned getNumLevels() const { return TemplateArgumentLists.size(); } - - /// \brief Retrieve the template argument at a given depth and index. - const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { - assert(Depth < TemplateArgumentLists.size()); - assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); - return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; - } - - /// \brief Determine whether there is a non-NULL template argument at the - /// given depth and index. - /// - /// There must exist a template argument list at the given depth. - bool hasTemplateArgument(unsigned Depth, unsigned Index) const { - assert(Depth < TemplateArgumentLists.size()); - - if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) - return false; - - return !(*this)(Depth, Index).isNull(); - } - - /// \brief Clear out a specific template argument. - void setArgument(unsigned Depth, unsigned Index, - TemplateArgument Arg) { - assert(Depth < TemplateArgumentLists.size()); - assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); - const_cast<TemplateArgument&>( - TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) - = Arg; - } - - /// \brief Add a new outermost level to the multi-level template argument - /// list. - void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { - addOuterTemplateArguments(ArgList(TemplateArgs->data(), - TemplateArgs->size())); - } - - /// \brief Add a new outmost level to the multi-level template argument - /// list. - void addOuterTemplateArguments(ArgList Args) { - TemplateArgumentLists.push_back(Args); - } - - /// \brief Retrieve the innermost template argument list. - const ArgList &getInnermost() const { - return TemplateArgumentLists.front(); - } - }; - - /// \brief The context in which partial ordering of function templates occurs. - enum TPOC { - /// \brief Partial ordering of function templates for a function call. - TPOC_Call, - /// \brief Partial ordering of function templates for a call to a - /// conversion function. - TPOC_Conversion, - /// \brief Partial ordering of function templates in other contexts, e.g., - /// taking the address of a function template or matching a function - /// template specialization to a function template. - TPOC_Other - }; - - // This is lame but unavoidable in a world without forward - // declarations of enums. The alternatives are to either pollute - // Sema.h (by including this file) or sacrifice type safety (by - // making Sema.h declare things as enums). - class TemplatePartialOrderingContext { - TPOC Value; - public: - TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} - operator TPOC() const { return Value; } - }; - - /// \brief Captures a template argument whose value has been deduced - /// via c++ template argument deduction. - class DeducedTemplateArgument : public TemplateArgument { - /// \brief For a non-type template argument, whether the value was - /// deduced from an array bound. - bool DeducedFromArrayBound; - - public: - DeducedTemplateArgument() - : TemplateArgument(), DeducedFromArrayBound(false) { } - - DeducedTemplateArgument(const TemplateArgument &Arg, - bool DeducedFromArrayBound = false) - : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { } - - /// \brief Construct an integral non-type template argument that - /// has been deduced, possibly from an array bound. - DeducedTemplateArgument(ASTContext &Ctx, - const llvm::APSInt &Value, - QualType ValueType, - bool DeducedFromArrayBound) - : TemplateArgument(Ctx, Value, ValueType), - DeducedFromArrayBound(DeducedFromArrayBound) { } - - /// \brief For a non-type template argument, determine whether the - /// template argument was deduced from an array bound. - bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } - - /// \brief Specify whether the given non-type template argument - /// was deduced from an array bound. - void setDeducedFromArrayBound(bool Deduced) { - DeducedFromArrayBound = Deduced; - } - }; - - /// \brief A stack-allocated class that identifies which local - /// variable declaration instantiations are present in this scope. - /// - /// A new instance of this class type will be created whenever we - /// instantiate a new function declaration, which will have its own - /// set of parameter declarations. - class LocalInstantiationScope { - public: - /// \brief A set of declarations. - typedef SmallVector<ParmVarDecl *, 4> DeclArgumentPack; - - private: - /// \brief Reference to the semantic analysis that is performing - /// this template instantiation. - Sema &SemaRef; - - typedef llvm::SmallDenseMap< - const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4> - LocalDeclsMap; - - /// \brief A mapping from local declarations that occur - /// within a template to their instantiations. - /// - /// This mapping is used during instantiation to keep track of, - /// e.g., function parameter and variable declarations. For example, - /// given: - /// - /// \code - /// template<typename T> T add(T x, T y) { return x + y; } - /// \endcode - /// - /// when we instantiate add<int>, we will introduce a mapping from - /// the ParmVarDecl for 'x' that occurs in the template to the - /// instantiated ParmVarDecl for 'x'. - /// - /// For a parameter pack, the local instantiation scope may contain a - /// set of instantiated parameters. This is stored as a DeclArgumentPack - /// pointer. - LocalDeclsMap LocalDecls; - - /// \brief The set of argument packs we've allocated. - SmallVector<DeclArgumentPack *, 1> ArgumentPacks; - - /// \brief The outer scope, which contains local variable - /// definitions from some other instantiation (that may not be - /// relevant to this particular scope). - LocalInstantiationScope *Outer; - - /// \brief Whether we have already exited this scope. - bool Exited; - - /// \brief Whether to combine this scope with the outer scope, such that - /// lookup will search our outer scope. - bool CombineWithOuterScope; - - /// \brief If non-NULL, the template parameter pack that has been - /// partially substituted per C++0x [temp.arg.explicit]p9. - NamedDecl *PartiallySubstitutedPack; - - /// \brief If \c PartiallySubstitutedPack is non-null, the set of - /// explicitly-specified template arguments in that pack. - const TemplateArgument *ArgsInPartiallySubstitutedPack; - - /// \brief If \c PartiallySubstitutedPack, the number of - /// explicitly-specified template arguments in - /// ArgsInPartiallySubstitutedPack. - unsigned NumArgsInPartiallySubstitutedPack; - - // This class is non-copyable - LocalInstantiationScope( - const LocalInstantiationScope &) = delete; - void operator=(const LocalInstantiationScope &) = delete; - - public: - LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) - : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), - Exited(false), CombineWithOuterScope(CombineWithOuterScope), - PartiallySubstitutedPack(nullptr) - { - SemaRef.CurrentInstantiationScope = this; - } - - ~LocalInstantiationScope() { - Exit(); - } - - const Sema &getSema() const { return SemaRef; } - - /// \brief Exit this local instantiation scope early. - void Exit() { - if (Exited) - return; - - for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) - delete ArgumentPacks[I]; - - SemaRef.CurrentInstantiationScope = Outer; - Exited = true; - } - - /// \brief Clone this scope, and all outer scopes, down to the given - /// outermost scope. - LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { - if (this == Outermost) return this; - - // Save the current scope from SemaRef since the LocalInstantiationScope - // will overwrite it on construction - LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; - - LocalInstantiationScope *newScope = - new LocalInstantiationScope(SemaRef, CombineWithOuterScope); - - newScope->Outer = nullptr; - if (Outer) - newScope->Outer = Outer->cloneScopes(Outermost); - - newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; - newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; - newScope->NumArgsInPartiallySubstitutedPack = - NumArgsInPartiallySubstitutedPack; - - for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); - I != E; ++I) { - const Decl *D = I->first; - llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = - newScope->LocalDecls[D]; - if (I->second.is<Decl *>()) { - Stored = I->second.get<Decl *>(); - } else { - DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); - DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); - Stored = NewPack; - newScope->ArgumentPacks.push_back(NewPack); - } - } - // Restore the saved scope to SemaRef - SemaRef.CurrentInstantiationScope = oldScope; - return newScope; - } - - /// \brief deletes the given scope, and all otuer scopes, down to the - /// given outermost scope. - static void deleteScopes(LocalInstantiationScope *Scope, - LocalInstantiationScope *Outermost) { - while (Scope && Scope != Outermost) { - LocalInstantiationScope *Out = Scope->Outer; - delete Scope; - Scope = Out; - } - } - - /// \brief Find the instantiation of the declaration D within the current - /// instantiation scope. - /// - /// \param D The declaration whose instantiation we are searching for. - /// - /// \returns A pointer to the declaration or argument pack of declarations - /// to which the declaration \c D is instantiated, if found. Otherwise, - /// returns NULL. - llvm::PointerUnion<Decl *, DeclArgumentPack *> * - findInstantiationOf(const Decl *D); - - void InstantiatedLocal(const Decl *D, Decl *Inst); - void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst); - void MakeInstantiatedLocalArgPack(const Decl *D); - - /// \brief Note that the given parameter pack has been partially substituted - /// via explicit specification of template arguments - /// (C++0x [temp.arg.explicit]p9). - /// - /// \param Pack The parameter pack, which will always be a template - /// parameter pack. - /// - /// \param ExplicitArgs The explicitly-specified template arguments provided - /// for this parameter pack. - /// - /// \param NumExplicitArgs The number of explicitly-specified template - /// arguments provided for this parameter pack. - void SetPartiallySubstitutedPack(NamedDecl *Pack, - const TemplateArgument *ExplicitArgs, - unsigned NumExplicitArgs); - - /// \brief Reset the partially-substituted pack when it is no longer of - /// interest. - void ResetPartiallySubstitutedPack() { - assert(PartiallySubstitutedPack && "No partially-substituted pack"); - PartiallySubstitutedPack = nullptr; - ArgsInPartiallySubstitutedPack = nullptr; - NumArgsInPartiallySubstitutedPack = 0; - } - - /// \brief Retrieve the partially-substitued template parameter pack. - /// - /// If there is no partially-substituted parameter pack, returns NULL. - NamedDecl * - getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, - unsigned *NumExplicitArgs = nullptr) const; - }; - - class TemplateDeclInstantiator - : public DeclVisitor<TemplateDeclInstantiator, Decl *> - { - Sema &SemaRef; - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; - DeclContext *Owner; - const MultiLevelTemplateArgumentList &TemplateArgs; - Sema::LateInstantiatedAttrVec* LateAttrs; - LocalInstantiationScope *StartingScope; - - /// \brief A list of out-of-line class template partial - /// specializations that will need to be instantiated after the - /// enclosing class's instantiation is complete. - SmallVector<std::pair<ClassTemplateDecl *, - ClassTemplatePartialSpecializationDecl *>, 4> - OutOfLinePartialSpecs; - - /// \brief A list of out-of-line variable template partial - /// specializations that will need to be instantiated after the - /// enclosing variable's instantiation is complete. - /// FIXME: Verify that this is needed. - SmallVector< - std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> - OutOfLineVarPartialSpecs; - - public: - TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, - const MultiLevelTemplateArgumentList &TemplateArgs) - : SemaRef(SemaRef), - SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), - Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr), - StartingScope(nullptr) {} - -// Define all the decl visitors using DeclNodes.inc -#define DECL(DERIVED, BASE) \ - Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); -#define ABSTRACT_DECL(DECL) - -// Decls which never appear inside a class or function. -#define OBJCCONTAINER(DERIVED, BASE) -#define FILESCOPEASM(DERIVED, BASE) -#define IMPORT(DERIVED, BASE) -#define LINKAGESPEC(DERIVED, BASE) -#define OBJCCOMPATIBLEALIAS(DERIVED, BASE) -#define OBJCMETHOD(DERIVED, BASE) -#define OBJCTYPEPARAM(DERIVED, BASE) -#define OBJCIVAR(DERIVED, BASE) -#define OBJCPROPERTY(DERIVED, BASE) -#define OBJCPROPERTYIMPL(DERIVED, BASE) -#define EMPTY(DERIVED, BASE) - -// Decls which use special-case instantiation code. -#define BLOCK(DERIVED, BASE) -#define CAPTURED(DERIVED, BASE) -#define IMPLICITPARAM(DERIVED, BASE) - -#include "clang/AST/DeclNodes.inc" - - // A few supplemental visitor functions. - Decl *VisitCXXMethodDecl(CXXMethodDecl *D, - TemplateParameterList *TemplateParams, - bool IsClassScopeSpecialization = false); - Decl *VisitFunctionDecl(FunctionDecl *D, - TemplateParameterList *TemplateParams); - Decl *VisitDecl(Decl *D); - Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate); - - // Enable late instantiation of attributes. Late instantiated attributes - // will be stored in LA. - void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { - LateAttrs = LA; - StartingScope = SemaRef.CurrentInstantiationScope; - } - - // Disable late instantiation of attributes. - void disableLateAttributeInstantiation() { - LateAttrs = nullptr; - StartingScope = nullptr; - } - - LocalInstantiationScope *getStartingScope() const { return StartingScope; } - - typedef - SmallVectorImpl<std::pair<ClassTemplateDecl *, - ClassTemplatePartialSpecializationDecl *> > - ::iterator - delayed_partial_spec_iterator; - - typedef SmallVectorImpl<std::pair< - VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> >::iterator - delayed_var_partial_spec_iterator; - - /// \brief Return an iterator to the beginning of the set of - /// "delayed" partial specializations, which must be passed to - /// InstantiateClassTemplatePartialSpecialization once the class - /// definition has been completed. - delayed_partial_spec_iterator delayed_partial_spec_begin() { - return OutOfLinePartialSpecs.begin(); - } - - delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { - return OutOfLineVarPartialSpecs.begin(); - } - - /// \brief Return an iterator to the end of the set of - /// "delayed" partial specializations, which must be passed to - /// InstantiateClassTemplatePartialSpecialization once the class - /// definition has been completed. - delayed_partial_spec_iterator delayed_partial_spec_end() { - return OutOfLinePartialSpecs.end(); - } - - delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { - return OutOfLineVarPartialSpecs.end(); - } - - // Helper functions for instantiating methods. - TypeSourceInfo *SubstFunctionType(FunctionDecl *D, - SmallVectorImpl<ParmVarDecl *> &Params); - bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); - bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); - - TemplateParameterList * - SubstTemplateParams(TemplateParameterList *List); - - bool SubstQualifier(const DeclaratorDecl *OldDecl, - DeclaratorDecl *NewDecl); - bool SubstQualifier(const TagDecl *OldDecl, - TagDecl *NewDecl); - - Decl *VisitVarTemplateSpecializationDecl( - VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos, - const TemplateArgumentListInfo &TemplateArgsInfo, - ArrayRef<TemplateArgument> Converted); - - Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); - ClassTemplatePartialSpecializationDecl * - InstantiateClassTemplatePartialSpecialization( - ClassTemplateDecl *ClassTemplate, - ClassTemplatePartialSpecializationDecl *PartialSpec); - VarTemplatePartialSpecializationDecl * - InstantiateVarTemplatePartialSpecialization( - VarTemplateDecl *VarTemplate, - VarTemplatePartialSpecializationDecl *PartialSpec); - void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); - }; -} - -#endif // LLVM_CLANG_SEMA_TEMPLATE_H diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h deleted file mode 100644 index c22c703..0000000 --- a/include/clang/Sema/TemplateDeduction.h +++ /dev/null @@ -1,315 +0,0 @@ -//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/ -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -//===----------------------------------------------------------------------===/ -// -// This file provides types used with Sema's template argument deduction -// routines. -// -//===----------------------------------------------------------------------===/ -#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H -#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H - -#include "clang/AST/DeclTemplate.h" -#include "clang/Basic/PartialDiagnostic.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -struct DeducedPack; -class TemplateArgumentList; -class Sema; - -namespace sema { - -/// \brief Provides information about an attempted template argument -/// deduction, whose success or failure was described by a -/// TemplateDeductionResult value. -class TemplateDeductionInfo { - /// \brief The deduced template argument list. - /// - TemplateArgumentList *Deduced; - - /// \brief The source location at which template argument - /// deduction is occurring. - SourceLocation Loc; - - /// \brief Have we suppressed an error during deduction? - bool HasSFINAEDiagnostic; - - /// \brief Warnings (and follow-on notes) that were suppressed due to - /// SFINAE while performing template argument deduction. - SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; - - TemplateDeductionInfo(const TemplateDeductionInfo &) = delete; - void operator=(const TemplateDeductionInfo &) = delete; - -public: - TemplateDeductionInfo(SourceLocation Loc) - : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false), - Expression(nullptr) {} - - /// \brief Returns the location at which template argument is - /// occurring. - SourceLocation getLocation() const { - return Loc; - } - - /// \brief Take ownership of the deduced template argument list. - TemplateArgumentList *take() { - TemplateArgumentList *Result = Deduced; - Deduced = nullptr; - return Result; - } - - /// \brief Take ownership of the SFINAE diagnostic. - void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { - assert(HasSFINAEDiagnostic); - PD.first = SuppressedDiagnostics.front().first; - PD.second.swap(SuppressedDiagnostics.front().second); - SuppressedDiagnostics.clear(); - HasSFINAEDiagnostic = false; - } - - /// \brief Provide a new template argument list that contains the - /// results of template argument deduction. - void reset(TemplateArgumentList *NewDeduced) { - Deduced = NewDeduced; - } - - /// \brief Is a SFINAE diagnostic available? - bool hasSFINAEDiagnostic() const { - return HasSFINAEDiagnostic; - } - - /// \brief Set the diagnostic which caused the SFINAE failure. - void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { - // Only collect the first diagnostic. - if (HasSFINAEDiagnostic) - return; - SuppressedDiagnostics.clear(); - SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); - HasSFINAEDiagnostic = true; - } - - /// \brief Add a new diagnostic to the set of diagnostics - void addSuppressedDiagnostic(SourceLocation Loc, - PartialDiagnostic PD) { - if (HasSFINAEDiagnostic) - return; - SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); - } - - /// \brief Iterator over the set of suppressed diagnostics. - typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator - diag_iterator; - - /// \brief Returns an iterator at the beginning of the sequence of suppressed - /// diagnostics. - diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } - - /// \brief Returns an iterator at the end of the sequence of suppressed - /// diagnostics. - diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } - - /// \brief The template parameter to which a template argument - /// deduction failure refers. - /// - /// Depending on the result of template argument deduction, this - /// template parameter may have different meanings: - /// - /// TDK_Incomplete: this is the first template parameter whose - /// corresponding template argument was not deduced. - /// - /// TDK_Inconsistent: this is the template parameter for which - /// two different template argument values were deduced. - TemplateParameter Param; - - /// \brief The first template argument to which the template - /// argument deduction failure refers. - /// - /// Depending on the result of the template argument deduction, - /// this template argument may have different meanings: - /// - /// TDK_Inconsistent: this argument is the first value deduced - /// for the corresponding template parameter. - /// - /// TDK_SubstitutionFailure: this argument is the template - /// argument we were instantiating when we encountered an error. - /// - /// TDK_DeducedMismatch: this is the parameter type, after substituting - /// deduced arguments. - /// - /// TDK_NonDeducedMismatch: this is the component of the 'parameter' - /// of the deduction, directly provided in the source code. - TemplateArgument FirstArg; - - /// \brief The second template argument to which the template - /// argument deduction failure refers. - /// - /// TDK_Inconsistent: this argument is the second value deduced - /// for the corresponding template parameter. - /// - /// TDK_DeducedMismatch: this is the (adjusted) call argument type. - /// - /// TDK_NonDeducedMismatch: this is the mismatching component of the - /// 'argument' of the deduction, from which we are deducing arguments. - /// - /// FIXME: Finish documenting this. - TemplateArgument SecondArg; - - union { - /// \brief The expression which caused a deduction failure. - /// - /// TDK_FailedOverloadResolution: this argument is the reference to - /// an overloaded function which could not be resolved to a specific - /// function. - Expr *Expression; - - /// \brief The index of the function argument that caused a deduction - /// failure. - /// - /// TDK_DeducedMismatch: this is the index of the argument that had a - /// different argument type from its substituted parameter type. - unsigned CallArgIndex; - }; - - /// \brief Information on packs that we're currently expanding. - /// - /// FIXME: This should be kept internal to SemaTemplateDeduction. - SmallVector<DeducedPack *, 8> PendingDeducedPacks; -}; - -} // end namespace sema - -/// A structure used to record information about a failed -/// template argument deduction, for diagnosis. -struct DeductionFailureInfo { - /// A Sema::TemplateDeductionResult. - unsigned Result : 8; - - /// \brief Indicates whether a diagnostic is stored in Diagnostic. - unsigned HasDiagnostic : 1; - - /// \brief Opaque pointer containing additional data about - /// this deduction failure. - void *Data; - - /// \brief A diagnostic indicating why deduction failed. - union { - void *Align; - char Diagnostic[sizeof(PartialDiagnosticAt)]; - }; - - /// \brief Retrieve the diagnostic which caused this deduction failure, - /// if any. - PartialDiagnosticAt *getSFINAEDiagnostic(); - - /// \brief Retrieve the template parameter this deduction failure - /// refers to, if any. - TemplateParameter getTemplateParameter(); - - /// \brief Retrieve the template argument list associated with this - /// deduction failure, if any. - TemplateArgumentList *getTemplateArgumentList(); - - /// \brief Return the first template argument this deduction failure - /// refers to, if any. - const TemplateArgument *getFirstArg(); - - /// \brief Return the second template argument this deduction failure - /// refers to, if any. - const TemplateArgument *getSecondArg(); - - /// \brief Return the expression this deduction failure refers to, - /// if any. - Expr *getExpr(); - - /// \brief Return the index of the call argument that this deduction - /// failure refers to, if any. - llvm::Optional<unsigned> getCallArgIndex(); - - /// \brief Free any memory associated with this deduction failure. - void Destroy(); -}; - -/// TemplateSpecCandidate - This is a generalization of OverloadCandidate -/// which keeps track of template argument deduction failure info, when -/// handling explicit specializations (and instantiations) of templates -/// beyond function overloading. -/// For now, assume that the candidates are non-matching specializations. -/// TODO: In the future, we may need to unify/generalize this with -/// OverloadCandidate. -struct TemplateSpecCandidate { - /// Specialization - The actual specialization that this candidate - /// represents. When NULL, this may be a built-in candidate. - Decl *Specialization; - - /// Template argument deduction info - DeductionFailureInfo DeductionFailure; - - void set(Decl *Spec, DeductionFailureInfo Info) { - Specialization = Spec; - DeductionFailure = Info; - } - - /// Diagnose a template argument deduction failure. - void NoteDeductionFailure(Sema &S, bool ForTakingAddress); -}; - -/// TemplateSpecCandidateSet - A set of generalized overload candidates, -/// used in template specializations. -/// TODO: In the future, we may need to unify/generalize this with -/// OverloadCandidateSet. -class TemplateSpecCandidateSet { - SmallVector<TemplateSpecCandidate, 16> Candidates; - SourceLocation Loc; - // Stores whether we're taking the address of these candidates. This helps us - // produce better error messages when dealing with the pass_object_size - // attribute on parameters. - bool ForTakingAddress; - - TemplateSpecCandidateSet( - const TemplateSpecCandidateSet &) = delete; - void operator=(const TemplateSpecCandidateSet &) = delete; - - void destroyCandidates(); - -public: - TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false) - : Loc(Loc), ForTakingAddress(ForTakingAddress) {} - ~TemplateSpecCandidateSet() { destroyCandidates(); } - - SourceLocation getLocation() const { return Loc; } - - /// \brief Clear out all of the candidates. - /// TODO: This may be unnecessary. - void clear(); - - typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator; - iterator begin() { return Candidates.begin(); } - iterator end() { return Candidates.end(); } - - size_t size() const { return Candidates.size(); } - bool empty() const { return Candidates.empty(); } - - /// \brief Add a new candidate with NumConversions conversion sequence slots - /// to the overload set. - TemplateSpecCandidate &addCandidate() { - Candidates.emplace_back(); - return Candidates.back(); - } - - void NoteCandidates(Sema &S, SourceLocation Loc); - - void NoteCandidates(Sema &S, SourceLocation Loc) const { - const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc); - } -}; - -} // end namespace clang - -#endif diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h deleted file mode 100644 index 3b0385e..0000000 --- a/include/clang/Sema/TypoCorrection.h +++ /dev/null @@ -1,366 +0,0 @@ -//===--- TypoCorrection.h - Class for typo correction results ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TypoCorrection class, which stores the results of -// Sema's typo correction (Sema::CorrectTypo). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_TYPOCORRECTION_H -#define LLVM_CLANG_SEMA_TYPOCORRECTION_H - -#include "clang/AST/DeclCXX.h" -#include "clang/Sema/DeclSpec.h" -#include "clang/Sema/Ownership.h" -#include "llvm/ADT/SmallVector.h" - -namespace clang { - -/// @brief Simple class containing the result of Sema::CorrectTypo -class TypoCorrection { -public: - // "Distance" for unusable corrections - static const unsigned InvalidDistance = ~0U; - // The largest distance still considered valid (larger edit distances are - // mapped to InvalidDistance by getEditDistance). - static const unsigned MaximumDistance = 10000U; - - // Relative weightings of the "edit distance" components. The higher the - // weight, the more of a penalty to fitness the component will give (higher - // weights mean greater contribution to the total edit distance, with the - // best correction candidates having the lowest edit distance). - static const unsigned CharDistanceWeight = 100U; - static const unsigned QualifierDistanceWeight = 110U; - static const unsigned CallbackDistanceWeight = 150U; - - TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, - NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0, - unsigned QualifierDistance = 0) - : CorrectionName(Name), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(QualifierDistance), - CallbackDistance(0), ForceSpecifierReplacement(false), - RequiresImport(false) { - if (NameDecl) - CorrectionDecls.push_back(NameDecl); - } - - TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr, - unsigned CharDistance = 0) - : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0), - ForceSpecifierReplacement(false), RequiresImport(false) { - if (Name) - CorrectionDecls.push_back(Name); - } - - TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr, - unsigned CharDistance = 0) - : CorrectionName(Name), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0), - ForceSpecifierReplacement(false), RequiresImport(false) {} - - TypoCorrection() - : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0), - CallbackDistance(0), ForceSpecifierReplacement(false), - RequiresImport(false) {} - - /// \brief Gets the DeclarationName of the typo correction - DeclarationName getCorrection() const { return CorrectionName; } - IdentifierInfo *getCorrectionAsIdentifierInfo() const { - return CorrectionName.getAsIdentifierInfo(); - } - - /// \brief Gets the NestedNameSpecifier needed to use the typo correction - NestedNameSpecifier *getCorrectionSpecifier() const { - return CorrectionNameSpec; - } - void setCorrectionSpecifier(NestedNameSpecifier *NNS) { - CorrectionNameSpec = NNS; - ForceSpecifierReplacement = (NNS != nullptr); - } - - void WillReplaceSpecifier(bool ForceReplacement) { - ForceSpecifierReplacement = ForceReplacement; - } - - bool WillReplaceSpecifier() const { - return ForceSpecifierReplacement; - } - - void setQualifierDistance(unsigned ED) { - QualifierDistance = ED; - } - - void setCallbackDistance(unsigned ED) { - CallbackDistance = ED; - } - - // Convert the given weighted edit distance to a roughly equivalent number of - // single-character edits (typically for comparison to the length of the - // string being edited). - static unsigned NormalizeEditDistance(unsigned ED) { - if (ED > MaximumDistance) - return InvalidDistance; - return (ED + CharDistanceWeight / 2) / CharDistanceWeight; - } - - /// \brief Gets the "edit distance" of the typo correction from the typo. - /// If Normalized is true, scale the distance down by the CharDistanceWeight - /// to return the edit distance in terms of single-character edits. - unsigned getEditDistance(bool Normalized = true) const { - if (CharDistance > MaximumDistance || QualifierDistance > MaximumDistance || - CallbackDistance > MaximumDistance) - return InvalidDistance; - unsigned ED = - CharDistance * CharDistanceWeight + - QualifierDistance * QualifierDistanceWeight + - CallbackDistance * CallbackDistanceWeight; - if (ED > MaximumDistance) - return InvalidDistance; - // Half the CharDistanceWeight is added to ED to simulate rounding since - // integer division truncates the value (i.e. round-to-nearest-int instead - // of round-to-zero). - return Normalized ? NormalizeEditDistance(ED) : ED; - } - - /// \brief Get the correction declaration found by name lookup (before we - /// looked through using shadow declarations and the like). - NamedDecl *getFoundDecl() const { - return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr; - } - - /// \brief Gets the pointer to the declaration of the typo correction - NamedDecl *getCorrectionDecl() const { - auto *D = getFoundDecl(); - return D ? D->getUnderlyingDecl() : nullptr; - } - template <class DeclClass> - DeclClass *getCorrectionDeclAs() const { - return dyn_cast_or_null<DeclClass>(getCorrectionDecl()); - } - - /// \brief Clears the list of NamedDecls. - void ClearCorrectionDecls() { - CorrectionDecls.clear(); - } - - /// \brief Clears the list of NamedDecls before adding the new one. - void setCorrectionDecl(NamedDecl *CDecl) { - CorrectionDecls.clear(); - addCorrectionDecl(CDecl); - } - - /// \brief Clears the list of NamedDecls and adds the given set. - void setCorrectionDecls(ArrayRef<NamedDecl*> Decls) { - CorrectionDecls.clear(); - CorrectionDecls.insert(CorrectionDecls.begin(), Decls.begin(), Decls.end()); - } - - /// \brief Add the given NamedDecl to the list of NamedDecls that are the - /// declarations associated with the DeclarationName of this TypoCorrection - void addCorrectionDecl(NamedDecl *CDecl); - - std::string getAsString(const LangOptions &LO) const; - std::string getQuoted(const LangOptions &LO) const { - return "'" + getAsString(LO) + "'"; - } - - /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName - explicit operator bool() const { return bool(CorrectionName); } - - /// \brief Mark this TypoCorrection as being a keyword. - /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be - /// added to the list of the correction's NamedDecl pointers, NULL is added - /// as the only element in the list to mark this TypoCorrection as a keyword. - void makeKeyword() { - CorrectionDecls.clear(); - CorrectionDecls.push_back(nullptr); - ForceSpecifierReplacement = true; - } - - // Check if this TypoCorrection is a keyword by checking if the first - // item in CorrectionDecls is NULL. - bool isKeyword() const { - return !CorrectionDecls.empty() && CorrectionDecls.front() == nullptr; - } - - // Check if this TypoCorrection is the given keyword. - template<std::size_t StrLen> - bool isKeyword(const char (&Str)[StrLen]) const { - return isKeyword() && getCorrectionAsIdentifierInfo()->isStr(Str); - } - - // Returns true if the correction either is a keyword or has a known decl. - bool isResolved() const { return !CorrectionDecls.empty(); } - - bool isOverloaded() const { - return CorrectionDecls.size() > 1; - } - - void setCorrectionRange(CXXScopeSpec *SS, - const DeclarationNameInfo &TypoName) { - CorrectionRange = TypoName.getSourceRange(); - if (ForceSpecifierReplacement && SS && !SS->isEmpty()) - CorrectionRange.setBegin(SS->getBeginLoc()); - } - - SourceRange getCorrectionRange() const { - return CorrectionRange; - } - - typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator; - decl_iterator begin() { - return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); - } - decl_iterator end() { return CorrectionDecls.end(); } - typedef SmallVectorImpl<NamedDecl *>::const_iterator const_decl_iterator; - const_decl_iterator begin() const { - return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); - } - const_decl_iterator end() const { return CorrectionDecls.end(); } - - /// \brief Returns whether this typo correction is correcting to a - /// declaration that was declared in a module that has not been imported. - bool requiresImport() const { return RequiresImport; } - void setRequiresImport(bool Req) { RequiresImport = Req; } - -private: - bool hasCorrectionDecl() const { - return (!isKeyword() && !CorrectionDecls.empty()); - } - - // Results. - DeclarationName CorrectionName; - NestedNameSpecifier *CorrectionNameSpec; - SmallVector<NamedDecl *, 1> CorrectionDecls; - unsigned CharDistance; - unsigned QualifierDistance; - unsigned CallbackDistance; - SourceRange CorrectionRange; - bool ForceSpecifierReplacement; - bool RequiresImport; -}; - -/// @brief Base class for callback objects used by Sema::CorrectTypo to check -/// the validity of a potential typo correction. -class CorrectionCandidateCallback { -public: - static const unsigned InvalidDistance = TypoCorrection::InvalidDistance; - - explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr, - NestedNameSpecifier *TypoNNS = nullptr) - : WantTypeSpecifiers(true), WantExpressionKeywords(true), - WantCXXNamedCasts(true), WantFunctionLikeCasts(true), - WantRemainingKeywords(true), WantObjCSuper(false), - IsObjCIvarLookup(false), IsAddressOfOperand(false), Typo(Typo), - TypoNNS(TypoNNS) {} - - virtual ~CorrectionCandidateCallback() {} - - /// \brief Simple predicate used by the default RankCandidate to - /// determine whether to return an edit distance of 0 or InvalidDistance. - /// This can be overrided by validators that only need to determine if a - /// candidate is viable, without ranking potentially viable candidates. - /// Only ValidateCandidate or RankCandidate need to be overriden by a - /// callback wishing to check the viability of correction candidates. - /// The default predicate always returns true if the candidate is not a type - /// name or keyword, true for types if WantTypeSpecifiers is true, and true - /// for keywords if WantTypeSpecifiers, WantExpressionKeywords, - /// WantCXXNamedCasts, WantRemainingKeywords, or WantObjCSuper is true. - virtual bool ValidateCandidate(const TypoCorrection &candidate); - - /// \brief Method used by Sema::CorrectTypo to assign an "edit distance" rank - /// to a candidate (where a lower value represents a better candidate), or - /// returning InvalidDistance if the candidate is not at all viable. For - /// validation callbacks that only need to determine if a candidate is viable, - /// the default RankCandidate returns either 0 or InvalidDistance depending - /// whether ValidateCandidate returns true or false. - virtual unsigned RankCandidate(const TypoCorrection &candidate) { - return (!MatchesTypo(candidate) && ValidateCandidate(candidate)) - ? 0 - : InvalidDistance; - } - - void setTypoName(IdentifierInfo *II) { Typo = II; } - void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; } - - // Flags for context-dependent keywords. WantFunctionLikeCasts is only - // used/meaningful when WantCXXNamedCasts is false. - // TODO: Expand these to apply to non-keywords or possibly remove them. - bool WantTypeSpecifiers; - bool WantExpressionKeywords; - bool WantCXXNamedCasts; - bool WantFunctionLikeCasts; - bool WantRemainingKeywords; - bool WantObjCSuper; - // Temporary hack for the one case where a CorrectTypoContext enum is used - // when looking up results. - bool IsObjCIvarLookup; - bool IsAddressOfOperand; - -protected: - bool MatchesTypo(const TypoCorrection &candidate) { - return Typo && candidate.isResolved() && !candidate.requiresImport() && - candidate.getCorrectionAsIdentifierInfo() == Typo && - // FIXME: This probably does not return true when both - // NestedNameSpecifiers have the same textual representation. - candidate.getCorrectionSpecifier() == TypoNNS; - } - - IdentifierInfo *Typo; - NestedNameSpecifier *TypoNNS; -}; - -/// @brief Simple template class for restricting typo correction candidates -/// to ones having a single Decl* of the given type. -template <class C> -class DeclFilterCCC : public CorrectionCandidateCallback { -public: - bool ValidateCandidate(const TypoCorrection &candidate) override { - return candidate.getCorrectionDeclAs<C>(); - } -}; - -// @brief Callback class to limit the allowed keywords and to only accept typo -// corrections that are keywords or whose decls refer to functions (or template -// functions) that accept the given number of arguments. -class FunctionCallFilterCCC : public CorrectionCandidateCallback { -public: - FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs, - bool HasExplicitTemplateArgs, - MemberExpr *ME = nullptr); - - bool ValidateCandidate(const TypoCorrection &candidate) override; - - private: - unsigned NumArgs; - bool HasExplicitTemplateArgs; - DeclContext *CurContext; - MemberExpr *MemberFn; -}; - -// @brief Callback class that effectively disabled typo correction -class NoTypoCorrectionCCC : public CorrectionCandidateCallback { -public: - NoTypoCorrectionCCC() { - WantTypeSpecifiers = false; - WantExpressionKeywords = false; - WantCXXNamedCasts = false; - WantFunctionLikeCasts = false; - WantRemainingKeywords = false; - } - - bool ValidateCandidate(const TypoCorrection &candidate) override { - return false; - } -}; - -} - -#endif diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h deleted file mode 100644 index 9c7212e..0000000 --- a/include/clang/Sema/Weak.h +++ /dev/null @@ -1,46 +0,0 @@ -//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the WeakInfo class, which is used to store -// information about the target of a #pragma weak directive. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_SEMA_WEAK_H -#define LLVM_CLANG_SEMA_WEAK_H - -#include "clang/Basic/SourceLocation.h" - -namespace clang { - -class IdentifierInfo; - -/// \brief Captures information about a \#pragma weak directive. -class WeakInfo { - IdentifierInfo *alias; // alias (optional) - SourceLocation loc; // for diagnostics - bool used; // identifier later declared? -public: - WeakInfo() - : alias(nullptr), loc(SourceLocation()), used(false) {} - WeakInfo(IdentifierInfo *Alias, SourceLocation Loc) - : alias(Alias), loc(Loc), used(false) {} - inline IdentifierInfo * getAlias() const { return alias; } - inline SourceLocation getLocation() const { return loc; } - void setUsed(bool Used=true) { used = Used; } - inline bool getUsed() { return used; } - bool operator==(WeakInfo RHS) const { - return alias == RHS.getAlias() && loc == RHS.getLocation(); - } - bool operator!=(WeakInfo RHS) const { return !(*this == RHS); } -}; - -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_WEAK_H |