diff options
Diffstat (limited to 'include/clang/Sema')
23 files changed, 1817 insertions, 706 deletions
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h index eeac973..432c4e2 100644 --- a/include/clang/Sema/AnalysisBasedWarnings.h +++ b/include/clang/Sema/AnalysisBasedWarnings.h @@ -38,6 +38,7 @@ public: unsigned enableCheckFallThrough : 1; unsigned enableCheckUnreachable : 1; unsigned enableThreadSafetyAnalysis : 1; + unsigned enableConsumedAnalysis : 1; public: Policy(); void disableCheckFallThrough() { enableCheckFallThrough = 0; } diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index d5f3177..508064d 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -19,6 +19,7 @@ #include "clang/Basic/VersionTuple.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Allocator.h" #include <cassert> @@ -44,6 +45,20 @@ struct AvailabilityChange { 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: @@ -66,13 +81,12 @@ public: /// __ptr16, alignas(...), etc. AS_Keyword }; + private: IdentifierInfo *AttrName; IdentifierInfo *ScopeName; - IdentifierInfo *ParmName; SourceRange AttrRange; SourceLocation ScopeLoc; - SourceLocation ParmLoc; SourceLocation EllipsisLoc; /// The number of expression arguments this attribute has. @@ -100,6 +114,9 @@ private: /// 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 @@ -114,22 +131,27 @@ private: /// The next attribute allocated in the current Pool. AttributeList *NextInPool; - Expr **getArgsBuffer() { - return reinterpret_cast<Expr**>(this+1); + /// Arguments, if any, are stored immediately following the object. + ArgsUnion *getArgsBuffer() { + return reinterpret_cast<ArgsUnion*>(this+1); } - Expr * const *getArgsBuffer() const { - return reinterpret_cast<Expr* const *>(this+1); + ArgsUnion const *getArgsBuffer() const { + return reinterpret_cast<ArgsUnion const *>(this+1); } enum AvailabilitySlot { IntroducedSlot, DeprecatedSlot, ObsoletedSlot }; - AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { - return reinterpret_cast<AvailabilityChange*>(this+1)[index]; + /// 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*>(this+1)[index]; + return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() + + NumArgs)[index]; } public: @@ -145,14 +167,20 @@ public: }; 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 *>(this + 1); + return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs); } const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { - return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1); + 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); } @@ -161,6 +189,8 @@ private: 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); @@ -181,36 +211,34 @@ private: /// Constructor for attributes with expression arguments. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed, SourceLocation ellipsisLoc) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), - NextInPool(0) { - if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); + : 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(0), NextInPool(0) { + 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, - IdentifierInfo *parmName, SourceLocation parmLoc, - const AvailabilityChange &introduced, + IdentifierLoc *Parm, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(), - NumArgs(0), SyntaxUsed(syntaxUsed), + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), - IsTypeTagForDatatype(false), IsProperty(false), + IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), UnavailableLoc(unavailable), MessageExpr(messageExpr), NextInPosition(0), NextInPool(0) { + ArgsUnion PVal(Parm); + memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); @@ -220,16 +248,15 @@ private: /// Constructor for type_tag_for_datatype attribute. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc), - EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), + 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), NextInPosition(NULL), - NextInPool(NULL) { + IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), + NextInPosition(NULL), NextInPool(NULL) { + ArgsUnion PVal(ArgKind); + memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); new (&ExtraData.MatchingCType) ParsedType(matchingCType); ExtraData.LayoutCompatible = layoutCompatible; @@ -240,14 +267,12 @@ private: /// Constructor for attributes with a single type argument. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, ParsedType typeArg, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), - UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), - NextInPool(0) { + : 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(0), NextInPool(0) { new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -255,15 +280,13 @@ private: /// Constructor for microsoft __declspec(property) attribute. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - SyntaxUsed(syntaxUsed), + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0), - NextInPool(0) { + IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), + NextInPosition(0), NextInPool(0) { new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -288,8 +311,7 @@ public: IdentifierInfo *getScopeName() const { return ScopeName; } SourceLocation getScopeLoc() const { return ScopeLoc; } - IdentifierInfo *getParameterName() const { return ParmName; } - SourceLocation getParameterLoc() const { return ParmLoc; } + bool hasParsedType() const { return HasParsedType; } /// Is this the Microsoft __declspec(property) attribute? bool isDeclspecPropertyAttribute() const { @@ -326,21 +348,31 @@ public: /// getNumArgs - Return the number of actual arguments to this attribute. unsigned getNumArgs() const { return NumArgs; } - /// hasParameterOrArguments - Return true if this attribute has a parameter, - /// or has a non empty argument expression list. - bool hasParameterOrArguments() const { return ParmName || NumArgs; } - /// getArg - Return the specified argument. - Expr *getArg(unsigned Arg) const { + 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*>(); + } + class arg_iterator { - Expr * const *X; + ArgsUnion const *X; unsigned Idx; public: - arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {} + arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {} arg_iterator& operator++() { ++Idx; @@ -357,7 +389,7 @@ public: return !operator==(I); } - Expr* operator*() const { + ArgsUnion operator*() const { return X[Idx]; } @@ -418,7 +450,7 @@ public: } const ParsedType &getTypeArg() const { - assert(getKind() == AT_VecTypeHint && "Not a type attribute"); + assert(HasParsedType && "Not a type attribute"); return getTypeBuffer(); } @@ -431,6 +463,10 @@ public: /// defined in Attr.td. This index is used by an attribute /// to pretty print itself. unsigned getAttributeSpellingListIndex() const; + + bool hasCustomParsing() const; + unsigned getMinArgs() const; + unsigned getMaxArgs() const; }; /// A factory, from which one makes pools, from which one creates @@ -445,11 +481,13 @@ public: /// which we want to ensure is a multiple of sizeof(void*). AvailabilityAllocSize = sizeof(AttributeList) - + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1) + + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*)), TypeTagForDatatypeAllocSize = sizeof(AttributeList) - + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1) + + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) + + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*), PropertyAllocSize = sizeof(AttributeList) @@ -541,22 +579,20 @@ public: AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc = SourceLocation()) { void *memory = allocate(sizeof(AttributeList) - + numArgs * sizeof(Expr*)); + + numArgs * sizeof(ArgsUnion)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, args, numArgs, syntax, ellipsisLoc)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, @@ -566,9 +602,9 @@ public: void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, - introduced, deprecated, obsoleted, - unavailable, MessageExpr, syntax)); + Param, introduced, deprecated, + obsoleted, unavailable, MessageExpr, + syntax)); } AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, @@ -577,40 +613,35 @@ public: AttributeList *createTypeTagForDatatype( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, AttributeList::Syntax syntax) { + 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, - argumentKindName, argumentKindLoc, - matchingCType, layoutCompatible, - mustBeNull, syntax)); + argumentKind, matchingCType, + layoutCompatible, mustBeNull, + syntax)); } AttributeList *createTypeAttribute( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed) { void *memory = allocate(sizeof(AttributeList) + sizeof(void *)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, typeArg, syntaxUsed)); } AttributeList *createPropertyAttribute( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed) { void *memory = allocate(AttributeFactory::PropertyAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, getterId, setterId, syntaxUsed)); } @@ -709,13 +740,12 @@ public: /// Add attribute with expression arguments. AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc = SourceLocation()) { AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, syntax, ellipsisLoc); + pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs, + syntax, ellipsisLoc); add(attr); return attr; } @@ -723,7 +753,7 @@ public: /// Add availability attribute. AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, @@ -731,9 +761,8 @@ public: const Expr *MessageExpr, AttributeList::Syntax syntax) { AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - introduced, deprecated, obsoleted, unavailable, - MessageExpr, syntax); + pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, + deprecated, obsoleted, unavailable, MessageExpr, syntax); add(attr); return attr; } @@ -742,16 +771,14 @@ public: AttributeList *addNewTypeTagForDatatype( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, AttributeList::Syntax syntax) { + IdentifierLoc *argumentKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, + AttributeList::Syntax syntax) { AttributeList *attr = pool.createTypeTagForDatatype(attrName, attrRange, scopeName, scopeLoc, - argumentKindName, argumentKindLoc, - matchingCType, layoutCompatible, - mustBeNull, syntax); + argumentKind, matchingCType, + layoutCompatible, mustBeNull, syntax); add(attr); return attr; } @@ -760,11 +787,10 @@ public: AttributeList * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed) { AttributeList *attr = pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, typeArg, syntaxUsed); + typeArg, syntaxUsed); add(attr); return attr; } @@ -773,13 +799,11 @@ public: AttributeList * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed) { AttributeList *attr = pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, getterId, setterId, - syntaxUsed); + getterId, setterId, syntaxUsed); add(attr); return attr; } @@ -798,6 +822,15 @@ private: 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 +}; + } // end namespace clang #endif diff --git a/include/clang/Sema/CMakeLists.txt b/include/clang/Sema/CMakeLists.txt index 6b5d222..5a48b90 100644 --- a/include/clang/Sema/CMakeLists.txt +++ b/include/clang/Sema/CMakeLists.txt @@ -17,3 +17,8 @@ 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/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index a1ddec7..64de82c 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -271,22 +271,17 @@ private: QualType BaseType; /// \brief The identifiers for Objective-C selector parts. - IdentifierInfo **SelIdents; - - /// \brief The number of Objective-C selector parts. - unsigned NumSelIdents; + ArrayRef<IdentifierInfo *> SelIdents; public: /// \brief Construct a new code-completion context of the given kind. - CodeCompletionContext(enum Kind Kind) : Kind(Kind), SelIdents(NULL), - NumSelIdents(0) { } + 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, - IdentifierInfo **SelIdents = NULL, - unsigned NumSelIdents = 0) : Kind(Kind), - SelIdents(SelIdents), - NumSelIdents(NumSelIdents) { + ArrayRef<IdentifierInfo *> SelIdents = None) + : Kind(Kind), + SelIdents(SelIdents) { if (Kind == CCC_DotMemberAccess || Kind == CCC_ArrowMemberAccess || Kind == CCC_ObjCPropertyAccess || Kind == CCC_ObjCClassMessage || Kind == CCC_ObjCInstanceMessage) @@ -308,10 +303,7 @@ public: QualType getBaseType() const { return BaseType; } /// \brief Retrieve the Objective-C selector identifiers. - IdentifierInfo **getSelIdents() const { return SelIdents; } - - /// \brief Retrieve the number of Objective-C selector identifiers. - unsigned getNumSelIdents() const { return NumSelIdents; } + ArrayRef<IdentifierInfo *> getSelIdents() const { return SelIdents; } /// \brief Determines whether we want C++ constructors as results within this /// context. diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 059919a..8f6bd18 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -337,6 +337,7 @@ private: // 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; @@ -381,6 +382,7 @@ private: 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; WrittenBuiltinSpecs writtenBS; @@ -419,6 +421,7 @@ public: 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), @@ -458,6 +461,12 @@ public: 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; } @@ -504,6 +513,8 @@ public: return TypeSpecType == TST_auto || 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); static const char *getSpecifierName(DeclSpec::TQ Q); @@ -532,8 +543,12 @@ public: } // function-specifier - bool isInlineSpecified() const { return FS_inline_specified; } - SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; } + 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; } @@ -547,6 +562,8 @@ public: 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; @@ -615,6 +632,8 @@ public: const char *&PrevSpec, unsigned &DiagID); bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); + bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecError(); void UpdateDeclRep(Decl *Rep) { assert(isDeclRep((TST) TypeSpecType)); @@ -632,10 +651,16 @@ public: bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const LangOptions &Lang); - bool setFunctionSpecInline(SourceLocation Loc); - bool setFunctionSpecVirtual(SourceLocation Loc); - bool setFunctionSpecExplicit(SourceLocation Loc); - bool setFunctionSpecNoreturn(SourceLocation Loc); + 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); @@ -1500,6 +1525,7 @@ public: 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. @@ -1575,7 +1601,6 @@ public: ~Declarator() { clear(); } - /// getDeclSpec - Return the declaration-specifier that this declarator was /// declared with. const DeclSpec &getDeclSpec() const { return DS; } @@ -1604,7 +1629,8 @@ public: bool isPrototypeContext() const { return (Context == PrototypeContext || Context == ObjCParameterContext || - Context == ObjCResultContext); + Context == ObjCResultContext || + Context == LambdaExprParameterContext); } /// \brief Get the source range that spans this declarator. @@ -1668,6 +1694,7 @@ public: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: + case LambdaExprParameterContext: case ObjCParameterContext: case ObjCResultContext: case TemplateParamContext: @@ -1696,6 +1723,7 @@ public: case ForContext: case ConditionContext: case PrototypeContext: + case LambdaExprParameterContext: case TemplateParamContext: case CXXCatchContext: case ObjCCatchContext: @@ -1717,6 +1745,39 @@ public: 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 { @@ -1748,6 +1809,7 @@ public: case KNRTypeListContext: case MemberContext: case PrototypeContext: + case LambdaExprParameterContext: case ObjCParameterContext: case ObjCResultContext: case TemplateParamContext: @@ -1934,6 +1996,7 @@ public: case AliasDeclContext: case AliasTemplateContext: case PrototypeContext: + case LambdaExprParameterContext: case ObjCParameterContext: case ObjCResultContext: case TemplateParamContext: @@ -1995,7 +2058,7 @@ public: /// \brief Return a source range list of C++11 attributes associated /// with the declarator. - void getCXX11AttributeRanges(SmallVector<SourceRange, 4> &Ranges) { + void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { AttributeList *AttrList = Attrs.getList(); while (AttrList) { if (AttrList->isCXX11Attribute()) @@ -2038,6 +2101,16 @@ public: 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(); + void setRedeclaration(bool Val) { Redeclaration = Val; } bool isRedeclaration() const { return Redeclaration; } }; @@ -2057,7 +2130,8 @@ public: enum Specifier { VS_None = 0, VS_Override = 1, - VS_Final = 2 + VS_Final = 2, + VS_Sealed = 4 }; VirtSpecifiers() : Specifiers(0) { } @@ -2068,7 +2142,8 @@ public: bool isOverrideSpecified() const { return Specifiers & VS_Override; } SourceLocation getOverrideLoc() const { return VS_overrideLoc; } - bool isFinalSpecified() const { return Specifiers & VS_Final; } + 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; } @@ -2088,13 +2163,16 @@ private: struct LambdaCapture { LambdaCaptureKind Kind; SourceLocation Loc; - IdentifierInfo* Id; + IdentifierInfo *Id; SourceLocation EllipsisLoc; - + ExprResult Init; + ParsedType InitCaptureType; LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, - IdentifierInfo* Id = 0, - SourceLocation EllipsisLoc = SourceLocation()) - : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc) + IdentifierInfo* Id, + SourceLocation EllipsisLoc, + ExprResult Init, ParsedType InitCaptureType) + : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init), + InitCaptureType(InitCaptureType) {} }; @@ -2111,11 +2189,13 @@ struct LambdaIntroducer { /// \brief Append a capture in a lambda introducer. void addCapture(LambdaCaptureKind Kind, SourceLocation Loc, - IdentifierInfo* Id = 0, - SourceLocation EllipsisLoc = SourceLocation()) { - Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc)); + IdentifierInfo* Id, + SourceLocation EllipsisLoc, + ExprResult Init, + ParsedType InitCaptureType) { + Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init, + InitCaptureType)); } - }; } // end namespace clang diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 3704e09..4f4a87f 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -6,16 +6,17 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the DelayedDiagnostic class, which 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. -// -// This file also defines AccessedEntity. -// +/// +/// \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_DELAYED_DIAGNOSTIC_H @@ -224,8 +225,7 @@ private: }; }; -/// DelayedDiagnosticPool - A collection of diagnostics which were -/// delayed. +/// \brief A collection of diagnostics which were delayed. class DelayedDiagnosticPool { const DelayedDiagnosticPool *Parent; SmallVector<DelayedDiagnostic, 4> Diagnostics; diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index cbce757..325abdf 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -14,6 +14,8 @@ #define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_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> @@ -30,7 +32,8 @@ 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 { @@ -177,6 +180,45 @@ public: 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::DenseMap<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; diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h index 0b1b74a..99d94a1 100644 --- a/include/clang/Sema/IdentifierResolver.h +++ b/include/clang/Sema/IdentifierResolver.h @@ -51,11 +51,6 @@ class IdentifierResolver { /// The decl must already be part of the decl chain. void RemoveDecl(NamedDecl *D); - /// Replaces the Old declaration with the New declaration. If the - /// replacement is successful, returns true. If the old - /// declaration was not found, returns false. - bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); - /// \brief Insert the given declaration at the given position in the list. void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { Decls.insert(Pos, D); @@ -168,11 +163,6 @@ public: /// The decl must already be part of the decl chain. void RemoveDecl(NamedDecl *D); - /// Replace the decl Old with the new declaration New on its - /// identifier chain. Returns true if the old declaration was found - /// (and, therefore, replaced). - bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); - /// \brief Insert the given declaration after the given iterator /// position. void InsertDeclAfter(iterator Pos, NamedDecl *D); diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 58781ac..83fb2be 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -35,6 +35,7 @@ class ParmVarDecl; class Sema; class TypeLoc; class VarDecl; +class ObjCMethodDecl; /// \brief Describes an entity that is being initialized. class InitializedEntity { @@ -78,7 +79,17 @@ public: EK_LambdaCapture, /// \brief The entity being initialized is the initializer for a compound /// literal. - EK_CompoundLiteralInit + 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: @@ -105,8 +116,8 @@ private: }; struct C { - /// \brief The variable being captured by an EK_LambdaCapture. - VarDecl *Var; + /// \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; @@ -116,6 +127,10 @@ private: /// \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". @@ -168,10 +183,10 @@ private: const InitializedEntity &Parent); /// \brief Create the initialization entity for a lambda capture. - InitializedEntity(VarDecl *Var, FieldDecl *Field, SourceLocation Loc) - : Kind(EK_LambdaCapture), Parent(0), Type(Field->getType()) + InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc) + : Kind(EK_LambdaCapture), Parent(0), Type(FieldType) { - Capture.Var = Var; + Capture.VarID = VarID; Capture.Location = Loc.getRawEncoding(); } @@ -254,10 +269,19 @@ public: 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, - CXXBaseSpecifier *Base, + const CXXBaseSpecifier *Base, bool IsInheritedVirtualBase); /// \brief Create the initialization entity for a delegated constructor. @@ -285,10 +309,10 @@ public: } /// \brief Create the initialization entity for a lambda capture. - static InitializedEntity InitializeLambdaCapture(VarDecl *Var, - FieldDecl *Field, + static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID, + QualType FieldType, SourceLocation Loc) { - return InitializedEntity(Var, Field, Loc); + return InitializedEntity(VarID, FieldType, Loc); } /// \brief Create the entity for a compound literal initializer. @@ -326,22 +350,29 @@ public: /// \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(getKind() == EK_Parameter && "Not a parameter"); + assert(isParameterKind() && "Not a parameter"); return (Parameter & 1); } /// \brief Retrieve the base specifier. - CXXBaseSpecifier *getBaseSpecifier() const { + const CXXBaseSpecifier *getBaseSpecifier() const { assert(getKind() == EK_Base && "Not a base specifier"); - return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1); + return reinterpret_cast<const CXXBaseSpecifier *>(Base & ~0x1); } /// \brief Return whether the base is an inherited virtual base. @@ -371,19 +402,28 @@ public: getKind() == EK_ComplexElement); this->Index = Index; } - - /// \brief Retrieve the variable for a captured variable in a lambda. - VarDecl *getCapturedVar() const { + /// \brief For a lambda capture, return the capture's name. + StringRef getCapturedVarName() const { assert(getKind() == EK_LambdaCapture && "Not a lambda capture!"); - return Capture.Var; + 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; + } + + /// 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 @@ -544,8 +584,10 @@ public: bool AllowExplicit() const { return !isCopyInit(); } /// \brief Retrieve whether this initialization allows the use of explicit - /// conversion functions. - bool allowExplicitConversionFunctions() const { + /// 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; } @@ -610,6 +652,8 @@ public: 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 Perform list-initialization with a constructor. @@ -706,6 +750,16 @@ public: /// \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 @@ -753,9 +807,6 @@ public: /// \brief Initializer has a placeholder type which cannot be /// resolved by initialization. FK_PlaceholderType, - /// \brief Failed to initialize a std::initializer_list because copy - /// construction of some element failed. - FK_InitListElementCopyFailure, /// \brief List-copy-initialization chose an explicit constructor. FK_ExplicitConstructor }; @@ -791,11 +842,19 @@ public: /// \param Kind the kind of initialization being performed. /// /// \param Args the argument(s) provided for initialization. + /// + /// \param InInitList true if we are initializing from an expression within + /// an initializer list. This disallows narrowing conversions in C++11 + /// onwards. InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, - MultiExprArg Args); - + MultiExprArg Args, + bool InInitList = false); + void InitializeFrom(Sema &S, const InitializedEntity &Entity, + const InitializationKind &Kind, MultiExprArg Args, + bool InInitList); + ~InitializationSequence(); /// \brief Perform the actual initialization of the given entity based on @@ -841,12 +900,12 @@ public: void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } /// \brief Determine whether the initialization sequence is valid. - operator bool() const { return !Failed(); } + LLVM_EXPLICIT operator bool() const { return !Failed(); } /// \brief Determine whether the initialization sequence is invalid. bool Failed() const { return SequenceKind == FailedSequence; } - - typedef SmallVector<Step, 4>::const_iterator step_iterator; + + typedef SmallVectorImpl<Step>::const_iterator step_iterator; step_iterator step_begin() const { return Steps.begin(); } step_iterator step_end() const { return Steps.end(); } @@ -930,7 +989,7 @@ public: /// \brief Add a new step that applies an implicit conversion sequence. void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, - QualType T); + QualType T, bool TopLevelOfInitList = false); /// \brief Add a list-initialization step. void AddListInitializationStep(QualType T); diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 3e7e3a1..105c879 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -139,7 +139,8 @@ public: Redecl(Redecl != Sema::NotForRedeclaration), HideTags(true), Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(Redecl == Sema::ForRedeclaration) + AllowHidden(Redecl == Sema::ForRedeclaration), + Shadowed(false) { configure(); } @@ -160,7 +161,8 @@ public: Redecl(Redecl != Sema::NotForRedeclaration), HideTags(true), Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(Redecl == Sema::ForRedeclaration) + AllowHidden(Redecl == Sema::ForRedeclaration), + Shadowed(false) { configure(); } @@ -179,7 +181,8 @@ public: Redecl(Other.Redecl), HideTags(Other.HideTags), Diagnose(false), - AllowHidden(Other.AllowHidden) + AllowHidden(Other.AllowHidden), + Shadowed(false) {} ~LookupResult() { @@ -283,33 +286,36 @@ public: /// \brief Determine whether the given declaration is visible to the /// program. - static bool isVisible(NamedDecl *D) { + static bool isVisible(Sema &SemaRef, NamedDecl *D) { // If this declaration is not hidden, it's visible. if (!D->isHidden()) return true; - - // FIXME: We should be allowed to refer to a module-private name from - // within the same module, e.g., during template instantiation. - // This requires us know which module a particular declaration came from. - return false; + + if (SemaRef.ActiveTemplateInstantiations.empty()) + return false; + + // 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 0; - - if (isHiddenDeclarationVisible() || isVisible(D)) + + if (isHiddenDeclarationVisible() || isVisible(SemaRef, 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; @@ -390,7 +396,15 @@ public: 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. /// @@ -479,6 +493,7 @@ public: if (Paths) deletePaths(Paths); Paths = NULL; NamingClass = 0; + Shadowed = false; } /// \brief Clears out any current state and re-initializes for a @@ -598,6 +613,13 @@ public: return Filter(*this); } + void setFindLocalExtern(bool FindLocalExtern) { + if (FindLocalExtern) + IDNS |= Decl::IDNS_LocalExtern; + else + IDNS &= ~Decl::IDNS_LocalExtern; + } + private: void diagnose() { if (isAmbiguous()) @@ -657,34 +679,44 @@ private: /// \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. +/// \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. /// - /// 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 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; - }; + /// \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 { @@ -701,7 +733,8 @@ public: Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); } - class iterator { + class iterator + : public std::iterator<std::forward_iterator_tag, NamedDecl *> { typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator; inner_iterator iter; @@ -713,7 +746,7 @@ public: iterator &operator++() { ++iter; return *this; } iterator operator++(int) { return iterator(iter++); } - NamedDecl *operator*() const { return iter->second; } + value_type operator*() const { return iter->second; } bool operator==(const iterator &other) const { return iter == other.iter; } bool operator!=(const iterator &other) const { return iter != other.iter; } diff --git a/include/clang/Sema/Makefile b/include/clang/Sema/Makefile index 7d658a7..799f789 100644 --- a/include/clang/Sema/Makefile +++ b/include/clang/Sema/Makefile @@ -1,7 +1,7 @@ CLANG_LEVEL := ../../.. TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \ - AttrSpellingListIndex.inc + AttrSpellingListIndex.inc AttrParsedAttrImpl.inc TABLEGEN_INC_FILES_COMMON = 1 @@ -31,4 +31,9 @@ $(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \ $(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 index ff87d05..e9ba479 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -322,6 +322,36 @@ public: 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::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap); + + /// \copydoc ExternalSemaSource::CorrectTypo + /// \note Returns the first nonempty correction. + virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, + int LookupKind, Scope *S, CXXScopeSpec *SS, + CorrectionCandidateCallback &CCC, + DeclContext *MemberContext, + bool EnteringContext, + const ObjCObjectPointerType *OPT); + + /// \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. + virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, QualType T); + // isa/cast/dyn_cast support static bool classof(const MultiplexExternalSemaSource*) { return true; } //static bool classof(const ExternalSemaSource*) { return true; } diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index c685843..b8bd14a 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -22,6 +22,7 @@ #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/Allocator.h" @@ -241,7 +242,7 @@ namespace clang { QualType &ConstantType) const; bool isPointerConversionToBool() const; bool isPointerConversionToVoidPointer(ASTContext& Context) const; - void DebugPrint() const; + void dump() const; }; /// UserDefinedConversionSequence - Represents a user-defined @@ -287,7 +288,7 @@ namespace clang { /// that refers to \c ConversionFunction. DeclAccessPair FoundConversionFunction; - void DebugPrint() const; + void dump() const; }; /// Represents an ambiguous user-defined conversion sequence. @@ -405,9 +406,6 @@ namespace clang { /// ConversionKind - The kind of implicit conversion sequence. unsigned ConversionKind : 30; - /// \brief Whether the argument is an initializer list. - bool ListInitializationSequence : 1; - /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. bool StdInitializerListElement : 1; @@ -440,16 +438,14 @@ namespace clang { BadConversionSequence Bad; }; - ImplicitConversionSequence() - : ConversionKind(Uninitialized), ListInitializationSequence(false), - StdInitializerListElement(false) + ImplicitConversionSequence() + : ConversionKind(Uninitialized), StdInitializerListElement(false) {} ~ImplicitConversionSequence() { destruct(); } ImplicitConversionSequence(const ImplicitConversionSequence &Other) - : ConversionKind(Other.ConversionKind), - ListInitializationSequence(Other.ListInitializationSequence), + : ConversionKind(Other.ConversionKind), StdInitializerListElement(Other.StdInitializerListElement) { switch (ConversionKind) { @@ -535,16 +531,6 @@ namespace clang { Ambiguous.construct(); } - /// \brief Whether this sequence was created by the rules of - /// list-initialization sequences. - bool isListInitializationSequence() const { - return ListInitializationSequence; - } - - void setListInitializationSequence() { - ListInitializationSequence = true; - } - /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. bool isStdInitializerListElement() const { @@ -568,7 +554,7 @@ namespace clang { SourceLocation CaretLoc, const PartialDiagnostic &PDiag) const; - void DebugPrint() const; + void dump() const; }; enum OverloadFailureKind { @@ -656,53 +642,6 @@ namespace clang { /// \brief The number of call arguments that were explicitly provided, /// to be used while performing partial ordering of function templates. unsigned ExplicitCallArguments; - - /// A structure used to record information about a failed - /// template argument deduction. - 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 Free any memory associated with this deduction failure. - void Destroy(); - }; union { DeductionFailureInfo DeductionFailure; @@ -773,7 +712,7 @@ namespace clang { /// \brief Clear out all of the candidates. void clear(); - typedef SmallVector<OverloadCandidate, 16>::iterator iterator; + typedef SmallVectorImpl<OverloadCandidate>::iterator iterator; iterator begin() { return Candidates.begin(); } iterator end() { return Candidates.end(); } diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index c3d1f4e..b7d7710 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -33,8 +33,12 @@ namespace clang { class TemplateName; class TemplateParameterList; - /// OpaquePtr - 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 UID + /// \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> @@ -49,11 +53,21 @@ namespace clang { static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } - template <typename T> T* getAs() const { + /// \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(); } - template <typename T> T getAsVal() const { + /// \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(); } @@ -65,7 +79,7 @@ namespace clang { Ptr = Traits::getAsVoidPointer(P); } - operator bool() const { return Ptr != 0; } + LLVM_EXPLICIT operator bool() const { return Ptr != 0; } void *getAsOpaquePtr() const { return Ptr; } static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index d016b9b..249a4c7 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -91,7 +91,10 @@ public: TryScope = 0x2000, /// \brief This is the scope for a function-level C++ try or catch scope. - FnTryCatchScope = 0x4000 + FnTryCatchScope = 0x4000, + + /// \brief This is the scope of OpenMP executable directive + OpenMPDirectiveScope = 0x8000 }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -143,11 +146,10 @@ private: typedef llvm::SmallPtrSet<Decl *, 32> DeclSetTy; DeclSetTy DeclsInScope; - /// Entity - The entity with which this scope is associated. For + /// 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. This field is - /// maintained by the Action implementation. - void *Entity; + /// entity of a function scope is a function, etc. + DeclContext *Entity; typedef SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy; UsingDirectivesTy UsingDirectives; @@ -236,8 +238,8 @@ public: return DeclsInScope.count(D) != 0; } - void* getEntity() const { return Entity; } - void setEntity(void *E) { Entity = E; } + DeclContext *getEntity() const { return Entity; } + void setEntity(DeclContext *E) { Entity = E; } bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); } @@ -301,7 +303,12 @@ public: } 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 a C++ 'try' block. bool isTryScope() const { return getFlags() & Scope::TryScope; } diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index b232b59..06afe1a 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -18,8 +18,11 @@ #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 { @@ -27,6 +30,7 @@ class Decl; class BlockDecl; class CapturedDecl; class CXXMethodDecl; +class FieldDecl; class ObjCPropertyDecl; class IdentifierInfo; class ImplicitParamDecl; @@ -34,8 +38,11 @@ class LabelDecl; class ReturnStmt; class Scope; class SwitchStmt; +class TemplateTypeParmDecl; +class TemplateParameterList; class VarDecl; class DeclRefExpr; +class MemberExpr; class ObjCIvarRefExpr; class ObjCPropertyRefExpr; class ObjCMessageExpr; @@ -330,60 +337,78 @@ public: ImplicitCaptureStyle ImpCaptureStyle; class Capture { - // There are two categories of capture: capturing 'this', and capturing - // local variables. 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. + // 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_This, Cap_ByCopy, Cap_ByRef, Cap_Block + Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This }; - // The variable being captured (if we are not capturing 'this'), - // and misc bits descibing the capture. - llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; + /// 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 whether this - // is a nested capture; the expression is only required if we are - // capturing ByVal and the variable's type has a non-trivial - // copy constructor. - llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; + /// 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<Expr*, 2, CaptureKind> InitExprAndCaptureKind; - /// \brief The source location at which the first capture occurred.. + /// \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, + Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, + SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, Expr *Cpy) - : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), - CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), - CaptureType(CaptureType){} + : 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, + Capture(IsThisCapture, bool IsNested, SourceLocation Loc, QualType CaptureType, Expr *Cpy) - : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), - EllipsisLoc(), CaptureType(CaptureType) { } + : VarAndNested(0, IsNested), + InitExprAndCaptureKind(Cpy, Cap_This), + Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} - bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } - bool isVariableCapture() const { return !isThisCapture(); } - bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } - bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } - bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } - bool isNested() { return CopyExprAndNested.getInt(); } + bool isThisCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_This; + } + bool isVariableCapture() const { + return InitExprAndCaptureKind.getInt() != Cap_This; + } + bool isCopyCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_ByCopy; + } + bool isReferenceCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_ByRef; + } + bool isBlockCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_Block; + } + bool isNested() { return VarAndNested.getInt(); } VarDecl *getVariable() const { - return VarAndKind.getPointer(); + return VarAndNested.getPointer(); } /// \brief Retrieve the location at which this variable was captured. @@ -398,8 +423,8 @@ public: /// that would store this capture. QualType getCaptureType() const { return CaptureType; } - Expr *getCopyExpr() const { - return CopyExprAndNested.getPointer(); + Expr *getInitExpr() const { + return InitExprAndCaptureKind.getPointer(); } }; @@ -529,6 +554,8 @@ public: switch (CapRegionKind) { case CR_Default: return "default captured statement"; + case CR_OpenMP: + return "OpenMP region"; } llvm_unreachable("Invalid captured region kind!"); } @@ -543,19 +570,23 @@ public: /// \brief The class that describes the lambda. CXXRecordDecl *Lambda; - /// \brief The class that describes the lambda. + /// \brief The lambda's compiler-generated \c operator(). CXXMethodDecl *CallOperator; /// \brief Source range covering the lambda introducer [...]. SourceRange IntroducerRange; - /// \brief The number of captures in the \c Captures list that are + /// \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; @@ -572,25 +603,169 @@ public: /// its list of array index variables. SmallVector<unsigned, 4> ArrayIndexStarts; - LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, - CXXMethodDecl *CallOperator) - : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), - CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), - ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) + /// \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(0), + CallOperator(0), NumExplicitCaptures(0), Mutable(false), + ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false), + AutoTemplateParameterDepth(0), GLTemplateParameterList(0) { Kind = SK_Lambda; } virtual ~LambdaScopeInfo(); - /// \brief Note when + /// \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; + 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) { + 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); + }; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index d7c80f2..48794d6 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -20,12 +20,13 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExternalASTSource.h" -#include "clang/AST/LambdaMangleContext.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/OpenMPKinds.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" @@ -49,6 +50,7 @@ #include "llvm/MC/MCParser/MCAsmParser.h" #include <deque> #include <string> +#include <vector> namespace llvm { class APSInt; @@ -85,6 +87,7 @@ namespace clang { class ClassTemplateDecl; class ClassTemplatePartialSpecializationDecl; class ClassTemplateSpecializationDecl; + class VarTemplatePartialSpecializationDecl; class CodeCompleteConsumer; class CodeCompletionAllocator; class CodeCompletionTUInfo; @@ -136,6 +139,7 @@ namespace clang { class ObjCPropertyDecl; class ObjCProtocolDecl; class OMPThreadPrivateDecl; + class OMPClause; class OverloadCandidateSet; class OverloadExpr; class ParenListExpr; @@ -170,9 +174,12 @@ namespace clang { class UsingShadowDecl; class ValueDecl; class VarDecl; + class VarTemplateSpecializationDecl; class VisibilityAttr; class VisibleDeclConsumer; class IndirectFieldDecl; + struct DeductionFailureInfo; + class TemplateSpecCandidateSet; namespace sema { class AccessedEntity; @@ -215,7 +222,7 @@ class Sema { // 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 !Old->isHidden() || New->hasExternalLinkage(); + return !Old->isHidden() || New->isExternallyVisible(); } public: @@ -274,6 +281,12 @@ public: /// 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 @@ -340,8 +353,7 @@ public: llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternCDecls; /// \brief Look for a locally scoped extern "C" declaration by the given name. - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator - findLocallyScopedExternCDecl(DeclarationName Name); + NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); typedef LazyVector<VarDecl *, ExternalSemaSource, &ExternalSemaSource::ReadTentativeDefinitions, 2, 2> @@ -366,11 +378,6 @@ public: /// cycle detection at the end of the TU. DelegatingCtorDeclsType DelegatingCtorDecls; - /// \brief All the destructors seen during a class definition that had their - /// exception spec computation delayed because it depended on an unparsed - /// exception spec. - SmallVector<CXXDestructorDecl*, 2> DelayedDestructorExceptionSpecs; - /// \brief All the overriding destructors seen during a class definition /// (there could be multiple due to nested classes) that had their exception /// spec checks delayed, plus the overridden destructor. @@ -388,8 +395,12 @@ public: SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> DelayedDefaultedMemberExceptionSpecs; + typedef llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> + LateParsedTemplateMapT; + LateParsedTemplateMapT LateParsedTemplateMap; + /// \brief Callback to the parser to parse templated functions when needed. - typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD); + typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT); LateTemplateParserCB *LateTemplateParser; void *OpaqueParser; @@ -621,7 +632,7 @@ public: /// \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 statment). + /// cases in a switch statement). ConstantEvaluated, /// \brief The current expression is potentially evaluated at run time, @@ -662,17 +673,17 @@ public: /// is indeed an unevaluated context. SmallVector<LambdaExpr *, 2> Lambdas; - /// \brief The declaration that provides context for the lambda expression - /// if the normal declaration context does not suffice, e.g., in a - /// default function argument. - Decl *LambdaContextDecl; + /// \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 - /// within this context. + /// and block literals within this context. /// /// This mangling information is allocated lazily, since most contexts - /// do not have lambda expressions. - IntrusiveRefCntPtr<LambdaMangleContext> LambdaMangle; + /// 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. @@ -685,19 +696,15 @@ public: ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, unsigned NumCleanupObjects, bool ParentNeedsCleanups, - Decl *LambdaContextDecl, + Decl *ManglingContextDecl, bool IsDecltype) : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), - LambdaContextDecl(LambdaContextDecl), LambdaMangle() { } - - /// \brief Retrieve the mangling context for lambdas. - LambdaMangleContext &getLambdaMangleContext() { - assert(LambdaContextDecl && "Need to have a lambda context declaration"); - if (!LambdaMangle) - LambdaMangle = new LambdaMangleContext; - return *LambdaMangle; - } + 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; @@ -707,6 +714,18 @@ public: /// 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. /// @@ -775,7 +794,7 @@ public: /// Obtain a sorted list of functions that are undefined but ODR-used. void getUndefinedButUsed( - llvm::SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); + SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; @@ -905,6 +924,15 @@ public: // 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. @@ -922,8 +950,9 @@ public: bool findMacroSpelling(SourceLocation &loc, StringRef name); /// \brief Get a string to suggest for zero-initialization of a type. - std::string getFixItZeroInitializerForType(QualType T) const; - std::string getFixItZeroLiteralForType(QualType T) const; + std::string + getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const; + std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const; ExprResult Owned(Expr* E) { return E; } ExprResult Owned(ExprResult R) { return R; } @@ -937,7 +966,13 @@ public: void PushFunctionScope(); void PushBlockScope(Scope *BlockScope, BlockDecl *Block); - void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator); + 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); @@ -947,7 +982,13 @@ public: sema::FunctionScopeInfo *getCurFunction() const { return FunctionScopes.back(); } - + + template <typename ExprT> + void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) { + if (!isUnevaluatedContext()) + getCurFunction()->recordUseOfWeak(E, IsRead); + } + void PushCompoundScope(); void PopCompoundScope(); @@ -958,14 +999,17 @@ public: /// \brief Retrieve the current block, if any. sema::BlockScopeInfo *getCurBlock(); - /// \brief Retrieve the current lambda expression, if any. + /// \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 - SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } + SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; } void ActOnComment(SourceRange Comment); @@ -987,6 +1031,8 @@ public: 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 @@ -1152,6 +1198,10 @@ public: virtual ~BoundTypeDiagnoser3() { } }; +private: + bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, + TypeDiagnoser &Diagnoser); +public: bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser); bool RequireCompleteType(SourceLocation Loc, QualType T, @@ -1287,6 +1337,7 @@ public: NC_Expression, NC_NestedNameSpecifier, NC_TypeTemplate, + NC_VarTemplate, NC_FunctionTemplate }; @@ -1325,6 +1376,12 @@ public: 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; @@ -1344,13 +1401,22 @@ public: } TemplateName getTemplateName() const { - assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); + assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || + Kind == NC_VarTemplate); return Template; } TemplateNameKind getTemplateNameKind() const { - assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); - return Kind == NC_TypeTemplate? TNK_Type_template : TNK_Function_template; + 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."); + } } }; @@ -1390,13 +1456,12 @@ public: NamedDecl *HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists); - void RegisterLocallyScopedExternCDecl(NamedDecl *ND, - const LookupResult &Previous, - Scope *S); + void RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S); bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, DeclarationName Name, SourceLocation Loc); + 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); @@ -1407,10 +1472,11 @@ public: LookupResult &Previous); NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, LookupResult &Previous, bool &Redeclaration); - NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, + NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, - MultiTemplateParamsArg TemplateParamLists); + MultiTemplateParamsArg TemplateParamLists, + bool &AddToScope); // Returns true if the variable declaration is a redeclaration bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); @@ -1418,6 +1484,7 @@ public: void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); void ActOnStartFunctionDeclarator(); void ActOnEndFunctionDeclarator(); + NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -1429,12 +1496,17 @@ public: bool CheckConstexprFunctionDecl(const FunctionDecl *FD); bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body); - void DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); + 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, @@ -1462,19 +1534,20 @@ public: void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); void FinalizeDeclaration(Decl *D); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, - Decl **Group, - unsigned NumDecls); - DeclGroupPtrTy BuildDeclaratorGroup(Decl **Group, unsigned NumDecls, + ArrayRef<Decl *> Group); + DeclGroupPtrTy BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group, bool TypeMayContainAuto = true); /// Should be called on all declarations that might have attached /// documentation comments. void ActOnDocumentableDecl(Decl *D); - void ActOnDocumentableDecls(Decl **Group, unsigned NumDecls); + void ActOnDocumentableDecls(ArrayRef<Decl *> Group); void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, SourceLocation LocAfterDecls); - void CheckForFunctionRedefinition(FunctionDecl *FD); + void CheckForFunctionRedefinition(FunctionDecl *FD, + const FunctionDecl *EffectiveDefinition = + 0); Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D); Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); @@ -1533,6 +1606,10 @@ public: 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 Create an implicit import of the given module at the given /// source location. /// @@ -1660,6 +1737,7 @@ public: /// member declarations. void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, SourceLocation FinalLoc, + bool IsFinalSpelledSealed, SourceLocation LBraceLoc); /// ActOnTagFinishDefinition - Invoked once we have finished parsing @@ -1748,7 +1826,7 @@ public: /// \param ExplicitInstantiationOrSpecialization When true, we are checking /// whether the declaration is in scope for the purposes of explicit template /// instantiation or specialization. The default is false. - bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0, + bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = 0, bool ExplicitInstantiationOrSpecialization = false); /// Finds the scope corresponding to the given decl context, if it @@ -1780,9 +1858,9 @@ public: unsigned AttrSpellingListIndex); DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); - FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, - int FormatIdx, int FirstArg, - unsigned AttrSpellingListIndex); + FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, + IdentifierInfo *Format, int FormatIdx, + int FirstArg, unsigned AttrSpellingListIndex); SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name, unsigned AttrSpellingListIndex); @@ -1802,13 +1880,13 @@ public: void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK = AMK_Redeclaration); void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls); - bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S); + bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S, + bool MergeTypeWithOld); bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, - Scope *S); + Scope *S, bool MergeTypeWithOld); void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old); - void MergeVarDecl(VarDecl *New, LookupResult &OldDecls, - bool OldDeclsWereHidden); - void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldIsHidden); + 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); @@ -1821,7 +1899,8 @@ public: AA_Converting, AA_Initializing, AA_Sending, - AA_Casting + AA_Casting, + AA_Passing_CFAudited }; /// C++ Overloading. @@ -1920,65 +1999,91 @@ public: /// 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_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); - /// \brief Abstract base class used to diagnose problems that occur while - /// trying to convert an expression to integral or enumeration type. - class ICEConvertDiagnoser { + /// \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; - ICEConvertDiagnoser(bool Suppress = false, - bool SuppressConversion = false) - : Suppress(Suppress), SuppressConversion(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 DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, - QualType T) = 0; + virtual SemaDiagnosticBuilder + diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) = 0; /// \brief Emits a diagnostic when the expression has incomplete class type. - virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, - QualType T) = 0; + virtual SemaDiagnosticBuilder + diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) = 0; /// \brief Emits a diagnostic when the only matching conversion function /// is explicit. - virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, - QualType T, - QualType ConvTy) = 0; + virtual SemaDiagnosticBuilder diagnoseExplicitConv( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; /// \brief Emits a note for the explicit conversion function. - virtual DiagnosticBuilder + virtual SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; /// \brief Emits a diagnostic when there are multiple possible conversion /// functions. - virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, - QualType T) = 0; + virtual SemaDiagnosticBuilder + diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) = 0; /// \brief Emits a note for one of the candidate conversions. - virtual DiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, - QualType ConvTy) = 0; + 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 DiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, - QualType T, - QualType ConvTy) = 0; + virtual SemaDiagnosticBuilder diagnoseConversion( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) = 0; - virtual ~ICEConvertDiagnoser() {} + virtual ~ContextualImplicitConverter() {} }; - ExprResult - ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE, - ICEConvertDiagnoser &Diagnoser, - bool AllowScopedEnumerations); + 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); + + SemaDiagnosticBuilder + diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) { + 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, @@ -2054,12 +2159,14 @@ public: DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, - OverloadCandidateSet& CandidateSet); + OverloadCandidateSet& CandidateSet, + bool AllowObjCConversionOnExplicit = false); void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, - OverloadCandidateSet &CandidateSet); + OverloadCandidateSet &CandidateSet, + bool AllowObjCConversionOnExplicit = false); void AddSurrogateCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -2159,14 +2266,13 @@ public: ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig, bool AllowTypoCorrection=true); bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE, - Expr **Args, unsigned NumArgs, - SourceLocation RParenLoc, + MultiExprArg Args, SourceLocation RParenLoc, OverloadCandidateSet *CandidateSet, ExprResult *Result); @@ -2186,15 +2292,17 @@ public: ExprResult BuildCallToMemberFunction(Scope *S, Expr *MemExpr, - SourceLocation LParenLoc, Expr **Args, - unsigned NumArgs, SourceLocation RParenLoc); + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation RParenLoc); ExprResult BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + MultiExprArg Args, SourceLocation RParenLoc); ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, - SourceLocation OpLoc); + SourceLocation OpLoc, + bool *NoArrowOperatorFound = 0); /// CheckCallReturnType - Checks that a call expression's return type is /// complete. Returns true on failure. The location passed in is the location @@ -2203,7 +2311,8 @@ public: CallExpr *CE, FunctionDecl *FD); /// Helpers for dealing with blocks and functions. - bool CheckParmsForFunctionDef(ParmVarDecl **Param, ParmVarDecl **ParamEnd, + bool CheckParmsForFunctionDef(ParmVarDecl *const *Param, + ParmVarDecl *const *ParamEnd, bool CheckParameterNames); void CheckCXXDefaultArguments(FunctionDecl *FD); void CheckExtraCXXDefaultArguments(Declarator &D); @@ -2271,6 +2380,9 @@ public: /// 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. @@ -2303,7 +2415,11 @@ public: /// \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 + 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, @@ -2370,7 +2486,9 @@ public: LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, ArrayRef<QualType> ArgTys, - bool AllowRawAndTemplate); + bool AllowRaw, + bool AllowTemplate, + bool AllowStringTemplate); bool isKnownName(StringRef name); void ArgumentDependentLookup(DeclarationName Name, bool Operator, @@ -2391,7 +2509,17 @@ public: CorrectionCandidateCallback &CCC, DeclContext *MemberContext = 0, bool EnteringContext = false, - const ObjCObjectPointerType *OPT = 0); + const ObjCObjectPointerType *OPT = 0, + bool RecordFailure = true); + + 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, @@ -2402,7 +2530,7 @@ public: bool ConsiderLinkage, bool ExplicitInstantiationOrSpecialization); - bool DiagnoseAmbiguousLookup(LookupResult &Result); + void DiagnoseAmbiguousLookup(LookupResult &Result); //@} ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id, @@ -2419,12 +2547,8 @@ public: void ProcessPragmaWeak(Scope *S, Decl *D); // Decl attributes - this routine is the top level dispatcher. - void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, - bool NonInheritable = true, - bool Inheritable = true); + void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, - bool NonInheritable = true, - bool Inheritable = true, bool IncludeCXX11Attributes = true); bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, const AttributeList *AttrList); @@ -2435,8 +2559,21 @@ public: bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const FunctionDecl *FD = 0); bool CheckNoReturnAttr(const AttributeList &attr); + bool checkStringLiteralArgumentAttr(const AttributeList &Attr, + unsigned ArgNum, StringRef &Str, + SourceLocation *ArgLocation = 0); + 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); + + /// 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; + /// \brief Stmt attributes - this routine is the top level dispatcher. StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs, SourceRange Range); @@ -2457,9 +2594,6 @@ public: ObjCMethodDecl *MethodDecl, bool IsProtocolMethodDecl); - bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl, - ObjCInterfaceDecl *IDecl); - typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap; @@ -2507,6 +2641,16 @@ public: 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); + + /// 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, @@ -2592,6 +2736,17 @@ private: bool receiverIdOrClass, bool warn, bool instance); + /// \brief Record the typo correction failure and return an empty correction. + TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, + bool RecordFailure = true, + bool IsUnqualifiedLookup = false) { + if (IsUnqualifiedLookup) + (void)UnqualifiedTyposCorrected[Typo]; + 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 @@ -2628,6 +2783,14 @@ public: warn, /*instance*/false); } + const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel, + QualType ObjectType=QualType()); + + /// DiagnoseMismatchedMethodsInGlobalPool - This routine goes through list of + /// methods in global pool and issues diagnostic on identical selectors which + /// have mismathched types. + void DiagnoseMismatchedMethodsInGlobalPool(); + /// LookupImplementedMethodInGlobalPool - Returns the method which has an /// implementation. ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel); @@ -2691,8 +2854,7 @@ public: void ActOnStartOfCompoundStmt(); void ActOnFinishOfCompoundStmt(); StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, - MultiStmtArg Elts, - bool isStmtExpr); + ArrayRef<Stmt *> Elts, bool isStmtExpr); /// \brief A RAII object to enter scope of a compound statement. class CompoundScopeRAII { @@ -2865,11 +3027,10 @@ public: StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock); StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, - MultiStmtArg Handlers); + ArrayRef<Stmt *> Handlers); StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? - SourceLocation TryLoc, - Stmt *TryBlock, + SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler); StmtResult ActOnSEHExceptBlock(SourceLocation Loc, @@ -2944,7 +3105,7 @@ public: ObjCMethodDecl *Getter, SourceLocation Loc); void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, - Expr **Args, unsigned NumArgs); + ArrayRef<Expr *> Args); void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = 0, @@ -3006,12 +3167,19 @@ public: /// 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); + QualType &DeclRefType, + const unsigned *const FunctionScopeIndexToStopAt); /// \brief Try to capture the given variable. bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, @@ -3034,8 +3202,8 @@ public: bool (*IsPlausibleResult)(QualType) = 0); /// \brief Figure out if an expression could be turned into a call. - bool isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, - UnresolvedSetImpl &NonTemplateOverloads); + bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, + UnresolvedSetImpl &NonTemplateOverloads); /// \brief Conditionally issue a diagnostic based on the current /// evaluation context. @@ -3054,7 +3222,8 @@ public: SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = 0); + CorrectionCandidateCallback *CCC = 0, + bool IsInlineAsmIdentifier = false); void DecomposeUnqualifiedId(const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, @@ -3080,17 +3249,19 @@ public: ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS = 0); - ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, - ExprValueKind VK, + ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, - const CXXScopeSpec *SS = 0, - NamedDecl *FoundD = 0); + const CXXScopeSpec *SS = 0, NamedDecl *FoundD = 0, + const TemplateArgumentListInfo *TemplateArgs = 0); ExprResult - BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, - SourceLocation nameLoc, - IndirectFieldDecl *indirectField, - Expr *baseObjectExpr = 0, - SourceLocation opLoc = SourceLocation()); + BuildAnonymousStructUnionMemberReference( + const CXXScopeSpec &SS, + SourceLocation nameLoc, + IndirectFieldDecl *indirectField, + DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_none), + Expr *baseObjectExpr = 0, + SourceLocation opLoc = SourceLocation()); + ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, @@ -3115,9 +3286,9 @@ public: ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL); - ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - NamedDecl *D, NamedDecl *FoundD = 0); + ExprResult BuildDeclarationNameExpr( + const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, + NamedDecl *FoundD = 0, const TemplateArgumentListInfo *TemplateArgs = 0); ExprResult BuildLiteralOperatorCall(LookupResult &R, DeclarationNameInfo &SuffixInfo, @@ -3125,6 +3296,8 @@ public: SourceLocation LitEndLoc, TemplateArgumentListInfo *ExplicitTemplateArgs = 0); + ExprResult BuildPredefinedExpr(SourceLocation Loc, + PredefinedExpr::IdentType IT); ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = 0); @@ -3143,15 +3316,14 @@ public: SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - MultiTypeArg ArgTypes, - MultiExprArg ArgExprs); + ArrayRef<ParsedType> ArgTypes, + ArrayRef<Expr *> ArgExprs); ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - TypeSourceInfo **Types, - Expr **Exprs, - unsigned NumAssocs); + ArrayRef<TypeSourceInfo *> Types, + ArrayRef<Expr *> Exprs); // Binary/Unary Operators. 'Tok' is the token for the operator. ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, @@ -3161,6 +3333,8 @@ public: 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, @@ -3255,7 +3429,7 @@ public: bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, const FunctionProtoType *Proto, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RParenLoc, bool ExecConfig = false); void CheckStaticArrayArgument(SourceLocation CallLoc, @@ -3270,7 +3444,7 @@ public: Expr *ExecConfig = 0, bool IsExecConfig = false); ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Arg, SourceLocation RParenLoc, Expr *Config = 0, bool IsExecConfig = false); @@ -3431,6 +3605,13 @@ public: 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(...) @@ -3488,12 +3669,14 @@ public: void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow); bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target, - const LookupResult &PreviousDecls); + const LookupResult &PreviousDecls, + UsingShadowDecl *&PrevShadow); UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD, - NamedDecl *Target); + NamedDecl *Target, + UsingShadowDecl *PrevDecl); bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc, - bool isTypeName, + bool HasTypenameKeyword, const CXXScopeSpec &SS, SourceLocation NameLoc, const LookupResult &Previous); @@ -3507,7 +3690,7 @@ public: const DeclarationNameInfo &NameInfo, AttributeList *AttrList, bool IsInstantiation, - bool IsTypeName, + bool HasTypenameKeyword, SourceLocation TypenameLoc); bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); @@ -3519,7 +3702,7 @@ public: CXXScopeSpec &SS, UnqualifiedId &Name, AttributeList *AttrList, - bool IsTypeName, + bool HasTypenameKeyword, SourceLocation TypenameLoc); Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, @@ -3918,7 +4101,17 @@ public: /// /// \param Explicit Whether 'this' is explicitly captured in a lambda /// capture list. - void CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false); + /// + /// \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 = 0); /// \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 @@ -3979,22 +4172,26 @@ public: SourceRange R); bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, bool UseGlobal, QualType AllocType, bool IsArray, - Expr **PlaceArgs, unsigned NumPlaceArgs, + MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete); bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, - DeclarationName Name, Expr** Args, - unsigned NumArgs, DeclContext *Ctx, + DeclarationName Name, MultiExprArg Args, + DeclContext *Ctx, bool AllowMissing, FunctionDecl *&Operator, bool Diagnose = true); void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, - QualType Argument, + QualType Param1, + QualType Param2 = QualType(), bool addMallocAttr = 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, @@ -4120,7 +4317,8 @@ public: } ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, bool DiscardedValue = false, - bool IsConstexpr = false); + bool IsConstexpr = false, + bool IsLambdaInitCaptureInitializer = false); StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. @@ -4131,7 +4329,6 @@ public: bool EnteringContext = false); bool isDependentScopeSpecifier(const CXXScopeSpec &SS); CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS); - bool isUnknownSpecialization(const CXXScopeSpec &SS); /// \brief The parser has parsed a global nested-name-specifier '::'. /// @@ -4296,7 +4493,8 @@ public: /// \brief Create a new lambda closure type. CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, TypeSourceInfo *Info, - bool KnownDependent); + bool KnownDependent, + LambdaCaptureDefault CaptureDefault); /// \brief Start the definition of a lambda expression. CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, @@ -4305,13 +4503,31 @@ public: SourceLocation EndLoc, ArrayRef<ParmVarDecl *> Params); - /// \brief Introduce the scope for a lambda expression. - sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator, - SourceRange IntroducerRange, - LambdaCaptureDefault CaptureDefault, - bool ExplicitParams, - bool ExplicitResultType, - bool Mutable); + /// \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. + QualType performLambdaInitCaptureInitialization(SourceLocation Loc, + bool ByRef, IdentifierInfo *Id, 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, 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. @@ -4444,6 +4660,7 @@ public: // bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS = 0); + bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS); bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, @@ -4466,7 +4683,7 @@ public: const DeclSpec &DS, SourceLocation IdLoc, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RParenLoc, SourceLocation EllipsisLoc); @@ -4590,7 +4807,9 @@ public: void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnFinishDelayedMemberInitializers(Decl *Record); - void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true); + void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD, + CachedTokens &Toks); + void UnmarkAsLateParsedTemplate(FunctionDecl *FD); bool IsInsideALocalClassWithinATemplateFunction(); Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, @@ -4624,7 +4843,7 @@ public: void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD, const FunctionProtoType *T); - void CheckDelayedExplicitlyDefaultedMemberExceptionSpecs(); + void CheckDelayedMemberExceptionSpecs(); //===--------------------------------------------------------------------===// // C++ Derived Classes @@ -4687,7 +4906,7 @@ public: bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); /// CheckOverrideControl - Check C++11 override control semantics. - void CheckOverrideControl(Decl *D); + void CheckOverrideControl(NamedDecl *D); /// CheckForFunctionMarkedFinal - Checks whether a virtual member function /// overrides a virtual member function marked 'final', according to @@ -4735,6 +4954,9 @@ public: 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, @@ -4771,6 +4993,7 @@ public: AbstractVariableType, AbstractFieldType, AbstractIvarType, + AbstractSynthesizedIvarType, AbstractArrayType }; @@ -4878,12 +5101,13 @@ public: Decl **Params, unsigned NumParams, SourceLocation RAngleLoc); - /// \brief The context in which we are checking a template parameter - /// list. + /// \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 @@ -4892,15 +5116,10 @@ public: bool CheckTemplateParameterList(TemplateParameterList *NewParams, TemplateParameterList *OldParams, TemplateParamListContext TPC); - TemplateParameterList * - MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, - SourceLocation DeclLoc, - const CXXScopeSpec &SS, - TemplateParameterList **ParamLists, - unsigned NumParamLists, - bool IsFriend, - bool &IsExplicitSpecialization, - bool &Invalid); + TemplateParameterList *MatchTemplateParametersToScopeSpecifier( + SourceLocation DeclStartLoc, SourceLocation DeclLoc, + const CXXScopeSpec &SS, ArrayRef<TemplateParameterList *> ParamLists, + bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid); DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, @@ -4942,6 +5161,21 @@ public: ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc); + DeclResult ActOnVarTemplateSpecialization( + Scope *S, VarTemplateDecl *VarTemplate, 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, @@ -5035,7 +5269,9 @@ public: SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, - SmallVectorImpl<TemplateArgument> &Converted); + SmallVectorImpl<TemplateArgument> + &Converted, + bool &HasDefaultArg); /// \brief Specifies the context in which a particular template /// argument is being checked. @@ -5289,7 +5525,7 @@ public: /// \brief Block expression, UPPC_Block -}; + }; /// \brief Diagnose unexpanded parameter packs. /// @@ -5538,10 +5774,25 @@ public: /// 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 @@ -5598,12 +5849,16 @@ public: sema::TemplateDeductionInfo &Info); TemplateDeductionResult - SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - TemplateArgumentListInfo &ExplicitTemplateArgs, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - SmallVectorImpl<QualType> &ParamTypes, - QualType *FunctionType, - sema::TemplateDeductionInfo &Info); + 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. @@ -5655,6 +5910,12 @@ public: 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, @@ -5666,7 +5927,6 @@ public: QualType &Result); DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result); - QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); @@ -5679,17 +5939,16 @@ public: FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments); - UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, - UnresolvedSetIterator SEnd, - TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments, - SourceLocation Loc, - const PartialDiagnostic &NoneDiag, - const PartialDiagnostic &AmbigDiag, - const PartialDiagnostic &CandidateDiag, - bool Complain = true, - QualType TargetType = QualType()); + 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( @@ -5697,6 +5956,10 @@ public: ClassTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); + VarTemplatePartialSpecializationDecl *getMoreSpecializedPartialSpecialization( + VarTemplatePartialSpecializationDecl *PS1, + VarTemplatePartialSpecializationDecl *PS2, SourceLocation Loc); + void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs, bool OnlyDeduced, unsigned Depth, @@ -5814,10 +6077,7 @@ public: case PriorTemplateArgumentSubstitution: case DefaultTemplateArgumentChecking: - if (X.Template != Y.Template) - return false; - - // Fall through + return X.Template == Y.Template && X.TemplateArgs == Y.TemplateArgs; case DefaultTemplateArgumentInstantiation: case ExplicitTemplateArgumentSubstitution: @@ -5845,6 +6105,20 @@ public: 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. /// @@ -5906,8 +6180,9 @@ public: /// deduction. /// /// FIXME: Serialize this structure to the AST file. - llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > - SuppressedDiagnostics; + typedef llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> > + SuppressedDiagnosticsMap; + SuppressedDiagnosticsMap SuppressedDiagnostics; /// \brief A stack object to be created when performing template /// instantiation. @@ -5959,6 +6234,15 @@ public: 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()); + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param, ArrayRef<TemplateArgument> TemplateArgs, @@ -5994,7 +6278,7 @@ public: /// \brief Determines whether we have exceeded the maximum /// recursive template instantiations. - operator bool() const { return Invalid; } + bool isInvalid() const { return Invalid; } private: Sema &SemaRef; @@ -6031,7 +6315,7 @@ public: /// \brief RAII class used to determine whether SFINAE has /// trapped any errors that occur during template argument - /// deduction.` + /// deduction. class SFINAETrap { Sema &SemaRef; unsigned PrevSFINAEErrors; @@ -6063,10 +6347,34 @@ public: } }; + /// \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; @@ -6081,6 +6389,14 @@ public: /// string represents a keyword. UnqualifiedTyposCorrectedMap UnqualifiedTyposCorrected; + 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; @@ -6107,6 +6423,26 @@ public: /// 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, @@ -6240,6 +6576,30 @@ public: 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 = 0, + LocalInstantiationScope *StartingScope = 0); + 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, @@ -6277,6 +6637,10 @@ public: const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); + + void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs, + IdentifierInfo *SuperName, + SourceLocation SuperLoc); Decl *ActOnCompatibilityAlias( SourceLocation AtCompatibilityAliasLoc, @@ -6359,18 +6723,15 @@ public: void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, - const IdentifierInfo *Name); + const IdentifierInfo *Name, + bool OverridingProtocolProperty); void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT, ObjCInterfaceDecl *ID); - void MatchOneProtocolPropertiesInClass(Decl *CDecl, - ObjCProtocolDecl *PDecl); - Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd, - Decl **allMethods = 0, unsigned allNum = 0, - Decl **allProperties = 0, unsigned pNum = 0, - DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0); + ArrayRef<Decl *> allMethods = None, + ArrayRef<DeclGroupPtrTy> allTUVars = None); Decl *ActOnProperty(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, @@ -6584,6 +6945,15 @@ public: 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, @@ -6595,6 +6965,13 @@ public: /// 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); + + /// 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, @@ -6670,16 +7047,79 @@ public: unsigned SpellingListIndex, bool IsPackExpansion); // OpenMP directives and clauses. +private: + void *VarDataSharingAttributesStack; + /// \brief Initialization of data-sharing attributes stack. + void InitDataSharingAttributesStack(); + void DestroyDataSharingAttributesStack(); +public: + /// \brief Called on start of new data sharing attribute block. + void StartOpenMPDSABlock(OpenMPDirectiveKind K, + const DeclarationNameInfo &DirName, + Scope *CurScope); + /// \brief Called on end of data sharing attribute block. + void EndOpenMPDSABlock(Stmt *CurDirective); + // 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, - Scope *CurScope, - ArrayRef<DeclarationNameInfo> IdList); - /// \brief Build a new OpenMPThreadPrivateDecl and check its correctness. + SourceLocation Loc, + ArrayRef<Expr *> VarList); + // \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness. OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl( - SourceLocation Loc, - ArrayRef<DeclRefExpr *> VarList); + SourceLocation Loc, + ArrayRef<Expr *> VarList); + + StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, + 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); + + 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); + + OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind, + ArrayRef<Expr *> Vars, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \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 'shared' clause. + OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -6753,20 +7193,25 @@ public: enum VarArgKind { VAK_Valid, VAK_ValidInCXX11, + VAK_Undefined, 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); + /// GatherArgumentsForCall - Collector argument expressions for various /// form of call prototypes. bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, const FunctionProtoType *Proto, unsigned FirstProtoArg, - Expr **Args, unsigned NumArgs, - SmallVector<Expr *, 8> &AllArgs, + ArrayRef<Expr *> Args, + SmallVectorImpl<Expr *> &AllArgs, VariadicCallType CallType = VariadicDoesNotApply, bool AllowExplicit = false, bool IsListInitialization = false); @@ -6776,10 +7221,6 @@ public: ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl); - /// Checks to see if the given expression is a valid argument to a variadic - /// function, issuing a diagnostic and returning NULL if not. - bool variadicArgumentPODCheck(const Expr *E, VariadicCallType CT); - // 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 @@ -6892,7 +7333,8 @@ public: // this routine performs the default function/array converions. AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, - bool Diagnose = true); + bool Diagnose = true, + bool DiagnoseCFAudited = false); // \brief If the lhs type is a transparent union, check whether we // can initialize the transparent union with the given expression. @@ -7071,7 +7513,8 @@ public: /// retainable pointers and other pointer kinds. ARCConversionResult CheckObjCARCConversion(SourceRange castRange, QualType castType, Expr *&op, - CheckedConversionKind CCK); + CheckedConversionKind CCK, + bool DiagnoseCFAudited = false); Expr *stripARCUnbridgedCast(Expr *e); void diagnoseARCUnbridgedCast(Expr *e); @@ -7098,7 +7541,7 @@ public: /// \param [out] ReturnType - The return type of the send. /// \return true iff there were any incompatible types. bool CheckMessageArgumentTypes(QualType ReceiverType, - Expr **Args, unsigned NumArgs, Selector Sel, + MultiExprArg Args, Selector Sel, ArrayRef<SourceLocation> SelectorLocs, ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, @@ -7186,8 +7629,8 @@ public: /// Returns false on success. /// Can optionally return whether the bit-field is of width 0 ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, - QualType FieldTy, Expr *BitWidth, - bool *ZeroWidth = 0); + QualType FieldTy, bool IsMsStruct, + Expr *BitWidth, bool *ZeroWidth = 0); enum CUDAFunctionTarget { CFT_Device, @@ -7284,9 +7727,10 @@ public: void CodeCompleteNamespaceDecl(Scope *S); void CodeCompleteNamespaceAliasDecl(Scope *S); void CodeCompleteOperatorName(Scope *S); - void CodeCompleteConstructorInitializer(Decl *Constructor, - CXXCtorInitializer** Initializers, - unsigned NumInitializers); + void CodeCompleteConstructorInitializer( + Decl *Constructor, + ArrayRef<CXXCtorInitializer *> Initializers); + void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand); @@ -7301,24 +7745,20 @@ public: bool IsParameter); void CodeCompleteObjCMessageReceiver(Scope *S); void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, + ArrayRef<IdentifierInfo *> SelIdents, bool AtArgumentExpression); void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, + ArrayRef<IdentifierInfo *> SelIdents, bool AtArgumentExpression, bool IsSuper = false); void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, + ArrayRef<IdentifierInfo *> SelIdents, bool AtArgumentExpression, ObjCInterfaceDecl *Super = 0); void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar); void CodeCompleteObjCSelector(Scope *S, - IdentifierInfo **SelIdents, - unsigned NumSelIdents); + ArrayRef<IdentifierInfo *> SelIdents); void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, unsigned NumProtocols); void CodeCompleteObjCProtocolDecl(Scope *S); @@ -7343,8 +7783,7 @@ public: bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnType, - IdentifierInfo **SelIdents, - unsigned NumSelIdents); + ArrayRef<IdentifierInfo *> SelIdents); void CodeCompletePreprocessorDirective(bool InConditional); void CodeCompleteInPreprocessorConditionalExclusion(Scope *S); void CodeCompletePreprocessorMacroName(bool IsDefinition); @@ -7385,8 +7824,9 @@ private: const FunctionProtoType *Proto); bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, ArrayRef<const Expr *> Args); - bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall, - const FunctionProtoType *Proto); + 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, @@ -7401,7 +7841,10 @@ private: bool CheckObjCString(Expr *Arg); ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + + bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); @@ -7411,6 +7854,9 @@ private: 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); @@ -7422,6 +7868,7 @@ private: bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result); +public: enum FormatStringType { FST_Scanf, FST_Printf, @@ -7433,37 +7880,26 @@ private: }; static FormatStringType GetFormatStringType(const FormatAttr *Format); - enum StringLiteralCheckType { - SLCT_NotALiteral, - SLCT_UncheckedLiteral, - SLCT_CheckedLiteral - }; - - StringLiteralCheckType checkFormatStringExpr(const Expr *E, - ArrayRef<const Expr *> Args, - bool HasVAListArg, - unsigned format_idx, - unsigned firstDataArg, - FormatStringType Type, - VariadicCallType CallType, - bool inFunctionCall = true); - 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); + VariadicCallType CallType, + llvm::SmallBitVector &CheckedVarArgs); +private: bool CheckFormatArguments(const FormatAttr *Format, ArrayRef<const Expr *> Args, bool IsCXXMember, VariadicCallType CallType, - SourceLocation Loc, SourceRange Range); + 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); + SourceLocation Loc, SourceRange range, + llvm::SmallBitVector &CheckedVarArgs); void CheckNonNullArguments(const NonNullAttr *NonNull, const Expr * const *ExprArgs, @@ -7536,6 +7972,7 @@ private: Scope *CurScope; mutable IdentifierInfo *Ident_super; + mutable IdentifierInfo *Ident___float128; protected: friend class Parser; @@ -7555,6 +7992,7 @@ public: Scope *getCurScope() const { return CurScope; } IdentifierInfo *getSuperIdentifier() const; + IdentifierInfo *getFloat128Identifier() const; Decl *getObjCDeclContext() const; @@ -7601,6 +8039,18 @@ public: } }; -} // end namespace clang +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/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index 9605bf8..fdf9593 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -16,7 +16,7 @@ namespace clang { namespace diag { enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" #undef DIAG diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index bbf4272..01d4cc9 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -24,7 +24,44 @@ namespace clang { inline PartialDiagnostic Sema::PDiag(unsigned DiagID) { return PartialDiagnostic(DiagID, Context.getDiagAllocator()); } - +
+
+// 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 = 0;
+ return !isa<ParmVarDecl>(Var) &&
+ Var->isUsableInConstantExpressions(Context) &&
+ Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE();
+}
+
+// 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);
+} } #endif diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h new file mode 100644 index 0000000..cf9fff1 --- /dev/null +++ b/include/clang/Sema/SemaLambda.h @@ -0,0 +1,39 @@ +//===--- 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_LAMBDA_H
+#define LLVM_CLANG_SEMA_LAMBDA_H
+#include "clang/AST/ASTLambda.h"
+#include "clang/Sema/ScopeInfo.h"
+namespace clang {
+
+// Given a lambda's call operator and a variable (or null for 'this'),
+// compute the nearest enclosing lambda that is capture-ready (i.e
+// the enclosing context is not dependent, and all intervening lambdas can
+// either implicitly or explicitly capture Var)
+//
+// Return the CallOperator of the capturable lambda and set function scope
+// index to the correct index within the function scope stack to correspond
+// to the capturable lambda.
+// If VarDecl *VD is null, we check for 'this' capture.
+CXXMethodDecl*
+GetInnermostEnclosingCapturableLambda(
+ ArrayRef<sema::FunctionScopeInfo*> FunctionScopes,
+ unsigned &FunctionScopeIndex,
+ DeclContext *const CurContext, VarDecl *VD, Sema &S);
+
+} // clang
+
+#endif // LLVM_CLANG_SEMA_LAMBDA_H
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index f9481c6..1af61d5 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -97,13 +97,6 @@ namespace clang { addOuterTemplateArguments(ArgList(TemplateArgs->data(), TemplateArgs->size())); } - - /// \brief Add a new outmost level to the multi-level template argument - /// list. - void addOuterTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs) { - addOuterTemplateArguments(ArgList(Args, NumArgs)); - } /// \brief Add a new outmost level to the multi-level template argument /// list. @@ -385,6 +378,14 @@ namespace clang { 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) @@ -393,62 +394,39 @@ namespace clang { Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0) { } - // FIXME: Once we get closer to completion, replace these manually-written - // declarations with automatically-generated ones from - // clang/AST/DeclNodes.inc. - Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); - Decl *VisitLabelDecl(LabelDecl *D); - Decl *VisitNamespaceDecl(NamespaceDecl *D); - Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - Decl *VisitTypedefDecl(TypedefDecl *D); - Decl *VisitTypeAliasDecl(TypeAliasDecl *D); - Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); - Decl *VisitVarDecl(VarDecl *D); - Decl *VisitAccessSpecDecl(AccessSpecDecl *D); - Decl *VisitFieldDecl(FieldDecl *D); - Decl *VisitMSPropertyDecl(MSPropertyDecl *D); - Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); - Decl *VisitStaticAssertDecl(StaticAssertDecl *D); - Decl *VisitEnumDecl(EnumDecl *D); - Decl *VisitEnumConstantDecl(EnumConstantDecl *D); - Decl *VisitFriendDecl(FriendDecl *D); - Decl *VisitFunctionDecl(FunctionDecl *D, - TemplateParameterList *TemplateParams = 0); - Decl *VisitCXXRecordDecl(CXXRecordDecl *D); +// 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 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 = 0, + TemplateParameterList *TemplateParams, bool IsClassScopeSpecialization = false); - Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); - Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); - Decl *VisitCXXConversionDecl(CXXConversionDecl *D); - ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D); - Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); - Decl *VisitClassTemplatePartialSpecializationDecl( - ClassTemplatePartialSpecializationDecl *D); - Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); - Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); - Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); - Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); - Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); - Decl *VisitUsingDecl(UsingDecl *D); - Decl *VisitUsingShadowDecl(UsingShadowDecl *D); - Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); - Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); - Decl *VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *D); - Decl *VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); - - // Base case. FIXME: Remove once we can instantiate everything. - Decl *VisitDecl(Decl *D) { - unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID( - DiagnosticsEngine::Error, - "cannot instantiate %0 yet"); - SemaRef.Diag(D->getLocation(), DiagID) - << D->getDeclKindName(); - - return 0; - } - + 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) { @@ -470,6 +448,10 @@ namespace clang { ::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 @@ -478,6 +460,10 @@ namespace clang { 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 @@ -486,6 +472,10 @@ namespace clang { 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); @@ -499,12 +489,21 @@ namespace clang { DeclaratorDecl *NewDecl); bool SubstQualifier(const TagDecl *OldDecl, TagDecl *NewDecl); - + + Decl *VisitVarTemplateSpecializationDecl( + VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos, + const TemplateArgumentListInfo &TemplateArgsInfo, + llvm::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); }; } diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 8292045..1daa689 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -20,6 +20,7 @@ namespace clang { class TemplateArgumentList; +class Sema; namespace sema { @@ -162,7 +163,124 @@ public: Expr *Expression; }; -} -} +} // 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 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); +}; + +/// 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; + + TemplateSpecCandidateSet( + const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; + void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; + + void destroyCandidates(); + +public: + TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {} + ~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.push_back(TemplateSpecCandidate()); + 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 index cdd71c8..f0b7726 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -39,31 +39,35 @@ public: static const unsigned CallbackDistanceWeight = 150U; TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl, - NestedNameSpecifier *NNS=0, unsigned CharDistance=0, - unsigned QualifierDistance=0) + NestedNameSpecifier *NNS = 0, unsigned CharDistance = 0, + unsigned QualifierDistance = 0) : CorrectionName(Name), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(QualifierDistance), - CallbackDistance(0) { + CharDistance(CharDistance), QualifierDistance(QualifierDistance), + CallbackDistance(0), ForceSpecifierReplacement(false), + RequiresImport(false) { if (NameDecl) CorrectionDecls.push_back(NameDecl); } - TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS=0, - unsigned CharDistance=0) + TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = 0, + unsigned CharDistance = 0) : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0) { + CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0), + ForceSpecifierReplacement(false), RequiresImport(false) { if (Name) CorrectionDecls.push_back(Name); } - TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS=0, - unsigned CharDistance=0) + TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = 0, + unsigned CharDistance = 0) : CorrectionName(Name), CorrectionNameSpec(NNS), - CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0) {} + CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0), + ForceSpecifierReplacement(false), RequiresImport(false) {} TypoCorrection() : CorrectionNameSpec(0), CharDistance(0), QualifierDistance(0), - CallbackDistance(0) {} + CallbackDistance(0), ForceSpecifierReplacement(false), + RequiresImport(false) {} /// \brief Gets the DeclarationName of the typo correction DeclarationName getCorrection() const { return CorrectionName; } @@ -77,6 +81,15 @@ public: } void setCorrectionSpecifier(NestedNameSpecifier* NNS) { CorrectionNameSpec = NNS; + ForceSpecifierReplacement = (NNS != 0); + } + + void WillReplaceSpecifier(bool ForceReplacement) { + ForceSpecifierReplacement = ForceReplacement; + } + + bool WillReplaceSpecifier() const { + return ForceSpecifierReplacement; } void setQualifierDistance(unsigned ED) { @@ -116,20 +129,31 @@ public: } /// \brief Gets the pointer to the declaration of the typo correction - NamedDecl* getCorrectionDecl() const { + NamedDecl *getCorrectionDecl() const { return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0; } 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); @@ -140,7 +164,7 @@ public: } /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName - operator bool() const { return bool(CorrectionName); } + LLVM_EXPLICIT operator bool() const { return bool(CorrectionName); } /// \brief Mark this TypoCorrection as being a keyword. /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be @@ -149,6 +173,7 @@ public: void makeKeyword() { CorrectionDecls.clear(); CorrectionDecls.push_back(0); + ForceSpecifierReplacement = true; } // Check if this TypoCorrection is a keyword by checking if the first @@ -171,10 +196,11 @@ public: return CorrectionDecls.size() > 1; } - void setCorrectionRange(CXXScopeSpec* SS, + void setCorrectionRange(CXXScopeSpec *SS, const DeclarationNameInfo &TypoName) { - CorrectionRange.setBegin(CorrectionNameSpec && SS ? SS->getBeginLoc() - : TypoName.getLoc()); + CorrectionRange.setBegin(ForceSpecifierReplacement && SS && !SS->isEmpty() + ? SS->getBeginLoc() + : TypoName.getLoc()); CorrectionRange.setEnd(TypoName.getLoc()); } @@ -182,17 +208,22 @@ public: return CorrectionRange; } - typedef SmallVector<NamedDecl *, 1>::iterator decl_iterator; + typedef SmallVectorImpl<NamedDecl *>::iterator decl_iterator; decl_iterator begin() { return isKeyword() ? CorrectionDecls.end() : CorrectionDecls.begin(); } decl_iterator end() { return CorrectionDecls.end(); } - typedef SmallVector<NamedDecl *, 1>::const_iterator const_decl_iterator; + 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()); @@ -206,12 +237,14 @@ private: 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: +public: static const unsigned InvalidDistance = TypoCorrection::InvalidDistance; CorrectionCandidateCallback() @@ -260,12 +293,42 @@ class CorrectionCandidateCallback { /// to ones having a single Decl* of the given type. template <class C> class DeclFilterCCC : public CorrectionCandidateCallback { - public: +public: virtual bool ValidateCandidate(const TypoCorrection &candidate) { 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); + + virtual bool ValidateCandidate(const TypoCorrection &candidate); + + private: + unsigned NumArgs; + bool HasExplicitTemplateArgs; +}; + +// @brief Callback class that effectively disabled typo correction +class NoTypoCorrectionCCC : public CorrectionCandidateCallback { +public: + NoTypoCorrectionCCC() { + WantTypeSpecifiers = false; + WantExpressionKeywords = false; + WantCXXNamedCasts = false; + WantRemainingKeywords = false; + } + + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + return false; + } +}; + } #endif |