diff options
Diffstat (limited to 'include/clang/Sema')
| -rw-r--r-- | include/clang/Sema/AttributeList.h | 129 | ||||
| -rw-r--r-- | include/clang/Sema/CleanupInfo.h | 47 | ||||
| -rw-r--r-- | include/clang/Sema/CodeCompleteConsumer.h | 6 | ||||
| -rw-r--r-- | include/clang/Sema/DeclSpec.h | 70 | ||||
| -rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 8 | ||||
| -rw-r--r-- | include/clang/Sema/Initialization.h | 21 | ||||
| -rw-r--r-- | include/clang/Sema/LocInfoType.h | 62 | ||||
| -rw-r--r-- | include/clang/Sema/Lookup.h | 71 | ||||
| -rw-r--r-- | include/clang/Sema/Makefile | 39 | ||||
| -rw-r--r-- | include/clang/Sema/MultiplexExternalSemaSource.h | 6 | ||||
| -rw-r--r-- | include/clang/Sema/ObjCMethodList.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/Overload.h | 33 | ||||
| -rw-r--r-- | include/clang/Sema/Ownership.h | 5 | ||||
| -rw-r--r-- | include/clang/Sema/ParsedTemplate.h | 17 | ||||
| -rw-r--r-- | include/clang/Sema/Scope.h | 5 | ||||
| -rw-r--r-- | include/clang/Sema/ScopeInfo.h | 94 | ||||
| -rw-r--r-- | include/clang/Sema/Sema.h | 831 | ||||
| -rw-r--r-- | include/clang/Sema/SemaInternal.h | 12 | ||||
| -rw-r--r-- | include/clang/Sema/SemaLambda.h | 2 | ||||
| -rw-r--r-- | include/clang/Sema/TemplateDeduction.h | 7 |
20 files changed, 997 insertions, 472 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index e32781d35fc73..fcddbecc029cc 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -46,6 +46,28 @@ struct AvailabilityChange { bool isValid() const { return !Version.empty(); } }; +namespace { +enum AvailabilitySlot { + IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots +}; + +/// Describes the trailing object for Availability attribute in AttributeList. +struct AvailabilityData { + AvailabilityChange Changes[NumAvailabilitySlots]; + SourceLocation StrictLoc; + const Expr *Replacement; + AvailabilityData(const AvailabilityChange &Introduced, + const AvailabilityChange &Deprecated, + const AvailabilityChange &Obsoleted, + SourceLocation Strict, const Expr *ReplaceExpr) + : StrictLoc(Strict), Replacement(ReplaceExpr) { + Changes[IntroducedSlot] = Introduced; + Changes[DeprecatedSlot] = Deprecated; + Changes[ObsoletedSlot] = Obsoleted; + } +}; +} + /// \brief Wraps an identifier and optional source location for the identifier. struct IdentifierLoc { SourceLocation Loc; @@ -94,9 +116,11 @@ private: SourceLocation ScopeLoc; SourceLocation EllipsisLoc; + unsigned AttrKind : 16; + /// The number of expression arguments this attribute has. /// The expressions themselves are stored after the object. - unsigned NumArgs : 15; + unsigned NumArgs : 16; /// Corresponds to the Syntax enum. unsigned SyntaxUsed : 3; @@ -122,7 +146,11 @@ private: /// True if this has a ParsedType unsigned HasParsedType : 1; - unsigned AttrKind : 8; + /// True if the processing cache is valid. + mutable unsigned HasProcessingCache : 1; + + /// A cached value. + mutable unsigned ProcessingCache : 8; /// \brief The location of the 'unavailable' keyword in an /// availability attribute. @@ -142,19 +170,13 @@ private: return reinterpret_cast<ArgsUnion const *>(this + 1); } - enum AvailabilitySlot { - IntroducedSlot, DeprecatedSlot, ObsoletedSlot - }; - /// Availability information is stored immediately following the arguments, /// if any, at the end of the object. - AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { - return reinterpret_cast<AvailabilityChange*>(getArgsBuffer() - + NumArgs)[index]; + AvailabilityData *getAvailabilityData() { + return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs); } - const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { - return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() - + NumArgs)[index]; + const AvailabilityData *getAvailabilityData() const { + return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs); } public: @@ -220,7 +242,8 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), - HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) { + HasParsedType(false), HasProcessingCache(false), + NextInPosition(nullptr), NextInPool(nullptr) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -233,18 +256,18 @@ private: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, - Syntax syntaxUsed) + Syntax syntaxUsed, SourceLocation strict, + const Expr *replacementExpr) : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - UnavailableLoc(unavailable), MessageExpr(messageExpr), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), UnavailableLoc(unavailable), + MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) { ArgsUnion PVal(Parm); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); - new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); - new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); - new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); + new (getAvailabilityData()) AvailabilityData( + introduced, deprecated, obsoleted, strict, replacementExpr); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -259,12 +282,11 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { - ArgsVector Args; - Args.push_back(Parm1); - Args.push_back(Parm2); - Args.push_back(Parm3); - memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion)); + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) { + ArgsUnion *Args = getArgsBuffer(); + Args[0] = Parm1; + Args[1] = Parm2; + Args[2] = Parm3; AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -277,7 +299,7 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) { ArgsUnion PVal(ArgKind); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); @@ -295,7 +317,7 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){ new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -309,7 +331,7 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) { new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -361,6 +383,16 @@ public: bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } + bool hasProcessingCache() const { return HasProcessingCache; } + unsigned getProcessingCache() const { + assert(hasProcessingCache()); + return ProcessingCache; + } + void setProcessingCache(unsigned value) const { + ProcessingCache = value; + HasProcessingCache = true; + } + bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } @@ -399,17 +431,22 @@ public: const AvailabilityChange &getAvailabilityIntroduced() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(IntroducedSlot); + return getAvailabilityData()->Changes[IntroducedSlot]; } const AvailabilityChange &getAvailabilityDeprecated() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(DeprecatedSlot); + return getAvailabilityData()->Changes[DeprecatedSlot]; } const AvailabilityChange &getAvailabilityObsoleted() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(ObsoletedSlot); + return getAvailabilityData()->Changes[ObsoletedSlot]; + } + + SourceLocation getStrictLoc() const { + assert(getKind() == AT_Availability && "Not an availability attribute"); + return getAvailabilityData()->StrictLoc; } SourceLocation getUnavailableLoc() const { @@ -422,6 +459,11 @@ public: return MessageExpr; } + const Expr *getReplacementExpr() const { + assert(getKind() == AT_Availability && "Not an availability attribute"); + return getAvailabilityData()->Replacement; + } + const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); @@ -457,6 +499,7 @@ public: bool isTargetSpecificAttr() const; bool isTypeAttr() const; + bool isStmtAttr() const; bool hasCustomParsing() const; unsigned getMinArgs() const; @@ -487,8 +530,7 @@ public: /// which we want to ensure is a multiple of sizeof(void*). AvailabilityAllocSize = sizeof(AttributeList) - + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + - sizeof(ArgsUnion) - 1) + + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*)), TypeTagForDatatypeAllocSize = sizeof(AttributeList) @@ -606,13 +648,14 @@ public: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, - AttributeList::Syntax syntax) { + AttributeList::Syntax syntax, + SourceLocation strict, const Expr *ReplacementExpr) { void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, obsoleted, unavailable, MessageExpr, - syntax)); + syntax, strict, ReplacementExpr)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, @@ -741,10 +784,12 @@ public: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, - AttributeList::Syntax syntax) { + AttributeList::Syntax syntax, + SourceLocation strict, const Expr *ReplacementExpr) { AttributeList *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, - deprecated, obsoleted, unavailable, MessageExpr, syntax); + deprecated, obsoleted, unavailable, MessageExpr, syntax, + strict, ReplacementExpr); add(attr); return attr; } @@ -824,6 +869,7 @@ enum AttributeDeclKind { ExpectedFunction, ExpectedUnion, ExpectedVariableOrFunction, + ExpectedFunctionVariableOrObjCInterface, ExpectedFunctionOrMethod, ExpectedParameter, ExpectedFunctionMethodOrBlock, @@ -833,9 +879,9 @@ enum AttributeDeclKind { ExpectedEnum, ExpectedVariable, ExpectedMethod, - ExpectedVariableFunctionOrLabel, ExpectedFieldOrGlobalVar, ExpectedStruct, + ExpectedParameterOrTypedef, ExpectedVariableOrTypedef, ExpectedTLSVar, ExpectedVariableOrField, @@ -849,13 +895,18 @@ enum AttributeDeclKind { ExpectedObjCInstanceMethod, ExpectedObjCInterfaceDeclInitMethod, ExpectedFunctionVariableOrClass, + ExpectedFunctionVariableClassOrObjCInterface, ExpectedObjectiveCProtocol, ExpectedFunctionGlobalVarMethodOrProperty, ExpectedStructOrUnionOrTypedef, ExpectedStructOrTypedef, ExpectedObjectiveCInterfaceOrProtocol, ExpectedKernelFunction, - ExpectedFunctionWithProtoType + ExpectedFunctionWithProtoType, + ExpectedVariableEnumFieldOrTypedef, + ExpectedFunctionMethodEnumOrClass, + ExpectedStructClassVariableFunctionOrInlineNamespace, + ExpectedForMaybeUnused }; } // end namespace clang diff --git a/include/clang/Sema/CleanupInfo.h b/include/clang/Sema/CleanupInfo.h new file mode 100644 index 0000000000000..751bfb63b4423 --- /dev/null +++ b/include/clang/Sema/CleanupInfo.h @@ -0,0 +1,47 @@ +//===--- CleanupInfo.cpp - Cleanup Control in Sema ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a set of operations on whether generating an +// ExprWithCleanups in a full expression. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_CLEANUP_INFO_H +#define LLVM_CLANG_SEMA_CLEANUP_INFO_H + +namespace clang { + +class CleanupInfo { + bool ExprNeedsCleanups = false; + bool CleanupsHaveSideEffects = false; + +public: + bool exprNeedsCleanups() const { return ExprNeedsCleanups; } + + bool cleanupsHaveSideEffects() const { return CleanupsHaveSideEffects; } + + void setExprNeedsCleanups(bool SideEffects) { + ExprNeedsCleanups = true; + CleanupsHaveSideEffects |= SideEffects; + } + + void reset() { + ExprNeedsCleanups = false; + CleanupsHaveSideEffects = false; + } + + void mergeFrom(CleanupInfo Rhs) { + ExprNeedsCleanups |= Rhs.ExprNeedsCleanups; + CleanupsHaveSideEffects |= Rhs.CleanupsHaveSideEffects; + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 97022738d03ed..014ea5d61dfd1 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -15,6 +15,7 @@ #include "clang-c/Index.h" #include "clang/AST/CanonicalType.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/Type.h" #include "clang/Sema/CodeCompleteOptions.h" #include "llvm/ADT/DenseMap.h" @@ -22,6 +23,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include <string> +#include <utility> namespace clang { @@ -516,8 +518,8 @@ class CodeCompletionTUInfo { public: explicit CodeCompletionTUInfo( - IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator) - : AllocatorRef(Allocator) { } + IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator) + : AllocatorRef(std::move(Allocator)) {} IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const { return AllocatorRef; diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 064d37b2a02bf..afcd791bca294 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -280,6 +280,7 @@ public: static const TST TST_half = clang::TST_half; static const TST TST_float = clang::TST_float; static const TST TST_double = clang::TST_double; + static const TST TST_float128 = clang::TST_float128; static const TST TST_bool = clang::TST_bool; static const TST TST_decimal32 = clang::TST_decimal32; static const TST TST_decimal64 = clang::TST_decimal64; @@ -299,6 +300,9 @@ public: static const TST TST_auto_type = clang::TST_auto_type; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; static const TST TST_atomic = clang::TST_atomic; +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t; +#include "clang/Basic/OpenCLImageTypes.def" static const TST TST_error = clang::TST_error; // type-qualifiers @@ -307,9 +311,10 @@ public: TQ_const = 1, TQ_restrict = 2, TQ_volatile = 4, + TQ_unaligned = 8, // This has no corresponding Qualifiers::TQ value, because it's not treated // as a qualifier in our type system. - TQ_atomic = 8 + TQ_atomic = 16 }; /// ParsedSpecifiers - Flags to query which specifiers were applied. This is @@ -340,7 +345,7 @@ private: unsigned TypeSpecPipe : 1; // type-qualifiers - unsigned TypeQualifiers : 4; // Bitwise OR of TQ. + unsigned TypeQualifiers : 5; // Bitwise OR of TQ. // function-specifier unsigned FS_inline_specified : 1; @@ -382,7 +387,8 @@ private: /// TSTNameLoc provides source range info for tag types. SourceLocation TSTNameLoc; SourceRange TypeofParensRange; - SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; + SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc, + TQ_unalignedLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; SourceLocation FS_forceinlineLoc; SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc, ConceptLoc; @@ -536,6 +542,7 @@ public: SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } + SourceLocation getUnalignedSpecLoc() const { return TQ_unalignedLoc; } SourceLocation getPipeLoc() const { return TQ_pipeLoc; } /// \brief Clear out all of the type qualifiers. @@ -545,6 +552,7 @@ public: TQ_restrictLoc = SourceLocation(); TQ_volatileLoc = SourceLocation(); TQ_atomicLoc = SourceLocation(); + TQ_unalignedLoc = SourceLocation(); TQ_pipeLoc = SourceLocation(); } @@ -785,6 +793,7 @@ public: }; /// PropertyAttributeKind - list of property attributes. + /// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes. enum ObjCPropertyAttributeKind { DQ_PR_noattr = 0x0, DQ_PR_readonly = 0x01, @@ -800,7 +809,8 @@ public: DQ_PR_strong = 0x400, DQ_PR_unsafe_unretained = 0x800, DQ_PR_nullability = 0x1000, - DQ_PR_null_resettable = 0x2000 + DQ_PR_null_resettable = 0x2000, + DQ_PR_class = 0x4000 }; ObjCDeclSpec() @@ -860,7 +870,7 @@ private: ObjCDeclQualifier objcDeclQualifier : 7; // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind - unsigned PropertyAttributes : 14; + unsigned PropertyAttributes : 15; unsigned Nullability : 2; @@ -1109,8 +1119,8 @@ struct DeclaratorChunk { }; struct PointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict/atomic. - unsigned TypeQuals : 4; + /// The type qualifiers: const/volatile/restrict/unaligned/atomic. + unsigned TypeQuals : 5; /// The location of the const-qualifier, if any. unsigned ConstQualLoc; @@ -1124,6 +1134,9 @@ struct DeclaratorChunk { /// The location of the _Atomic-qualifier, if any. unsigned AtomicQualLoc; + /// The location of the __unaligned-qualifier, if any. + unsigned UnalignedQualLoc; + void destroy() { } }; @@ -1138,14 +1151,15 @@ struct DeclaratorChunk { }; struct ArrayTypeInfo : TypeInfoCommon { - /// The type qualifiers for the array: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; + /// The type qualifiers for the array: + /// const/volatile/restrict/__unaligned/_Atomic. + unsigned TypeQuals : 5; /// True if this dimension included the 'static' keyword. - bool hasStatic : 1; + unsigned hasStatic : 1; /// True if this dimension was [*]. In this case, NumElts is null. - bool isStar : 1; + unsigned isStar : 1; /// This is the size of the array, or null if [] or [*] was specified. /// Since the parser is multi-purpose, and we don't want to impose a root @@ -1205,9 +1219,9 @@ struct DeclaratorChunk { /// Otherwise, it's an rvalue reference. unsigned RefQualifierIsLValueRef : 1; - /// The type qualifiers: const/volatile/restrict. + /// The type qualifiers: const/volatile/restrict/__unaligned /// The qualifier bitmask values are the same as in QualType. - unsigned TypeQuals : 3; + unsigned TypeQuals : 4; /// ExceptionSpecType - An ExceptionSpecificationType value. unsigned ExceptionSpecType : 4; @@ -1391,16 +1405,16 @@ struct DeclaratorChunk { struct BlockPointerTypeInfo : TypeInfoCommon { /// For now, sema will catch these as invalid. - /// The type qualifiers: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; + /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. + unsigned TypeQuals : 5; void destroy() { } }; struct MemberPointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; + /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. + unsigned TypeQuals : 5; // CXXScopeSpec has a constructor, so it can't be a direct member. // So we need some pointer-aligned storage and a bit of trickery. union { @@ -1464,7 +1478,8 @@ struct DeclaratorChunk { SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, - SourceLocation AtomicQualLoc) { + SourceLocation AtomicQualLoc, + SourceLocation UnalignedQualLoc) { DeclaratorChunk I; I.Kind = Pointer; I.Loc = Loc; @@ -1473,6 +1488,7 @@ struct DeclaratorChunk { I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding(); I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding(); I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding(); + I.Ptr.UnalignedQualLoc = UnalignedQualLoc.getRawEncoding(); I.Ptr.AttrList = nullptr; return I; } @@ -1551,7 +1567,7 @@ struct DeclaratorChunk { I.Kind = Pipe; I.Loc = Loc; I.Cls.TypeQuals = TypeQuals; - I.Cls.AttrList = 0; + I.Cls.AttrList = nullptr; return I; } @@ -1617,6 +1633,7 @@ public: MemberContext, // Struct/Union field. BlockContext, // Declaration within a block in a function. ForContext, // Declaration within first part of a for loop. + InitStmtContext, // Declaration within optional init stmt of if/switch. ConditionContext, // Condition declaration in a C++ if/switch/while/for. TemplateParamContext,// Within a template parameter list. CXXNewContext, // C++ new-expression. @@ -1648,10 +1665,10 @@ private: SmallVector<DeclaratorChunk, 8> DeclTypeInfo; /// InvalidType - Set by Sema::GetTypeForDeclarator(). - bool InvalidType : 1; + unsigned InvalidType : 1; /// GroupingParens - Set by Parser::ParseParenDeclarator(). - bool GroupingParens : 1; + unsigned GroupingParens : 1; /// FunctionDefinition - Is this Declarator for a function or member /// definition and, if so, what kind? @@ -1660,7 +1677,7 @@ private: unsigned FunctionDefinition : 2; /// \brief Is this Declarator a redeclaration? - bool Redeclaration : 1; + unsigned Redeclaration : 1; /// Attrs - Attributes. ParsedAttributes Attrs; @@ -1795,6 +1812,7 @@ public: case MemberContext: case BlockContext: case ForContext: + case InitStmtContext: case ConditionContext: return false; @@ -1829,6 +1847,7 @@ public: case MemberContext: case BlockContext: case ForContext: + case InitStmtContext: case ConditionContext: case PrototypeContext: case LambdaExprParameterContext: @@ -1862,6 +1881,7 @@ public: case MemberContext: case BlockContext: case ForContext: + case InitStmtContext: case ConditionContext: case PrototypeContext: case LambdaExprParameterContext: @@ -1906,6 +1926,7 @@ public: case FileContext: case BlockContext: case ForContext: + case InitStmtContext: return true; case ConditionContext: @@ -2104,9 +2125,10 @@ public: case FileContext: case MemberContext: case BlockContext: + case ForContext: + case InitStmtContext: return true; - case ForContext: case ConditionContext: case KNRTypeListContext: case TypeNameContext: @@ -2340,4 +2362,4 @@ struct LambdaIntroducer { } // end namespace clang -#endif +#endif // LLVM_CLANG_SEMA_DECLSPEC_H diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 97f78f46a613c..c2b13046d7090 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -70,6 +70,10 @@ public: /// selector. virtual void ReadMethodPool(Selector Sel); + /// Load the contents of the global method pool for a given + /// selector if necessary. + virtual void updateOutOfDateSelector(Selector Sel); + /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. virtual void ReadKnownNamespaces( @@ -77,8 +81,8 @@ public: /// \brief Load the set of used but not defined functions or variables with /// internal linkage, or used but not defined internal functions. - virtual void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined); + virtual void + ReadUndefinedButUsed(llvm::MapVector<NamedDecl *, SourceLocation> &Undefined); virtual void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &); diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index d4f57b701127b..a0bf78bf16881 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -284,9 +284,10 @@ public: /// \brief Create the initialization entity for a base class subobject. - static InitializedEntity InitializeBase(ASTContext &Context, - const CXXBaseSpecifier *Base, - bool IsInheritedVirtualBase); + static InitializedEntity + InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base, + bool IsInheritedVirtualBase, + const InitializedEntity *Parent = nullptr); /// \brief Create the initialization entity for a delegated constructor. static InitializedEntity InitializeDelegation(QualType Type) { @@ -885,14 +886,17 @@ public: /// \param TopLevelOfInitList true if we are initializing from an expression /// at the top level inside an initializer list. This disallows /// narrowing conversions in C++11 onwards. + /// \param TreatUnavailableAsInvalid true if we want to treat unavailable + /// as invalid. InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, - bool TopLevelOfInitList = false); + bool TopLevelOfInitList = false, + bool TreatUnavailableAsInvalid = true); void InitializeFrom(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, - bool TopLevelOfInitList); + bool TopLevelOfInitList, bool TreatUnavailableAsInvalid); ~InitializationSequence(); @@ -948,6 +952,9 @@ public: step_iterator step_begin() const { return Steps.begin(); } step_iterator step_end() const { return Steps.end(); } + typedef llvm::iterator_range<step_iterator> step_range; + step_range steps() const { return {step_begin(), step_end()}; } + /// \brief Determine whether this initialization is a direct reference /// binding (C++ [dcl.init.ref]). bool isDirectReferenceBinding() const; @@ -1042,8 +1049,8 @@ public: /// \param FromInitList The constructor call is syntactically an initializer /// list. /// \param AsInitList The constructor is called as an init list constructor. - void AddConstructorInitializationStep(CXXConstructorDecl *Constructor, - AccessSpecifier Access, + void AddConstructorInitializationStep(DeclAccessPair FoundDecl, + CXXConstructorDecl *Constructor, QualType T, bool HadMultipleCandidates, bool FromInitList, bool AsInitList); diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/Sema/LocInfoType.h deleted file mode 100644 index 63dfa72b8f742..0000000000000 --- a/include/clang/Sema/LocInfoType.h +++ /dev/null @@ -1,62 +0,0 @@ -//===--- LocInfoType.h - Parsed Type with Location Information---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the LocInfoType class, which holds a type and its -// source-location information. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_LOCINFOTYPE_H -#define LLVM_CLANG_SEMA_LOCINFOTYPE_H - -#include "clang/AST/Type.h" - -namespace clang { - -class TypeSourceInfo; - -/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator -/// parsing. -/// -/// LocInfoType is a "transient" type, only needed for passing to/from Parser -/// and Sema, when we want to preserve type source info for a parsed type. -/// It will not participate in the type system semantics in any way. -class LocInfoType : public Type { - enum { - // The last number that can fit in Type's TC. - // Avoids conflict with an existing Type class. - LocInfo = Type::TypeLast + 1 - }; - - TypeSourceInfo *DeclInfo; - - LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isInstantiationDependentType(), - ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { - assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); - } - friend class Sema; - -public: - QualType getType() const { return getCanonicalTypeInternal(); } - TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; } - - void getAsStringInternal(std::string &Str, - const PrintingPolicy &Policy) const; - - static bool classof(const Type *T) { - return T->getTypeClass() == (TypeClass)LocInfo; - } -}; - -} // end namespace clang - -#endif // LLVM_CLANG_SEMA_LOCINFOTYPE_H diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 7efb19f574198..2ed9548b5936a 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -185,6 +185,49 @@ public: Shadowed(false) {} + // FIXME: Remove these deleted methods once the default build includes + // -Wdeprecated. + LookupResult(const LookupResult &) = delete; + LookupResult &operator=(const LookupResult &) = delete; + + LookupResult(LookupResult &&Other) + : ResultKind(std::move(Other.ResultKind)), + Ambiguity(std::move(Other.Ambiguity)), Decls(std::move(Other.Decls)), + Paths(std::move(Other.Paths)), + NamingClass(std::move(Other.NamingClass)), + BaseObjectType(std::move(Other.BaseObjectType)), + SemaPtr(std::move(Other.SemaPtr)), NameInfo(std::move(Other.NameInfo)), + NameContextRange(std::move(Other.NameContextRange)), + LookupKind(std::move(Other.LookupKind)), IDNS(std::move(Other.IDNS)), + Redecl(std::move(Other.Redecl)), HideTags(std::move(Other.HideTags)), + Diagnose(std::move(Other.Diagnose)), + AllowHidden(std::move(Other.AllowHidden)), + Shadowed(std::move(Other.Shadowed)) { + Other.Paths = nullptr; + Other.Diagnose = false; + } + LookupResult &operator=(LookupResult &&Other) { + ResultKind = std::move(Other.ResultKind); + Ambiguity = std::move(Other.Ambiguity); + Decls = std::move(Other.Decls); + Paths = std::move(Other.Paths); + NamingClass = std::move(Other.NamingClass); + BaseObjectType = std::move(Other.BaseObjectType); + SemaPtr = std::move(Other.SemaPtr); + NameInfo = std::move(Other.NameInfo); + NameContextRange = std::move(Other.NameContextRange); + LookupKind = std::move(Other.LookupKind); + IDNS = std::move(Other.IDNS); + Redecl = std::move(Other.Redecl); + HideTags = std::move(Other.HideTags); + Diagnose = std::move(Other.Diagnose); + AllowHidden = std::move(Other.AllowHidden); + Shadowed = std::move(Other.Shadowed); + Other.Paths = nullptr; + Other.Diagnose = false; + return *this; + } + ~LookupResult() { if (Diagnose) diagnose(); if (Paths) deletePaths(Paths); @@ -726,7 +769,13 @@ public: class ADLResult { private: /// A map from canonical decls to the 'most recent' decl. - llvm::DenseMap<NamedDecl*, NamedDecl*> Decls; + llvm::MapVector<NamedDecl*, NamedDecl*> Decls; + + struct select_second { + NamedDecl *operator()(std::pair<NamedDecl*, NamedDecl*> P) const { + return P.second; + } + }; public: /// Adds a new ADL candidate to this map. @@ -737,23 +786,11 @@ public: Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); } - class iterator - : public llvm::iterator_adaptor_base< - iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator, - std::forward_iterator_tag, NamedDecl *> { - friend class ADLResult; - - iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter) - : iterator_adaptor_base(std::move(Iter)) {} - - public: - iterator() {} - - value_type operator*() const { return I->second; } - }; + typedef llvm::mapped_iterator<decltype(Decls)::iterator, select_second> + iterator; - iterator begin() { return iterator(Decls.begin()); } - iterator end() { return iterator(Decls.end()); } + iterator begin() { return iterator(Decls.begin(), select_second()); } + iterator end() { return iterator(Decls.end(), select_second()); } }; } diff --git a/include/clang/Sema/Makefile b/include/clang/Sema/Makefile deleted file mode 100644 index 799f789e0eadd..0000000000000 --- a/include/clang/Sema/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \ - AttrSpellingListIndex.inc AttrParsedAttrImpl.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/AttrTemplateInstantiate.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute template instantiate code with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-template-instantiate -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrList.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute list with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-list -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrKinds.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute kinds with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-kinds -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute spelling list index with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-spelling-index -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute list impl with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-impl -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h index d6daadc89da5f..9bf8cd3d92528 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -203,6 +203,10 @@ public: /// selector. void ReadMethodPool(Selector Sel) override; + /// Load the contents of the global method pool for a given + /// selector if necessary. + void updateOutOfDateSelector(Selector Sel) override; + /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. void @@ -211,7 +215,7 @@ public: /// \brief Load the set of used but not defined functions or variables with /// internal linkage, or used but not defined inline functions. void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override; + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override; void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h index b618e38f88cd4..80ccd363d2725 100644 --- a/include/clang/Sema/ObjCMethodList.h +++ b/include/clang/Sema/ObjCMethodList.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_OBJCMETHODLIST_H #define LLVM_CLANG_SEMA_OBJCMETHODLIST_H +#include "clang/AST/DeclObjC.h" #include "llvm/ADT/PointerIntPair.h" namespace clang { @@ -32,6 +33,9 @@ struct ObjCMethodList { ObjCMethodList() { } ObjCMethodList(ObjCMethodDecl *M) : MethodAndHasMoreThanOneDecl(M, 0) {} + ObjCMethodList(const ObjCMethodList &L) + : MethodAndHasMoreThanOneDecl(L.MethodAndHasMoreThanOneDecl), + NextAndExtraBits(L.NextAndExtraBits) {} ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); } unsigned getBits() const { return NextAndExtraBits.getInt(); } diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 62437953b35b1..d0f21cd71f8d6 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -199,6 +199,7 @@ namespace clang { /// conversions are either identity conversions or derived-to-base /// conversions. CXXConstructorDecl *CopyConstructor; + DeclAccessPair FoundCopyConstructor; void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } void setToType(unsigned Idx, QualType T) { @@ -282,7 +283,7 @@ namespace clang { /// Represents an ambiguous user-defined conversion sequence. struct AmbiguousConversionSequence { - typedef SmallVector<FunctionDecl*, 4> ConversionSet; + typedef SmallVector<std::pair<NamedDecl*, FunctionDecl*>, 4> ConversionSet; void *FromTypePtr; void *ToTypePtr; @@ -305,8 +306,8 @@ namespace clang { return *reinterpret_cast<const ConversionSet*>(Buffer); } - void addConversion(FunctionDecl *D) { - conversions().push_back(D); + void addConversion(NamedDecl *Found, FunctionDecl *D) { + conversions().push_back(std::make_pair(Found, D)); } typedef ConversionSet::iterator iterator; @@ -396,7 +397,7 @@ namespace clang { /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. - bool StdInitializerListElement : 1; + unsigned StdInitializerListElement : 1; void setKind(Kind K) { destruct(); @@ -797,6 +798,30 @@ namespace clang { const OverloadCandidate& Cand2, SourceLocation Loc, bool UserDefinedConversion = false); + + struct ConstructorInfo { + DeclAccessPair FoundDecl; + CXXConstructorDecl *Constructor; + FunctionTemplateDecl *ConstructorTmpl; + explicit operator bool() const { return Constructor; } + }; + // FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload + // that takes one of these. + inline ConstructorInfo getConstructorInfo(NamedDecl *ND) { + if (isa<UsingDecl>(ND)) + return ConstructorInfo{}; + + // For constructors, the access check is performed against the underlying + // declaration, not the found declaration. + auto *D = ND->getUnderlyingDecl(); + ConstructorInfo Info = {DeclAccessPair::make(ND, D->getAccess()), nullptr, + nullptr}; + Info.ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D); + if (Info.ConstructorTmpl) + D = Info.ConstructorTmpl->getTemplatedDecl(); + Info.Constructor = dyn_cast<CXXConstructorDecl>(D); + return Info; + } } // end namespace clang #endif // LLVM_CLANG_SEMA_OVERLOAD_H diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index 8acf9e82bf95a..68d13f97e2e4f 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H #define LLVM_CLANG_SEMA_OWNERSHIP_H +#include "clang/AST/Expr.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" @@ -43,13 +44,13 @@ namespace clang { /// compatible with "Type" pointers for example. template <class PtrTy> class OpaquePtr { - void *Ptr; + void *Ptr = nullptr; explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} typedef llvm::PointerLikeTypeTraits<PtrTy> Traits; public: - OpaquePtr() : Ptr(nullptr) {} + OpaquePtr(std::nullptr_t = nullptr) {} static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index b36425f1be83d..03de9ff6ae44f 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -1,4 +1,4 @@ -//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===// +//===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,12 +11,19 @@ // templates. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TemplateKinds.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Ownership.h" +#include "llvm/ADT/SmallVector.h" #include <cassert> +#include <cstdlib> +#include <new> namespace clang { /// \brief Represents the parsed form of a C++ template argument. @@ -114,8 +121,8 @@ namespace clang { KindType Kind; /// \brief The actual template argument representation, which may be - /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an - /// expression), or an ActionBase::TemplateTy (for a template). + /// an \c Sema::TypeTy* (for a type), an Expr* (for an + /// expression), or an Sema::TemplateTy (for a template). void *Arg; /// \brief The nested-name-specifier that can accompany a template template @@ -209,6 +216,6 @@ namespace clang { /// Retrieves the range of the given template parameter lists. SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams); -} +} // end namespace clang -#endif +#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index dfc6f9c4628f0..d0b006b82ec6e 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_SCOPE_H #define LLVM_CLANG_SEMA_SCOPE_H +#include "clang/AST/Decl.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" @@ -196,6 +197,8 @@ private: /// this scope, or over-defined. The bit is true when over-defined. llvm::PointerIntPair<VarDecl *, 1, bool> NRVO; + void setFlags(Scope *Parent, unsigned F); + public: Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag) : ErrorTrap(Diag) { @@ -205,7 +208,7 @@ public: /// getFlags - Return the flags for this scope. /// unsigned getFlags() const { return Flags; } - void setFlags(unsigned F) { Flags = F; } + void setFlags(unsigned F) { setFlags(getParent(), F); } /// isBlockScope - Return true if this scope correspond to a closure. bool isBlockScope() const { return Flags & BlockScope; } diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index d13667e800707..ee724f7d728c9 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -19,6 +19,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Sema/CleanupInfo.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" @@ -104,6 +105,12 @@ public: /// \brief Whether a statement was dropped because it was invalid. bool HasDroppedStmt : 1; + /// \brief True if current scope is for OpenMP declare reduction combiner. + bool HasOMPDeclareReductionCombiner; + + /// \brief Whether there is a fallthrough statement in this function. + bool HasFallthroughStmt : 1; + /// A flag that is set when parsing a method that must call super's /// implementation, such as \c -dealloc, \c -finalize, or any method marked /// with \c __attribute__((objc_requires_super)). @@ -183,6 +190,7 @@ public: /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) + /// MyClass.foo.prop | +foo (ObjCMethodDecl) | -prop (ObjCPropertyDecl) /// weakVar | 0 (known) | weakVar (VarDecl) /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) /// @@ -341,6 +349,14 @@ public: HasDroppedStmt = true; } + void setHasOMPDeclareReductionCombiner() { + HasOMPDeclareReductionCombiner = true; + } + + void setHasFallthroughStmt() { + HasFallthroughStmt = true; + } + void setHasCXXTry(SourceLocation TryLoc) { setHasBranchProtectedScope(); FirstCXXTryLoc = TryLoc; @@ -363,6 +379,8 @@ public: HasBranchIntoScope(false), HasIndirectGoto(false), HasDroppedStmt(false), + HasOMPDeclareReductionCombiner(false), + HasFallthroughStmt(false), ObjCShouldCallSuper(false), ObjCIsDesignatedInit(false), ObjCWarnForNoDesignatedInitChain(false), @@ -404,19 +422,21 @@ public: // variables of reference type are captured by reference, and other // variables are captured by copy. enum CaptureKind { - Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This + Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA + }; + enum { + IsNestedCapture = 0x1, + IsThisCaptured = 0x2 }; - /// The variable being captured (if we are not capturing 'this') and whether - /// this is a nested capture. - llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested; - + /// this is a nested capture, and whether we are capturing 'this' + llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis; /// Expression to initialize a field of the given type, and the kind of /// capture (if this is a capture and not an init-capture). The expression /// is only required if we are capturing ByVal and the variable's type has /// a non-trivial copy constructor. llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind; - + /// \brief The source location at which the first capture occurred. SourceLocation Loc; @@ -431,27 +451,28 @@ public: Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, Expr *Cpy) - : VarAndNested(Var, IsNested), - InitExprAndCaptureKind(Cpy, Block ? Cap_Block : - ByRef ? Cap_ByRef : Cap_ByCopy), + : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0), + InitExprAndCaptureKind( + Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef + : Cap_ByCopy), Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} enum IsThisCapture { ThisCapture }; Capture(IsThisCapture, bool IsNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy) - : VarAndNested(nullptr, IsNested), - InitExprAndCaptureKind(Cpy, Cap_This), + QualType CaptureType, Expr *Cpy, const bool ByCopy) + : VarAndNestedAndThis( + nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))), + InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef), Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} bool isThisCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_This; + return VarAndNestedAndThis.getInt() & IsThisCaptured; } bool isVariableCapture() const { - return InitExprAndCaptureKind.getInt() != Cap_This && !isVLATypeCapture(); + return !isThisCapture() && !isVLATypeCapture(); } bool isCopyCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy && - !isVLATypeCapture(); + return InitExprAndCaptureKind.getInt() == Cap_ByCopy; } bool isReferenceCapture() const { return InitExprAndCaptureKind.getInt() == Cap_ByRef; @@ -460,13 +481,14 @@ public: return InitExprAndCaptureKind.getInt() == Cap_Block; } bool isVLATypeCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy && - getVariable() == nullptr; + return InitExprAndCaptureKind.getInt() == Cap_VLA; + } + bool isNested() const { + return VarAndNestedAndThis.getInt() & IsNestedCapture; } - bool isNested() const { return VarAndNested.getInt(); } VarDecl *getVariable() const { - return VarAndNested.getPointer(); + return VarAndNestedAndThis.getPointer(); } /// \brief Retrieve the location at which this variable was captured. @@ -479,8 +501,11 @@ public: /// \brief Retrieve the capture type for this capture, which is effectively /// the type of the non-static data member in the lambda/block structure /// that would store this capture. - QualType getCaptureType() const { return CaptureType; } - + QualType getCaptureType() const { + assert(!isThisCapture()); + return CaptureType; + } + Expr *getInitExpr() const { assert(!isVLATypeCapture() && "no init expression for type capture"); return static_cast<Expr *>(InitExprAndCaptureKind.getPointer()); @@ -525,8 +550,11 @@ public: /*Cpy*/ nullptr)); } - void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, - Expr *Cpy); + // Note, we do not need to add the type of 'this' since that is always + // retrievable from Sema::getCurrentThisType - and is also encoded within the + // type of the corresponding FieldDecl. + void addThisCapture(bool isNested, SourceLocation Loc, + Expr *Cpy, bool ByCopy); /// \brief Determine whether the C++ 'this' is captured. bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } @@ -604,14 +632,15 @@ public: /// \brief The implicit parameter for the captured variables. ImplicitParamDecl *ContextParam; /// \brief The kind of captured region. - CapturedRegionKind CapRegionKind; + unsigned short CapRegionKind; + unsigned short OpenMPLevel; CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, RecordDecl *RD, ImplicitParamDecl *Context, - CapturedRegionKind K) + CapturedRegionKind K, unsigned OpenMPLevel) : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), - ContextParam(Context), CapRegionKind(K) + ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) { Kind = SK_CapturedRegion; } @@ -660,7 +689,7 @@ public: bool ExplicitParams; /// \brief Whether any of the capture expressions requires cleanups. - bool ExprNeedsCleanups; + CleanupInfo Cleanup; /// \brief Whether the lambda contains an unexpanded parameter pack. bool ContainsUnexpandedParameterPack; @@ -708,7 +737,7 @@ public: LambdaScopeInfo(DiagnosticsEngine &Diag) : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr), CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false), - ExplicitParams(false), ExprNeedsCleanups(false), + ExplicitParams(false), Cleanup{}, ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr) { Kind = SK_Lambda; @@ -846,9 +875,10 @@ void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { inline void CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy) { - Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, - Cpy)); + Expr *Cpy, + const bool ByCopy) { + Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, QualType(), + Cpy, ByCopy)); CXXThisCaptureIndex = Captures.size(); } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 29aa642a9ab87..25aa805dac4bd 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -16,10 +16,12 @@ #define LLVM_CLANG_SEMA_SEMA_H #include "clang/AST/Attr.h" +#include "clang/AST/Availability.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/LocInfoType.h" #include "clang/AST/MangleNumberingContext.h" #include "clang/AST/NSAPI.h" #include "clang/AST/PrettyPrinter.h" @@ -28,14 +30,15 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" #include "clang/Sema/AnalysisBasedWarnings.h" +#include "clang/Sema/CleanupInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/IdentifierResolver.h" -#include "clang/Sema/LocInfoType.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Ownership.h" #include "clang/Sema/Scope.h" @@ -108,7 +111,6 @@ namespace clang { class EnumConstantDecl; class Expr; class ExtVectorType; - class ExternalSemaSource; class FormatAttr; class FriendDecl; class FunctionDecl; @@ -144,6 +146,8 @@ namespace clang { class ObjCPropertyDecl; class ObjCProtocolDecl; class OMPThreadPrivateDecl; + class OMPDeclareReductionDecl; + class OMPDeclareSimdDecl; class OMPClause; struct OverloadCandidate; class OverloadCandidateSet; @@ -314,50 +318,28 @@ public: /// This is used as part of a hack to omit that class from ADL results. DeclarationName VAListTagName; - /// PackContext - Manages the stack for \#pragma pack. An alignment - /// of 0 indicates default alignment. - void *PackContext; // Really a "PragmaPackStack*" - bool MSStructPragmaOn; // True when \#pragma ms_struct on /// \brief Controls member pointer representation format under the MS ABI. LangOptions::PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod; - enum PragmaVtorDispKind { - PVDK_Push, ///< #pragma vtordisp(push, mode) - PVDK_Set, ///< #pragma vtordisp(mode) - PVDK_Pop, ///< #pragma vtordisp(pop) - PVDK_Reset ///< #pragma vtordisp() - }; - - enum PragmaMsStackAction { - PSK_Reset, // #pragma () - PSK_Set, // #pragma ("name") - PSK_Push, // #pragma (push[, id]) - PSK_Push_Set, // #pragma (push[, id], "name") - PSK_Pop, // #pragma (pop[, id]) - PSK_Pop_Set, // #pragma (pop[, id], "name") - }; - - /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft - /// C++ ABI. Possible values are 0, 1, and 2, which mean: - /// - /// 0: Suppress all vtordisps - /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial - /// structors - /// 2: Always insert vtordisps to support RTTI on partially constructed - /// objects - /// - /// The stack always has at least one element in it. - SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack; - /// Stack of active SEH __finally scopes. Can be empty. SmallVector<Scope*, 2> CurrentSEHFinally; /// \brief Source location for newly created implicit MSInheritanceAttrs SourceLocation ImplicitMSInheritanceAttrLoc; + enum PragmaMsStackAction { + PSK_Reset = 0x0, // #pragma () + PSK_Set = 0x1, // #pragma (value) + PSK_Push = 0x2, // #pragma (push[, id]) + PSK_Pop = 0x4, // #pragma (pop[, id]) + PSK_Show = 0x8, // #pragma (show) -- only for "pack"! + PSK_Push_Set = PSK_Push | PSK_Set, // #pragma (push[, id], value) + PSK_Pop_Set = PSK_Pop | PSK_Set, // #pragma (pop[, id], value) + }; + template<typename ValueType> struct PragmaStack { struct Slot { @@ -374,19 +356,71 @@ public: PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, ValueType Value); - explicit PragmaStack(const ValueType &Value) - : CurrentValue(Value) {} + + // MSVC seems to add artificial slots to #pragma stacks on entering a C++ + // method body to restore the stacks on exit, so it works like this: + // + // struct S { + // #pragma <name>(push, InternalPragmaSlot, <current_pragma_value>) + // void Method {} + // #pragma <name>(pop, InternalPragmaSlot) + // }; + // + // It works even with #pragma vtordisp, although MSVC doesn't support + // #pragma vtordisp(push [, id], n) + // syntax. + // + // Push / pop a named sentinel slot. + void SentinelAction(PragmaMsStackAction Action, StringRef Label) { + assert((Action == PSK_Push || Action == PSK_Pop) && + "Can only push / pop #pragma stack sentinels!"); + Act(CurrentPragmaLocation, Action, Label, CurrentValue); + } + + // Constructors. + explicit PragmaStack(const ValueType &Default) + : DefaultValue(Default), CurrentValue(Default) {} + SmallVector<Slot, 2> Stack; + ValueType DefaultValue; // Value used for PSK_Reset action. ValueType CurrentValue; SourceLocation CurrentPragmaLocation; }; // FIXME: We should serialize / deserialize these if they occur in a PCH (but // we shouldn't do so if they're in a module). + + /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft + /// C++ ABI. Possible values are 0, 1, and 2, which mean: + /// + /// 0: Suppress all vtordisps + /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial + /// structors + /// 2: Always insert vtordisps to support RTTI on partially constructed + /// objects + PragmaStack<MSVtorDispAttr::Mode> VtorDispStack; + // #pragma pack. + // Sentinel to represent when the stack is set to mac68k alignment. + static const unsigned kMac68kAlignmentSentinel = ~0U; + PragmaStack<unsigned> PackStack; + // Segment #pragmas. PragmaStack<StringLiteral *> DataSegStack; PragmaStack<StringLiteral *> BSSSegStack; PragmaStack<StringLiteral *> ConstSegStack; PragmaStack<StringLiteral *> CodeSegStack; + // RAII object to push / pop sentinel slots for all MS #pragma stacks. + // Actions should be performed only if we enter / exit a C++ method body. + class PragmaStackSentinelRAII { + public: + PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct); + ~PragmaStackSentinelRAII(); + + private: + Sema &S; + StringRef SlotLabel; + bool ShouldAct; + }; + /// A mapping that describes the nullability we've seen in each header file. FileNullabilityMap NullabilityMap; @@ -408,9 +442,8 @@ public: /// if Sema is already doing so, which would cause infinite recursions. bool IsBuildingRecoveryCallExpr; - /// ExprNeedsCleanups - True if the current evaluation context - /// requires cleanups to be run at its conclusion. - bool ExprNeedsCleanups; + /// Used to control the generation of ExprWithCleanups. + CleanupInfo Cleanup; /// ExprCleanupObjects - This is the stack of objects requiring /// cleanup that are created by the current full expression. The @@ -765,6 +798,11 @@ public: /// run time. Unevaluated, + /// \brief The current expression occurs within a discarded statement. + /// This behaves largely similarly to an unevaluated operand in preventing + /// definitions from being required, but not in other ways. + DiscardedStatement, + /// \brief The current expression occurs within an unevaluated /// operand that unconditionally permits abstract references to /// fields, such as a SIZE operator in MS-style inline assembly. @@ -798,7 +836,7 @@ public: ExpressionEvaluationContext Context; /// \brief Whether the enclosing context needed a cleanup. - bool ParentNeedsCleanups; + CleanupInfo ParentCleanup; /// \brief Whether we are in a decltype expression. bool IsDecltype; @@ -839,10 +877,10 @@ public: ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, unsigned NumCleanupObjects, - bool ParentNeedsCleanups, + CleanupInfo ParentCleanup, Decl *ManglingContextDecl, bool IsDecltype) - : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), + : Context(Context), ParentCleanup(ParentCleanup), IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), NumTypos(0), ManglingContextDecl(ManglingContextDecl), MangleNumbering() { } @@ -939,7 +977,7 @@ public: /// UndefinedInternals - all the used, undefined objects which require a /// definition in this translation unit. - llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed; + llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed; /// Obtain a sorted list of functions that are undefined but ODR-used. void getUndefinedButUsed( @@ -984,6 +1022,7 @@ public: llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared; void ReadMethodPool(Selector Sel); + void updateOutOfDateSelector(Selector Sel); /// Private Helper predicate to check for 'self'. bool isSelfExpr(Expr *RExpr); @@ -1008,24 +1047,6 @@ public: bool OldFPContractState : 1; }; - /// Records and restores the vtordisp state on entry/exit of C++ method body. - class VtorDispStackRAII { - public: - VtorDispStackRAII(Sema &S, bool ShouldSaveAndRestore) - : S(S), ShouldSaveAndRestore(ShouldSaveAndRestore), OldVtorDispStack() { - if (ShouldSaveAndRestore) - OldVtorDispStack = S.VtorDispModeStack; - } - ~VtorDispStackRAII() { - if (ShouldSaveAndRestore) - S.VtorDispModeStack = OldVtorDispStack; - } - private: - Sema &S; - bool ShouldSaveAndRestore; - SmallVector<MSVtorDispAttr::Mode, 2> OldVtorDispStack; - }; - void addImplicitTypedef(StringRef Name, QualType T); public: @@ -1388,6 +1409,16 @@ public: bool isVisible(const NamedDecl *D) { return !D->isHidden() || isVisibleSlow(D); } + + /// Determine whether any declaration of an entity is visible. + bool + hasVisibleDeclaration(const NamedDecl *D, + llvm::SmallVectorImpl<Module *> *Modules = nullptr) { + return isVisible(D) || hasVisibleDeclarationSlow(D, Modules); + } + bool hasVisibleDeclarationSlow(const NamedDecl *D, + llvm::SmallVectorImpl<Module *> *Modules); + bool hasVisibleMergedDefinition(NamedDecl *Def); /// Determine if \p D has a visible definition. If not, suggest a declaration @@ -1404,6 +1435,11 @@ public: hasVisibleDefaultArgument(const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); + /// Determine if there is a visible declaration of \p D that is a member + /// specialization declaration (as opposed to an instantiated declaration). + bool hasVisibleMemberSpecialization( + const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); + /// Determine if \p A and \p B are equivalent internal linkage declarations /// from different modules, and thus an ambiguity error can be downgraded to /// an extension warning. @@ -1485,9 +1521,8 @@ public: ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS = nullptr, - bool isClassName = false, - bool HasTrailingDot = false, - ParsedType ObjectType = ParsedType(), + bool isClassName = false, bool HasTrailingDot = false, + ParsedType ObjectType = nullptr, bool IsCtorOrDtorName = false, bool WantNontrivialTypeSourceInfo = false, IdentifierInfo **CorrectedII = nullptr); @@ -1500,12 +1535,13 @@ public: ParsedType &SuggestedType, bool AllowClassTemplates = false); - /// \brief For compatibility with MSVC, we delay parsing of some default - /// template type arguments until instantiation time. Emits a warning and - /// returns a synthesized DependentNameType that isn't really dependent on any - /// other template arguments. - ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, - SourceLocation NameLoc); + /// Attempt to behave like MSVC in situations where lookup of an unqualified + /// type name has failed in a dependent context. In these situations, we + /// automatically form a DependentTypeName that will retry lookup in a related + /// scope during instantiation. + ParsedType ActOnMSVCUnknownTypeName(const IdentifierInfo &II, + SourceLocation NameLoc, + bool IsTemplateTypeArg); /// \brief Describes the result of the name lookup and resolution performed /// by \c ClassifyName(). @@ -1645,12 +1681,24 @@ public: SourceLocation ConstQualLoc = SourceLocation(), SourceLocation VolatileQualLoc = SourceLocation(), SourceLocation RestrictQualLoc = SourceLocation(), - SourceLocation AtomicQualLoc = SourceLocation()); + SourceLocation AtomicQualLoc = SourceLocation(), + SourceLocation UnalignedQualLoc = SourceLocation()); static bool adjustContextForLocalExternDecl(DeclContext *&DC); void DiagnoseFunctionSpecifiers(const DeclSpec &DS); void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); void CheckShadow(Scope *S, VarDecl *D); + + /// Warn if 'E', which is an expression that is about to be modified, refers + /// to a shadowing declaration. + void CheckShadowingDeclModification(Expr *E, SourceLocation Loc); + +private: + /// Map of current shadowing declarations to shadowed declarations. Warn if + /// it looks like the user is trying to modify the shadowing declaration. + llvm::DenseMap<const NamedDecl *, const NamedDecl *> ShadowingDecls; + +public: void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); void handleTagNumbering(const TagDecl *Tag, Scope *TagScope); void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, @@ -1772,7 +1820,7 @@ public: Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); Decl *ActOnSkippedFunctionBody(Decl *Decl); - void ActOnFinishInlineMethodDef(CXXMethodDecl *D); + void ActOnFinishInlineFunctionDef(FunctionDecl *D); /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an /// attribute for which parsing is delayed. @@ -1780,16 +1828,14 @@ public: /// \brief Diagnose any unused parameters in the given sequence of /// ParmVarDecl pointers. - void DiagnoseUnusedParameters(ParmVarDecl * const *Begin, - ParmVarDecl * const *End); + void DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters); /// \brief Diagnose whether the size of parameters or return value of a /// function or obj-c method definition is pass-by-value and larger than a /// specified threshold. - void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin, - ParmVarDecl * const *End, - QualType ReturnTy, - NamedDecl *D); + void + DiagnoseSizeOfParametersAndReturnValue(ArrayRef<ParmVarDecl *> Parameters, + QualType ReturnTy, NamedDecl *D); void DiagnoseInvalidJumps(Stmt *Body); Decl *ActOnFileScopeAsmDecl(Expr *expr, @@ -1838,17 +1884,30 @@ public: enum class MissingImportKind { Declaration, Definition, - DefaultArgument + DefaultArgument, + ExplicitSpecialization, + PartialSpecialization }; /// \brief Diagnose that the specified declaration needs to be visible but /// isn't, and suggest a module import that would resolve the problem. void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, - bool NeedDefinition, bool Recover = true); + MissingImportKind MIK, bool Recover = true); void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, SourceLocation DeclLoc, ArrayRef<Module *> Modules, MissingImportKind MIK, bool Recover); + /// \brief We've found a use of a templated declaration that would trigger an + /// implicit instantiation. Check that any relevant explicit specializations + /// and partial specializations are visible, and diagnose if not. + void checkSpecializationVisibility(SourceLocation Loc, NamedDecl *Spec); + + /// \brief We've found a use of a template specialization that would select a + /// partial specialization. Check that the partial specialization is visible, + /// and diagnose if not. + void checkPartialSpecializationVisibility(SourceLocation Loc, + NamedDecl *Spec); + /// \brief Retrieve a suitable printing policy. PrintingPolicy getPrintingPolicy() const { return getPrintingPolicy(Context, PP); @@ -1862,12 +1921,12 @@ public: void ActOnPopScope(SourceLocation Loc, Scope *S); void ActOnTranslationUnitScope(Scope *S); - Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, - DeclSpec &DS); - Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, - DeclSpec &DS, + Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, + RecordDecl *&AnonRecord); + Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, MultiTemplateParamsArg TemplateParams, - bool IsExplicitInstantiation = false); + bool IsExplicitInstantiation, + RecordDecl *&AnonRecord); Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, AccessSpecifier AS, @@ -1981,7 +2040,7 @@ public: /// ActOnTagFinishDefinition - Invoked once we have finished parsing /// the definition of a tag (enumeration, class, struct, or union). void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, - SourceLocation RBraceLoc); + SourceRange BraceRange); void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context); @@ -2018,8 +2077,8 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, AttributeList *Attrs, SourceLocation EqualLoc, Expr *Val); - void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, - SourceLocation RBraceLoc, Decl *EnumDecl, + void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, + Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, AttributeList *Attr); @@ -2104,11 +2163,13 @@ public: /// Attribute merging methods. Return true if a new attribute was added. AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, + bool Implicit, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, + bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex); TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, @@ -2189,7 +2250,8 @@ public: const LookupResult &OldDecls, NamedDecl *&OldDecl, bool IsForUsingDecl); - bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl); + bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl, + bool ConsiderCudaAttrs = true); /// \brief Checks availability of the function depending on the current /// function context.Inside an unavailable function,unavailability is ignored. @@ -2271,7 +2333,8 @@ public: 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. + CCEK_NewExpr, ///< Constant expression in a noptr-new-declarator. + CCEK_ConstexprIf ///< Condition in a constexpr if statement. }; ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); @@ -2383,8 +2446,8 @@ public: // Members have to be NamespaceDecl* or TranslationUnitDecl*. // TODO: make this is a typesafe union. - typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet; - typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet; + typedef llvm::SmallSetVector<DeclContext *, 16> AssociatedNamespaceSet; + typedef llvm::SmallSetVector<CXXRecordDecl *, 16> AssociatedClassSet; void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, @@ -2468,7 +2531,8 @@ public: bool PartialOverloading = false); // Emit as a 'note' the specific overload candidate - void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(), + void NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, + QualType DestType = QualType(), bool TakingAddress = false); // Emit as a series of 'note's all template and non-templates identified by @@ -2505,6 +2569,12 @@ public: bool *pHadMultipleCandidates = nullptr); FunctionDecl * + resolveAddressOfOnlyViableOverloadCandidate(Expr *E, + DeclAccessPair &FoundResult); + + bool resolveAndFixAddressOfOnlyViableOverloadCandidate(ExprResult &SrcExpr); + + FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain = false, DeclAccessPair *Found = nullptr); @@ -2594,8 +2664,7 @@ public: CallExpr *CE, FunctionDecl *FD); /// Helpers for dealing with blocks and functions. - bool CheckParmsForFunctionDef(ParmVarDecl *const *Param, - ParmVarDecl *const *ParamEnd, + bool CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters, bool CheckParameterNames); void CheckCXXDefaultArguments(FunctionDecl *FD); void CheckExtraCXXDefaultArguments(Declarator &D); @@ -2670,6 +2739,8 @@ public: LookupObjCProtocolName, /// Look up implicit 'self' parameter of an objective-c method. LookupObjCImplicitSelfParam, + /// \brief Look up the name of an OpenMP user-defined reduction operation. + LookupOMPReductionName, /// \brief Look up any declaration with any name. LookupAnyName }; @@ -3145,25 +3216,32 @@ private: public: /// \brief - Returns instance or factory methods in global method pool for - /// given selector. If no such method or only one method found, function returns - /// false; otherwise, it returns true - bool CollectMultipleMethodsInGlobalPool(Selector Sel, - SmallVectorImpl<ObjCMethodDecl*>& Methods, - bool instance); + /// given selector. It checks the desired kind first, if none is found, and + /// parameter checkTheOther is set, it then checks the other kind. If no such + /// method or only one method is found, function returns false; otherwise, it + /// returns true. + bool + CollectMultipleMethodsInGlobalPool(Selector Sel, + SmallVectorImpl<ObjCMethodDecl*>& Methods, + bool InstanceFirst, bool CheckTheOther, + const ObjCObjectType *TypeBound = nullptr); - bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, - SourceRange R, - bool receiverIdOrClass); + bool + AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, + SourceRange R, bool receiverIdOrClass, + SmallVectorImpl<ObjCMethodDecl*>& Methods); - void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, - Selector Sel, SourceRange R, - bool receiverIdOrClass); + void + DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, + Selector Sel, SourceRange R, + bool receiverIdOrClass); private: /// \brief - Returns a selector which best matches given argument list or /// nullptr if none could be found ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, - bool IsInstance); + bool IsInstance, + SmallVectorImpl<ObjCMethodDecl*>& Methods); /// \brief Record the typo correction failure and return an empty correction. @@ -3224,6 +3302,7 @@ public: public: class FullExprArg { public: + FullExprArg() : E(nullptr) { } FullExprArg(Sema &actions) : E(nullptr) { } ExprResult release() { @@ -3317,27 +3396,30 @@ public: ArrayRef<const Attr*> Attrs, Stmt *SubStmt); - StmtResult ActOnIfStmt(SourceLocation IfLoc, - FullExprArg CondVal, Decl *CondVar, - Stmt *ThenVal, + class ConditionResult; + StmtResult ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr, + Stmt *InitStmt, + ConditionResult Cond, Stmt *ThenVal, + SourceLocation ElseLoc, Stmt *ElseVal); + StmtResult BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, + Stmt *InitStmt, + ConditionResult Cond, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal); StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, - Expr *Cond, - Decl *CondVar); + Stmt *InitStmt, + ConditionResult Cond); StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body); - StmtResult ActOnWhileStmt(SourceLocation WhileLoc, - FullExprArg Cond, - Decl *CondVar, Stmt *Body); + StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, + Stmt *Body); StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, - SourceLocation WhileLoc, - SourceLocation CondLParen, Expr *Cond, - SourceLocation CondRParen); + SourceLocation WhileLoc, SourceLocation CondLParen, + Expr *Cond, SourceLocation CondRParen); StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, - Stmt *First, FullExprArg Second, - Decl *SecondVar, + Stmt *First, + ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body); @@ -3368,7 +3450,7 @@ public: StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, SourceLocation ColonLoc, - Stmt *RangeDecl, Stmt *BeginEndDecl, + Stmt *RangeDecl, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, @@ -3396,9 +3478,9 @@ public: SourceLocation Loc, unsigned NumParams); VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, - bool AllowFunctionParameters); + bool AllowParamOrMoveConstructible); bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, - bool AllowFunctionParameters); + bool AllowParamOrMoveConstructible); StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope); @@ -3551,11 +3633,12 @@ public: //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. - bool CanUseDecl(NamedDecl *D); + bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid); bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false); void NoteDeletedFunction(FunctionDecl *FD); + void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD); std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, @@ -3585,9 +3668,15 @@ public: // for expressions referring to a decl; these exist because odr-use marking // needs to be delayed for some constant variables when we build one of the // named expressions. - void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse); + // + // MightBeOdrUse indicates whether the use could possibly be an odr-use, and + // should usually be true. This only needs to be set to false if the lack of + // odr-use cannot be determined from the current context (for instance, + // because the name denotes a virtual function and was written without an + // explicit nested-name-specifier). + void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse); void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, - bool OdrUse = true); + bool MightBeOdrUse = true); void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); void MarkDeclRefReferenced(DeclRefExpr *E); void MarkMemberReferenced(MemberExpr *E); @@ -3970,6 +4059,8 @@ public: ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); + void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc); + /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null /// in the case of a the GNU conditional expr extension. ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, @@ -4170,6 +4261,13 @@ public: bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); + /// Given a derived-class using shadow declaration for a constructor and the + /// correspnding base class constructor, find or create the implicit + /// synthesized derived class constructor to use for this initialization. + CXXConstructorDecl * + findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor, + ConstructorUsingShadowDecl *DerivedShadow); + Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, bool HasUsingKeyword, @@ -4194,16 +4292,29 @@ public: /// \param ConstructKind - a CXXConstructExpr::ConstructionKind ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, + NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, bool IsStdInitListInitialization, bool RequiresZeroInit, unsigned ConstructKind, SourceRange ParenRange); + /// Build a CXXConstructExpr whose constructor has already been resolved if + /// it denotes an inherited constructor. + ExprResult + BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, + CXXConstructorDecl *Constructor, bool Elidable, + MultiExprArg Exprs, + bool HadMultipleCandidates, bool IsListInitialization, + bool IsStdInitListInitialization, + bool RequiresZeroInit, unsigned ConstructKind, + SourceRange ParenRange); + // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if // the constructor can be elidable? ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, + NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, bool Elidable, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, @@ -4323,7 +4434,8 @@ public: /// \brief Determine what sort of exception specification an inheriting /// constructor of a class will have. ImplicitExceptionSpecification - ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD); + ComputeInheritingCtorExceptionSpec(SourceLocation Loc, + CXXConstructorDecl *CD); /// \brief Evaluate the implicit exception specification for a defaulted /// special member function. @@ -4353,9 +4465,12 @@ public: ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr); + class InheritedConstructorInfo; + /// \brief Determine if a special member function should have a deleted /// definition when it is defaulted. bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, + InheritedConstructorInfo *ICI = nullptr, bool Diagnose = false); /// \brief Declare the implicit default constructor for the given class. @@ -4392,12 +4507,6 @@ public: void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, CXXDestructorDecl *Destructor); - /// \brief Declare all inheriting constructors for the given class. - /// - /// \param ClassDecl The class declaration into which the inheriting - /// constructors will be added. - void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl); - /// \brief Define the specified inheriting constructor. void DefineInheritingConstructor(SourceLocation UseLoc, CXXConstructorDecl *Constructor); @@ -4458,6 +4567,9 @@ public: /// class. void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class); + /// \brief Check a completed declaration of an implicit special member. + void CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD); + /// \brief Determine whether the given function is an implicitly-deleted /// special member function. bool isImplicitlyDeleted(FunctionDecl *FD); @@ -4613,7 +4725,8 @@ public: /// \return returns 'true' if failed, 'false' if success. bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, bool BuildAndDiagnose = true, - const unsigned *const FunctionScopeIndexToStopAt = nullptr); + const unsigned *const FunctionScopeIndexToStopAt = nullptr, + bool ByCopy = false); /// \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 @@ -4627,6 +4740,10 @@ public: /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); + ExprResult + ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef<AvailabilitySpec> AvailSpecs, + SourceLocation AtLoc, SourceLocation RParen); + /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); @@ -4684,8 +4801,7 @@ public: void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, QualType Param1, - QualType Param2 = QualType(), - bool addRestrictAttr = false); + QualType Param2 = QualType()); bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl* &Operator, @@ -4698,11 +4814,10 @@ public: ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand); - - DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); - ExprResult CheckConditionVariable(VarDecl *ConditionVar, - SourceLocation StmtLoc, - bool ConvertToBoolean); + void CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, + bool IsDelete, bool CallCanBeVirtual, + bool WarnOnNonAbstractTypes, + SourceLocation DtorLoc); ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, Expr *Operand, SourceLocation RParen); @@ -4781,6 +4896,10 @@ public: Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); + MaterializeTemporaryExpr * + CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, + bool BoundToLvalueReference); + ExprResult ActOnFinishFullExpr(Expr *Expr) { return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() : SourceLocation()); @@ -4992,7 +5111,8 @@ public: SourceRange IntroducerRange, TypeSourceInfo *MethodType, SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params); + ArrayRef<ParmVarDecl *> Params, + bool IsConstexprSpecified); /// \brief Endow the lambda scope info with the relevant properties. void buildLambdaScope(sema::LambdaScopeInfo *LSI, @@ -5289,11 +5409,18 @@ public: ArrayRef<CXXCtorInitializer*> MemInits, bool AnyErrors); + /// \brief Check class-level dllimport/dllexport attribute. The caller must + /// ensure that referenceDLLExportedClassMethods is called some point later + /// when all outer classes of Class are complete. void checkClassLevelDLLAttribute(CXXRecordDecl *Class); + + void referenceDLLExportedClassMethods(); + void propagateDLLAttrToBaseClassTemplate( CXXRecordDecl *Class, Attr *ClassAttr, ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc); + void CheckCompletedCXXClass(CXXRecordDecl *Record); void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, Decl *TagDecl, @@ -5449,13 +5576,13 @@ public: bool Diagnose = true); AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, + DeclAccessPair FoundDecl, const InitializedEntity &Entity, - AccessSpecifier Access, bool IsCopyBindingRefToTemp = false); AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, + DeclAccessPair FoundDecl, const InitializedEntity &Entity, - AccessSpecifier Access, const PartialDiagnostic &PDiag); AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, @@ -5588,7 +5715,8 @@ public: SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef<Decl *> Params, - SourceLocation RAngleLoc); + SourceLocation RAngleLoc, + Expr *RequiresClause); /// \brief The context in which we are checking a template parameter list. enum TemplateParamListContext { @@ -6540,6 +6668,10 @@ public: /// \brief The number of template arguments in TemplateArgs. unsigned NumTemplateArgs; + ArrayRef<TemplateArgument> template_arguments() const { + return {TemplateArgs, NumTemplateArgs}; + } + /// \brief The template deduction info object associated with the /// substitution or checking of explicit or deduced template arguments. sema::TemplateDeductionInfo *DeductionInfo; @@ -6614,6 +6746,10 @@ public: /// template defined within it. llvm::DenseSet<Module*> &getLookupModules(); + /// \brief Map from the most recent declaration of a namespace to the most + /// recent visible declaration of that namespace. + llvm::DenseMap<NamedDecl*, NamedDecl*> VisibleNamespaceCache; + /// \brief Whether we are in a SFINAE context that is not associated with /// template instantiation. /// @@ -6965,6 +7101,33 @@ public: SavedPendingLocalImplicitInstantiations; }; + /// A helper class for building up ExtParameterInfos. + class ExtParameterInfoBuilder { + SmallVector<FunctionProtoType::ExtParameterInfo, 16> Infos; + bool HasInteresting = false; + + public: + /// Set the ExtParameterInfo for the parameter at the given index, + /// + void set(unsigned index, FunctionProtoType::ExtParameterInfo info) { + assert(Infos.size() <= index); + Infos.resize(index); + Infos.push_back(info); + + if (!HasInteresting) + HasInteresting = (info != FunctionProtoType::ExtParameterInfo()); + } + + /// Return a pointer (suitable for setting in an ExtProtoInfo) to the + /// ExtParameterInfo array we've built up. + const FunctionProtoType::ExtParameterInfo * + getPointerOrNull(unsigned numParams) { + if (!HasInteresting) return nullptr; + Infos.resize(numParams); + return Infos.data(); + } + }; + void PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, @@ -6992,11 +7155,12 @@ public: int indexAdjustment, Optional<unsigned> NumExpansions, bool ExpectParameterPack); - bool SubstParmTypes(SourceLocation Loc, - ParmVarDecl **Params, unsigned NumParams, + bool SubstParmTypes(SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, + const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl<QualType> &ParamTypes, - SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr); + SmallVectorImpl<ParmVarDecl *> *OutParams, + ExtParameterInfoBuilder &ParamInfos); ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -7101,7 +7265,8 @@ public: void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive = false, - bool DefinitionRequired = false); + bool DefinitionRequired = false, + bool AtEndOfTU = false); VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( VarTemplateDecl *VarTemplate, VarDecl *FromVar, const TemplateArgumentList &TemplateArgList, @@ -7125,7 +7290,8 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs); void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarDecl *Var, bool Recursive = false, - bool DefinitionRequired = false); + bool DefinitionRequired = false, + bool AtEndOfTU = false); void InstantiateStaticDataMemberDefinition( SourceLocation PointOfInstantiation, VarDecl *Var, @@ -7254,6 +7420,12 @@ public: ArrayRef<IdentifierLocPair> ProtocolId, SmallVectorImpl<Decl *> &Protocols); + void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, + SourceLocation ProtocolLoc, + IdentifierInfo *TypeArgId, + SourceLocation TypeArgLoc, + bool SelectProtocolFirst = false); + /// Given a list of identifiers (and their locations), resolve the /// names to either Objective-C protocol qualifiers or type /// arguments, as appropriate. @@ -7348,7 +7520,8 @@ public: bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, - SourceLocation PropertyIvarLoc); + SourceLocation PropertyIvarLoc, + ObjCPropertyQueryKind QueryKind); enum ObjCSpecialMethodKind { OSMK_None, @@ -7556,41 +7729,17 @@ public: void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc); - enum PragmaPackKind { - PPK_Default, // #pragma pack([n]) - PPK_Show, // #pragma pack(show), only supported by MSVC. - PPK_Push, // #pragma pack(push, [identifier], [n]) - PPK_Pop // #pragma pack(pop, [identifier], [n]) - }; - - enum PragmaMSStructKind { - PMSST_OFF, // #pragms ms_struct off - PMSST_ON // #pragms ms_struct on - }; - - enum PragmaMSCommentKind { - PCK_Unknown, - PCK_Linker, // #pragma comment(linker, ...) - PCK_Lib, // #pragma comment(lib, ...) - PCK_Compiler, // #pragma comment(compiler, ...) - PCK_ExeStr, // #pragma comment(exestr, ...) - PCK_User // #pragma comment(user, ...) - }; - /// ActOnPragmaPack - Called on well formed \#pragma pack(...). - void ActOnPragmaPack(PragmaPackKind Kind, - IdentifierInfo *Name, - Expr *Alignment, - SourceLocation PragmaLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc); + void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, + StringRef SlotLabel, Expr *Alignment); /// 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); + void ActOnPragmaMSComment(SourceLocation CommentLoc, PragmaMSCommentKind Kind, + StringRef Arg); /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma /// pointers_to_members(representation method[, general purpose @@ -7600,7 +7749,8 @@ public: SourceLocation PragmaLoc); /// \brief Called on well formed \#pragma vtordisp(). - void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc, + void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, + SourceLocation PragmaLoc, MSVtorDispAttr::Mode Value); enum PragmaSectionKind { @@ -7636,7 +7786,8 @@ public: void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II); /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch - void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value); + void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, + StringRef Value); /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, @@ -7746,6 +7897,17 @@ public: void AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, Expr *MinBlocks, unsigned SpellingListIndex); + /// AddModeAttr - Adds a mode attribute to a particular declaration. + void AddModeAttr(SourceRange AttrRange, Decl *D, IdentifierInfo *Name, + unsigned SpellingListIndex, bool InInstantiation = false); + + void AddParameterABIAttr(SourceRange AttrRange, Decl *D, + ParameterABI ABI, unsigned SpellingListIndex); + + void AddNSConsumedAttr(SourceRange AttrRange, Decl *D, + unsigned SpellingListIndex, bool isNSConsumed, + bool isTemplateInstantiation); + //===--------------------------------------------------------------------===// // C++ Coroutines TS // @@ -7764,34 +7926,40 @@ public: // private: void *VarDataSharingAttributesStack; + /// Set to true inside '#pragma omp declare target' region. + bool IsInOpenMPDeclareTargetContext = false; /// \brief Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, bool StrictlyPositive = true); + /// Returns OpenMP nesting level for current directive. + unsigned getOpenMPNestingLevel() const; public: /// \brief Return true if the provided declaration \a VD should be captured by - /// reference in the provided scope \a RSI. This will take into account the - /// semantics of the directive and associated clauses. - bool IsOpenMPCapturedByRef(VarDecl *VD, - const sema::CapturedRegionScopeInfo *RSI); + /// reference. + /// \param Level Relative level of nested OpenMP construct for that the check + /// is performed. + bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level); /// \brief Check if the specified variable is used in one of the private /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP /// constructs. - bool IsOpenMPCapturedVar(VarDecl *VD); + VarDecl *IsOpenMPCapturedDecl(ValueDecl *D); + ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, + ExprObjectKind OK, SourceLocation Loc); /// \brief Check if the specified variable is used in 'private' clause. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. - bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level); + bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level); /// \brief Check if the specified variable is captured by 'target' directive. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. - bool isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level); + bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level); ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op); @@ -7826,6 +7994,42 @@ public: OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl( SourceLocation Loc, ArrayRef<Expr *> VarList); + /// \brief Check if the specified type is allowed to be used in 'omp declare + /// reduction' construct. + QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, + TypeResult ParsedType); + /// \brief Called on start of '#pragma omp declare reduction'. + DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart( + Scope *S, DeclContext *DC, DeclarationName Name, + ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, + AccessSpecifier AS, Decl *PrevDeclInScope = nullptr); + /// \brief Initialize declare reduction construct initializer. + void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D); + /// \brief Finish current declare reduction construct initializer. + void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner); + /// \brief Initialize declare reduction construct initializer. + void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D); + /// \brief Finish current declare reduction construct initializer. + void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer); + /// \brief Called at the end of '#pragma omp declare reduction'. + DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd( + Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid); + + /// Called on the start of target region i.e. '#pragma omp declare target'. + bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc); + /// Called at the end of target region i.e. '#pragme omp end declare target'. + void ActOnFinishOpenMPDeclareTargetDirective(); + /// Called on correct id-expression from the '#pragma omp declare target'. + void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, + const DeclarationNameInfo &Id, + OMPDeclareTargetDeclAttr::MapTypeTy MT, + NamedDeclSetType &SameDirectiveDecls); + /// Check declaration inside target region. + void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D); + /// Return true inside OpenMP target region. + bool isInOpenMPDeclareTargetContext() const { + return IsInOpenMPDeclareTargetContext; + } /// \brief Initialization of captured region for OpenMP region. void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); @@ -7851,19 +8055,19 @@ public: StmtResult ActOnOpenMPSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp for' after parsing /// of the associated statement. StmtResult ActOnOpenMPForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp for simd' after parsing /// of the associated statement. StmtResult ActOnOpenMPForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp sections' after parsing /// of the associated statement. StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7893,13 +8097,13 @@ public: StmtResult ActOnOpenMPParallelForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel for simd' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel sections' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7947,6 +8151,28 @@ public: StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target enter data' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target exit data' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target parallel' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target parallel for' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetParallelForDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp teams' after parsing of the /// associated statement. StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, @@ -7967,19 +8193,63 @@ public: StmtResult ActOnOpenMPTaskLoopDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp taskloop simd' after parsing of /// the associated statement. StmtResult ActOnOpenMPTaskLoopSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp distribute' after parsing /// of the associated statement. StmtResult ActOnOpenMPDistributeDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp target update'. + StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp distribute parallel for' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPDistributeParallelForDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp distribute parallel for simd' + /// after parsing of the associated statement. + StmtResult ActOnOpenMPDistributeParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp distribute simd' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPDistributeSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp target parallel for simd' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + + /// Checks correctness of linear modifiers. + bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, + SourceLocation LinLoc); + /// Checks that the specified declaration matches requirements for the linear + /// decls. + bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, + OpenMPLinearClauseKind LinKind, QualType Type); + + /// \brief Called on well-formed '\#pragma omp declare simd' after parsing of + /// the associated method/function. + DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective( + DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, + Expr *Simdlen, ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, + ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, + ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, @@ -8108,7 +8378,8 @@ public: CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, - OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc); + OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, + SourceLocation DepLinMapLoc); /// \brief Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -8130,12 +8401,12 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'reduction' clause. - OMPClause * - ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation ColonLoc, - SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId); + OMPClause *ActOnOpenMPReductionClause( + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, + CXXScopeSpec &ReductionIdScopeSpec, + const DeclarationNameInfo &ReductionId, + ArrayRef<Expr *> UnresolvedReductions = llvm::None); /// \brief Called on well-formed 'linear' clause. OMPClause * ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, @@ -8175,10 +8446,12 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'map' clause. - OMPClause *ActOnOpenMPMapClause( - OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, - SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + OMPClause * + ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, + SourceLocation MapLoc, SourceLocation ColonLoc, + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'num_teams' clause. OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -8192,6 +8465,36 @@ public: OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'dist_schedule' clause. + OMPClause *ActOnOpenMPDistScheduleClause( + OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, + SourceLocation CommaLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'defaultmap' clause. + OMPClause *ActOnOpenMPDefaultmapClause( + OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, + SourceLocation KindLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'to' clause. + OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'from' clause. + OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// Called on well-formed 'use_device_ptr' clause. + OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// Called on well-formed 'is_device_ptr' clause. + OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -8609,7 +8912,7 @@ public: Expr *CastExpr, SourceLocation RParenLoc); - enum ARCConversionResult { ACR_okay, ACR_unbridged }; + enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; /// \brief Checks for invalid conversions and casts between /// retainable pointers and other pointer kinds. @@ -8670,6 +8973,60 @@ public: /// type, and if so, emit a note describing what happened. void EmitRelatedResultTypeNoteForReturn(QualType destType); + class ConditionResult { + Decl *ConditionVar; + FullExprArg Condition; + bool Invalid; + bool HasKnownValue; + bool KnownValue; + + friend class Sema; + ConditionResult(Sema &S, Decl *ConditionVar, FullExprArg Condition, + bool IsConstexpr) + : ConditionVar(ConditionVar), Condition(Condition), Invalid(false), + HasKnownValue(IsConstexpr && Condition.get() && + !Condition.get()->isValueDependent()), + KnownValue(HasKnownValue && + !!Condition.get()->EvaluateKnownConstInt(S.Context)) {} + explicit ConditionResult(bool Invalid) + : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid), + HasKnownValue(false), KnownValue(false) {} + + public: + ConditionResult() : ConditionResult(false) {} + bool isInvalid() const { return Invalid; } + std::pair<VarDecl *, Expr *> get() const { + return std::make_pair(cast_or_null<VarDecl>(ConditionVar), + Condition.get()); + } + llvm::Optional<bool> getKnownValue() const { + if (!HasKnownValue) + return None; + return KnownValue; + } + }; + static ConditionResult ConditionError() { return ConditionResult(true); } + + enum class ConditionKind { + Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'. + ConstexprIf, ///< A constant boolean condition from 'if constexpr'. + Switch ///< An integral condition for a 'switch' statement. + }; + + ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, + Expr *SubExpr, ConditionKind CK); + + ConditionResult ActOnConditionVariable(Decl *ConditionVar, + SourceLocation StmtLoc, + ConditionKind CK); + + DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); + + ExprResult CheckConditionVariable(VarDecl *ConditionVar, + SourceLocation StmtLoc, + ConditionKind CK); + ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond); + /// CheckBooleanCondition - Diagnose problems involving the use of /// the given expression as a boolean condition (e.g. in an if /// statement). Also performs the standard function and array @@ -8678,10 +9035,8 @@ public: /// \param Loc - A location associated with the condition, e.g. the /// 'if' keyword. /// \return true iff there were any errors - ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc); - - ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr); + ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, + bool IsConstexpr = false); /// DiagnoseAssignmentAsCondition - Given that an expression is /// being used as a boolean condition, warn if it's an assignment. @@ -8692,7 +9047,7 @@ public: void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE); /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. - ExprResult CheckCXXBooleanCondition(Expr *CondExpr); + ExprResult CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr = false); /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have /// the specified width and sign. If an overflow occurs, detect it and emit @@ -8749,12 +9104,18 @@ public: CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); + // CUDA function call preference. Must be ordered numerically from + // worst to best. enum CUDAFunctionPreference { CFP_Never, // Invalid caller/callee combination. - CFP_LastResort, // Lowest priority. Only in effect if + CFP_WrongSide, // Calls from host-device to host or device + // function that do not match current compilation + // mode. Only in effect if // LangOpts.CUDADisableTargetCallChecks is true. - CFP_Fallback, // Low priority caller/callee combination - CFP_Best, // Preferred caller/callee combination + CFP_HostDevice, // Any calls to host/device functions. + CFP_SameSide, // Calls from host-device to host or device + // function matching current compilation mode. + CFP_Native, // host-to-host or device-to-device calls. }; /// Identifies relative preference of a given Caller/Callee @@ -8767,7 +9128,16 @@ public: CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller, const FunctionDecl *Callee); - bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee); + /// Determines whether Caller may invoke Callee, based on their CUDA + /// host/device attributes. Returns true if the call is not allowed. + bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) { + return IdentifyCUDAPreference(Caller, Callee) == CFP_Never; + } + + /// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, + /// depending on FD and the current compilation settings. + void maybeAddCUDAHostDeviceAttrs(Scope *S, FunctionDecl *FD, + const LookupResult &Previous); /// Finds a function in \p Matches with highest calling priority /// from \p Caller context and erases all functions with lower @@ -8797,6 +9167,11 @@ public: bool ConstRHS, bool Diagnose); + /// \return true if \p CD can be considered empty according to CUDA + /// (E.2.3.1 in CUDA 7.5 Programming guide). + bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD); + bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD); + /// \name Code completion //@{ /// \brief Describes the context in which code completion occurs. @@ -8861,6 +9236,7 @@ public: void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); + void CodeCompleteBracketDeclarator(Scope *S); void CodeCompleteCase(Scope *S); void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args); void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, @@ -9048,13 +9424,6 @@ public: }; static FormatStringType GetFormatStringType(const FormatAttr *Format); - void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr, - ArrayRef<const Expr *> Args, bool HasVAListArg, - unsigned format_idx, unsigned firstDataArg, - FormatStringType Type, bool inFunctionCall, - VariadicCallType CallType, - llvm::SmallBitVector &CheckedVarArgs); - bool FormatStringHasSArg(const StringLiteral *FExpr); static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); @@ -9237,15 +9606,18 @@ public: /// \brief RAII object that enters a new expression evaluation context. class EnterExpressionEvaluationContext { Sema &Actions; + bool Entered = true; public: EnterExpressionEvaluationContext(Sema &Actions, Sema::ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr, - bool IsDecltype = false) - : Actions(Actions) { - Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, - IsDecltype); + bool IsDecltype = false, + bool ShouldEnter = true) + : Actions(Actions), Entered(ShouldEnter) { + if (Entered) + Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, + IsDecltype); } EnterExpressionEvaluationContext(Sema &Actions, Sema::ExpressionEvaluationContext NewContext, @@ -9258,7 +9630,8 @@ public: } ~EnterExpressionEvaluationContext() { - Actions.PopExpressionEvaluationContext(); + if (Entered) + Actions.PopExpressionEvaluationContext(); } }; diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index 60c6598287b7d..76567f3b77f40 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -73,10 +73,11 @@ inline void MarkVarDeclODRUsed(VarDecl *Var, // 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; + (!Var->isExternallyVisible() || Var->isInline()) && + !(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, @@ -216,6 +217,9 @@ public: bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; } const CXXScopeSpec *getSS() const { return SS.get(); } Scope *getScope() const { return S; } + CorrectionCandidateCallback *getCorrectionValidator() const { + return CorrectionValidator.get(); + } private: class NamespaceSpecifierSet { diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h index d043e2c459b3c..df40b134f0a7d 100644 --- a/include/clang/Sema/SemaLambda.h +++ b/include/clang/Sema/SemaLambda.h @@ -18,7 +18,7 @@ #include "clang/AST/ASTLambda.h" #include "clang/Sema/ScopeInfo.h" namespace clang { - +class Sema; /// \brief Examines the FunctionScopeInfo stack to determine the nearest /// enclosing lambda (to the current lambda) that is 'capture-capable' for diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index c22c703ef7322..ed1e768832cce 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -244,6 +244,10 @@ struct DeductionFailureInfo { /// TODO: In the future, we may need to unify/generalize this with /// OverloadCandidate. struct TemplateSpecCandidate { + /// \brief The declaration that was looked up, together with its access. + /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl. + DeclAccessPair FoundDecl; + /// Specialization - The actual specialization that this candidate /// represents. When NULL, this may be a built-in candidate. Decl *Specialization; @@ -251,7 +255,8 @@ struct TemplateSpecCandidate { /// Template argument deduction info DeductionFailureInfo DeductionFailure; - void set(Decl *Spec, DeductionFailureInfo Info) { + void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) { + FoundDecl = Found; Specialization = Spec; DeductionFailure = Info; } |
