diff options
Diffstat (limited to 'include/clang/Sema')
-rw-r--r-- | include/clang/Sema/AttributeList.h | 373 | ||||
-rw-r--r-- | include/clang/Sema/DeclSpec.h | 342 | ||||
-rw-r--r-- | include/clang/Sema/DelayedDiagnostic.h | 18 | ||||
-rw-r--r-- | include/clang/Sema/IdentifierResolver.h | 18 | ||||
-rw-r--r-- | include/clang/Sema/Initialization.h | 13 | ||||
-rw-r--r-- | include/clang/Sema/Lookup.h | 1 | ||||
-rw-r--r-- | include/clang/Sema/Overload.h | 3 | ||||
-rw-r--r-- | include/clang/Sema/Ownership.h | 13 | ||||
-rw-r--r-- | include/clang/Sema/ParsedTemplate.h | 13 | ||||
-rw-r--r-- | include/clang/Sema/Scope.h | 76 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 673 | ||||
-rw-r--r-- | include/clang/Sema/SemaDiagnostic.h | 3 | ||||
-rw-r--r-- | include/clang/Sema/Template.h | 2 | ||||
-rw-r--r-- | include/clang/Sema/TemplateDeduction.h | 2 |
14 files changed, 1127 insertions, 423 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 45ee579..72cd475 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -16,14 +16,33 @@ #define LLVM_CLANG_SEMA_ATTRLIST_H #include "llvm/Support/Allocator.h" -#include "clang/Sema/Ownership.h" +#include "llvm/ADT/SmallVector.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/VersionTuple.h" #include <cassert> namespace clang { + class ASTContext; class IdentifierInfo; class Expr; +/// \brief Represents information about a change in availability for +/// an entity, which is part of the encoding of the 'availability' +/// attribute. +struct AvailabilityChange { + /// \brief The location of the keyword indicating the kind of change. + SourceLocation KeywordLoc; + + /// \brief The version number at which the change occurred. + VersionTuple Version; + + /// \brief The source range covering the version number. + SourceRange VersionRange; + + /// \brief Determine whether this availability change is valid. + bool isValid() const { return !Version.empty(); } +}; + /// AttributeList - Represents GCC's __attribute__ declaration. There are /// 4 forms of this construct...they are: /// @@ -32,52 +51,102 @@ namespace clang { /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. /// -class AttributeList { -public: - class Factory; +class AttributeList { // TODO: This should really be called ParsedAttribute private: IdentifierInfo *AttrName; - SourceLocation AttrLoc; IdentifierInfo *ScopeName; - SourceLocation ScopeLoc; IdentifierInfo *ParmName; + SourceLocation AttrLoc; + SourceLocation ScopeLoc; SourceLocation ParmLoc; - Expr **Args; - unsigned NumArgs; - AttributeList *Next; - bool DeclspecAttribute, CXX0XAttribute; + + /// The number of expression arguments this attribute has. + /// The expressions themselves are stored after the object. + unsigned NumArgs : 16; + + /// True if Microsoft style: declspec(foo). + unsigned DeclspecAttribute : 1; + + /// True if C++0x-style: [[foo]]. + unsigned CXX0XAttribute : 1; /// True if already diagnosed as invalid. - mutable bool Invalid; + mutable unsigned Invalid : 1; + + /// True if this has the extra information associated with an + /// availability attribute. + unsigned IsAvailability : 1; + + /// \brief The location of the 'unavailable' keyword in an + /// availability attribute. + SourceLocation UnavailableLoc; + + /// The next attribute in the current position. + AttributeList *NextInPosition; + + /// The next attribute allocated in the current Pool. + AttributeList *NextInPool; + + Expr **getArgsBuffer() { + return reinterpret_cast<Expr**>(this+1); + } + Expr * const *getArgsBuffer() const { + return reinterpret_cast<Expr* const *>(this+1); + } + + enum AvailabilitySlot { + IntroducedSlot, DeprecatedSlot, ObsoletedSlot + }; + + AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { + return reinterpret_cast<AvailabilityChange*>(this+1)[index]; + } + const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { + return reinterpret_cast<const AvailabilityChange*>(this+1)[index]; + } AttributeList(const AttributeList &); // DO NOT IMPLEMENT void operator=(const AttributeList &); // DO NOT IMPLEMENT void operator delete(void *); // DO NOT IMPLEMENT ~AttributeList(); // DO NOT IMPLEMENT - AttributeList(llvm::BumpPtrAllocator &Alloc, - IdentifierInfo *AttrName, SourceLocation AttrLoc, - IdentifierInfo *ScopeName, SourceLocation ScopeLoc, - IdentifierInfo *ParmName, SourceLocation ParmLoc, - Expr **args, unsigned numargs, - bool declspec, bool cxx0x); + + size_t allocated_size() const; + + AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + Expr **args, unsigned numArgs, + bool declspec, bool cxx0x) + : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), + AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + NumArgs(numArgs), + DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false), + IsAvailability(false), NextInPosition(0), NextInPool(0) { + if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); + } + + AttributeList(IdentifierInfo *attrName, SourceLocation attrLoc, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + const AvailabilityChange &introduced, + const AvailabilityChange &deprecated, + const AvailabilityChange &obsoleted, + SourceLocation unavailable, + bool declspec, bool cxx0x) + : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), + AttrLoc(attrLoc), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), + Invalid(false), IsAvailability(true), UnavailableLoc(unavailable), + NextInPosition(0), NextInPool(0) { + new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); + new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); + new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); + } + + friend class AttributePool; + friend class AttributeFactory; + public: - class Factory { - llvm::BumpPtrAllocator Alloc; - public: - Factory() {} - ~Factory() {} - AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc, - IdentifierInfo *ScopeName, SourceLocation ScopeLoc, - IdentifierInfo *ParmName, SourceLocation ParmLoc, - Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) { - AttributeList *Mem = Alloc.Allocate<AttributeList>(); - new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc, - ParmName, ParmLoc, args, numargs, - declspec, cxx0x); - return Mem; - } - }; - enum Kind { // Please keep this list alphabetized. AT_IBAction, // Clang-specific. AT_IBOutlet, // Clang-specific. @@ -88,6 +157,7 @@ public: AT_always_inline, AT_analyzer_noreturn, AT_annotate, + AT_availability, // Clang-specific AT_base_check, AT_blocks, AT_carries_dependency, @@ -125,6 +195,7 @@ public: AT_nothrow, AT_nsobject, AT_objc_exception, + AT_objc_method_family, AT_cf_returns_not_retained, // Clang-specific. AT_cf_returns_retained, // Clang-specific. AT_ns_returns_not_retained, // Clang-specific. @@ -134,6 +205,7 @@ public: AT_ns_consumed, // Clang-specific. AT_ns_consumes_self, // Clang-specific. AT_objc_gc, + AT_opencl_image_access, // OpenCL-specific. AT_opencl_kernel_function, // OpenCL-specific. AT_overloadable, // Clang-specific. AT_ownership_holds, // Clang-specific. @@ -141,6 +213,7 @@ public: AT_ownership_takes, // Clang-specific. AT_packed, AT_pascal, + AT_pcs, // ARM specific AT_pure, AT_regparm, AT_section, @@ -162,6 +235,7 @@ public: AT_weak_import, AT_reqd_wg_size, AT_init_priority, + AT_MsStruct, IgnoredAttribute, UnknownAttribute }; @@ -185,23 +259,27 @@ public: Kind getKind() const { return getKind(getName()); } static Kind getKind(const IdentifierInfo *Name); - AttributeList *getNext() const { return Next; } - void setNext(AttributeList *N) { Next = N; } + AttributeList *getNext() const { return NextInPosition; } + void setNext(AttributeList *N) { NextInPosition = N; } /// getNumArgs - Return the number of actual arguments to this attribute. unsigned getNumArgs() const { return NumArgs; } + /// hasParameterOrArguments - Return true if this attribute has a parameter, + /// or has a non empty argument expression list. + bool hasParameterOrArguments() const { return ParmName || NumArgs; } + /// getArg - Return the specified argument. Expr *getArg(unsigned Arg) const { assert(Arg < NumArgs && "Arg access out of range!"); - return Args[Arg]; + return getArgsBuffer()[Arg]; } class arg_iterator { - Expr** X; + Expr * const *X; unsigned Idx; public: - arg_iterator(Expr** x, unsigned idx) : X(x), Idx(idx) {} + arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {} arg_iterator& operator++() { ++Idx; @@ -228,14 +306,167 @@ public: }; arg_iterator arg_begin() const { - return arg_iterator(Args, 0); + return arg_iterator(getArgsBuffer(), 0); } arg_iterator arg_end() const { - return arg_iterator(Args, NumArgs); + return arg_iterator(getArgsBuffer(), NumArgs); + } + + const AvailabilityChange &getAvailabilityIntroduced() const { + assert(getKind() == AT_availability && "Not an availability attribute"); + return getAvailabilitySlot(IntroducedSlot); + } + + const AvailabilityChange &getAvailabilityDeprecated() const { + assert(getKind() == AT_availability && "Not an availability attribute"); + return getAvailabilitySlot(DeprecatedSlot); + } + + const AvailabilityChange &getAvailabilityObsoleted() const { + assert(getKind() == AT_availability && "Not an availability attribute"); + return getAvailabilitySlot(ObsoletedSlot); + } + + SourceLocation getUnavailableLoc() const { + assert(getKind() == AT_availability && "Not an availability attribute"); + return UnavailableLoc; } }; +/// A factory, from which one makes pools, from which one creates +/// individual attributes which are deallocated with the pool. +/// +/// Note that it's tolerably cheap to create and destroy one of +/// these as long as you don't actually allocate anything in it. +class AttributeFactory { +public: + enum { + /// The required allocation size of an availability attribute, + /// which we want to ensure is a multiple of sizeof(void*). + AvailabilityAllocSize = + sizeof(AttributeList) + + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1) + / sizeof(void*) * sizeof(void*)) + }; + +private: + enum { + /// The number of free lists we want to be sure to support + /// inline. This is just enough that availability attributes + /// don't surpass it. It's actually very unlikely we'll see an + /// attribute that needs more than that; on x86-64 you'd need 10 + /// expression arguments, and on i386 you'd need 19. + InlineFreeListsCapacity = + 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*) + }; + + llvm::BumpPtrAllocator Alloc; + + /// Free lists. The index is determined by the following formula: + /// (size - sizeof(AttributeList)) / sizeof(void*) + llvm::SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists; + + // The following are the private interface used by AttributePool. + friend class AttributePool; + + /// Allocate an attribute of the given size. + void *allocate(size_t size); + + /// Reclaim all the attributes in the given pool chain, which is + /// non-empty. Note that the current implementation is safe + /// against reclaiming things which were not actually allocated + /// with the allocator, although of course it's important to make + /// sure that their allocator lives at least as long as this one. + void reclaimPool(AttributeList *head); + +public: + AttributeFactory(); + ~AttributeFactory(); +}; + +class AttributePool { + AttributeFactory &Factory; + AttributeList *Head; + + void *allocate(size_t size) { + return Factory.allocate(size); + } + + AttributeList *add(AttributeList *attr) { + // We don't care about the order of the pool. + attr->NextInPool = Head; + Head = attr; + return attr; + } + + void takePool(AttributeList *pool); + +public: + /// Create a new pool for a factory. + AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {} + + /// Move the given pool's allocations to this pool. + AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) { + pool.Head = 0; + } + + AttributeFactory &getFactory() const { return Factory; } + + void clear() { + if (Head) { + Factory.reclaimPool(Head); + Head = 0; + } + } + + /// Take the given pool's allocations and add them to this pool. + void takeAllFrom(AttributePool &pool) { + if (pool.Head) { + takePool(pool.Head); + pool.Head = 0; + } + } + + ~AttributePool() { + if (Head) Factory.reclaimPool(Head); + } + + AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + Expr **args, unsigned numArgs, + bool declspec = false, bool cxx0x = false) { + void *memory = allocate(sizeof(AttributeList) + + numArgs * sizeof(Expr*)); + return add(new (memory) AttributeList(attrName, attrLoc, + scopeName, scopeLoc, + parmName, parmLoc, + args, numArgs, + declspec, cxx0x)); + } + + AttributeList *create(IdentifierInfo *attrName, SourceLocation attrLoc, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + const AvailabilityChange &introduced, + const AvailabilityChange &deprecated, + const AvailabilityChange &obsoleted, + SourceLocation unavailable, + bool declspec = false, bool cxx0x = false) { + void *memory = allocate(AttributeFactory::AvailabilityAllocSize); + return add(new (memory) AttributeList(attrName, attrLoc, + scopeName, scopeLoc, + parmName, parmLoc, + introduced, deprecated, obsoleted, + unavailable, + declspec, cxx0x)); + } + + AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, + SourceLocation TokLoc, int Arg); +}; + /// addAttributeLists - Add two AttributeLists together /// The right-hand list is appended to the left-hand list, if any /// A pointer to the joined list is returned. @@ -278,7 +509,16 @@ struct CXX0XAttributeList { /// is that this will become significantly more serious. class ParsedAttributes { public: - ParsedAttributes() : list(0) {} + ParsedAttributes(AttributeFactory &factory) + : pool(factory), list(0) { + } + + ParsedAttributes(ParsedAttributes &attrs) + : pool(attrs.pool), list(attrs.list) { + attrs.list = 0; + } + + AttributePool &getPool() const { return pool; } bool empty() const { return list == 0; } @@ -289,7 +529,7 @@ public: list = newAttr; } - void append(AttributeList *newList) { + void addAll(AttributeList *newList) { if (!newList) return; AttributeList *lastInNewList = newList; @@ -304,14 +544,59 @@ public: list = newList; } - void clear() { list = 0; } + void takeAllFrom(ParsedAttributes &attrs) { + addAll(attrs.list); + attrs.list = 0; + pool.takeAllFrom(attrs.pool); + } + + void clear() { list = 0; pool.clear(); } AttributeList *getList() const { return list; } /// Returns a reference to the attribute list. Try not to introduce /// dependencies on this method, it may not be long-lived. AttributeList *&getListRef() { return list; } + + AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + Expr **args, unsigned numArgs, + bool declspec = false, bool cxx0x = false) { + AttributeList *attr = + pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc, + args, numArgs, declspec, cxx0x); + add(attr); + return attr; + } + + AttributeList *addNew(IdentifierInfo *attrName, SourceLocation attrLoc, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + const AvailabilityChange &introduced, + const AvailabilityChange &deprecated, + const AvailabilityChange &obsoleted, + SourceLocation unavailable, + bool declspec = false, bool cxx0x = false) { + AttributeList *attr = + pool.create(attrName, attrLoc, scopeName, scopeLoc, parmName, parmLoc, + introduced, deprecated, obsoleted, unavailable, + declspec, cxx0x); + add(attr); + return attr; + } + + AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name, + SourceLocation loc, int arg) { + AttributeList *attr = + pool.createIntegerAttribute(C, name, loc, arg); + add(attr); + return attr; + } + + private: + mutable AttributePool pool; AttributeList *list; }; diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 64126bd..708c9b2 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -22,7 +22,9 @@ #include "clang/Sema/AttributeList.h" #include "clang/Sema/Ownership.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/Lex/Token.h" +#include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/SmallVector.h" @@ -54,32 +56,10 @@ namespace clang { /// /// The actual scope is described by getScopeRep(). class CXXScopeSpec { - SourceRange Range; - NestedNameSpecifier *ScopeRep; - - /// \brief Buffer used to store source-location information for the - /// nested-name-specifier. - /// - /// Note that we explicitly manage the buffer (rather than using a - /// SmallVector) because \c Declarator expects it to be possible to memcpy() - /// a \c CXXScopeSpec. - char *Buffer; - - /// \brief The size of the buffer used to store source-location information - /// for the nested-name-specifier. - unsigned BufferSize; - - /// \brief The capacity of the buffer used to store source-location - /// information for the nested-name-specifier. - unsigned BufferCapacity; + SourceRange Range; + NestedNameSpecifierLocBuilder Builder; public: - CXXScopeSpec() : Range(), ScopeRep(), Buffer(0), BufferSize(0), - BufferCapacity(0) { } - CXXScopeSpec(const CXXScopeSpec &Other); - CXXScopeSpec &operator=(const CXXScopeSpec &Other); - ~CXXScopeSpec(); - const SourceRange &getRange() const { return Range; } void setRange(const SourceRange &R) { Range = R; } void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } @@ -87,7 +67,10 @@ public: SourceLocation getBeginLoc() const { return Range.getBegin(); } SourceLocation getEndLoc() const { return Range.getEnd(); } - NestedNameSpecifier *getScopeRep() const { return ScopeRep; } + /// \brief Retrieve the representation of the nested-name-specifier. + NestedNameSpecifier *getScopeRep() const { + return Builder.getRepresentation(); + } /// \brief Extend the current nested-name-specifier by another /// nested-name-specifier component of the form 'type::'. @@ -175,10 +158,10 @@ public: /// A scope specifier is present, but may be valid or invalid. bool isNotEmpty() const { return !isEmpty(); } - /// An error occured during parsing of the scope specifier. - bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; } + /// An error occurred during parsing of the scope specifier. + bool isInvalid() const { return isNotEmpty() && getScopeRep() == 0; } /// A scope specifier is present, and it refers to a real scope. - bool isValid() const { return isNotEmpty() && ScopeRep != 0; } + bool isValid() const { return isNotEmpty() && getScopeRep() != 0; } /// \brief Indicate that this nested-name-specifier is invalid. void SetInvalid(SourceRange R) { @@ -186,24 +169,24 @@ public: if (Range.getBegin().isInvalid()) Range.setBegin(R.getBegin()); Range.setEnd(R.getEnd()); - ScopeRep = 0; + Builder.Clear(); } /// Deprecated. Some call sites intend isNotEmpty() while others intend /// isValid(). - bool isSet() const { return ScopeRep != 0; } + bool isSet() const { return getScopeRep() != 0; } void clear() { Range = SourceRange(); - ScopeRep = 0; + Builder.Clear(); } /// \brief Retrieve the data associated with the source-location information. - char *location_data() const { return Buffer; } + char *location_data() const { return Builder.getBuffer().first; } /// \brief Retrieve the size of the data associated with source-location /// information. - unsigned location_size() const { return BufferSize; } + unsigned location_size() const { return Builder.getBuffer().second; } }; /// DeclSpec - This class captures information about "declaration specifiers", @@ -267,6 +250,7 @@ public: static const TST TST_typeofExpr = clang::TST_typeofExpr; static const TST TST_decltype = clang::TST_decltype; static const TST TST_auto = clang::TST_auto; + static const TST TST_unknown_anytype = clang::TST_unknown_anytype; static const TST TST_error = clang::TST_error; // type-qualifiers @@ -288,7 +272,6 @@ public: }; private: - // storage-class-specifier /*SCS*/unsigned StorageClassSpec : 3; unsigned SCS_thread_specified : 1; @@ -346,6 +329,11 @@ private: SourceLocation StorageClassSpecLoc, SCS_threadLoc; SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc; + /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, + /// typename, then this is the location of the named type (if present); + /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and + /// TSTNameLoc provides source range info for tag types. + SourceLocation TSTNameLoc; SourceRange TypeofParensRange; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; @@ -370,7 +358,7 @@ private: void operator=(const DeclSpec&); // DO NOT IMPLEMENT public: - DeclSpec() + DeclSpec(AttributeFactory &attrFactory) : StorageClassSpec(SCS_unspecified), SCS_thread_specified(false), SCS_extern_in_linkage_spec(false), @@ -389,6 +377,7 @@ public: Friend_specified(false), Constexpr_specified(false), StorageClassSpecAsWritten(SCS_unspecified), + Attrs(attrFactory), ProtocolQualifiers(0), NumProtocolQualifiers(0), ProtocolLocs(0), @@ -448,6 +437,11 @@ public: SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } SourceLocation getAltiVecLoc() const { return AltiVecLoc; } + SourceLocation getTypeSpecTypeNameLoc() const { + assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename); + return TSTNameLoc; + } + SourceRange getTypeofParensRange() const { return TypeofParensRange; } void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } @@ -539,6 +533,13 @@ public: unsigned &DiagID, ParsedType Rep); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned); + bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, + SourceLocation TagNameLoc, const char *&PrevSpec, + unsigned &DiagID, ParsedType Rep); + bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, + SourceLocation TagNameLoc, const char *&PrevSpec, + unsigned &DiagID, Decl *Rep, bool Owned); + bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Expr *Rep); bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, @@ -581,6 +582,10 @@ public: bool isConstexprSpecified() const { return Constexpr_specified; } SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } + AttributePool &getAttributePool() const { + return Attrs.getPool(); + } + /// AddAttributes - contatenates two attribute lists. /// The GCC attribute syntax allows for the following: /// @@ -594,9 +599,9 @@ public: /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; /// void addAttributes(AttributeList *AL) { - Attrs.append(AL); + Attrs.addAll(AL); } - void aetAttributes(AttributeList *AL) { + void setAttributes(AttributeList *AL) { Attrs.set(AL); } @@ -608,14 +613,12 @@ public: /// TakeAttributes - Return the current attribute list and remove them from /// the DeclSpec so that it doesn't own them. ParsedAttributes takeAttributes() { - ParsedAttributes saved = Attrs; - Attrs.clear(); - return saved; + // The non-const "copy" constructor clears the operand automatically. + return Attrs; } void takeAttributesFrom(ParsedAttributes &attrs) { - Attrs.append(attrs.getList()); - attrs.clear(); + Attrs.takeAllFrom(attrs); } typedef Decl * const *ProtocolQualifierListTy; @@ -649,7 +652,12 @@ public: /// "declaration specifiers" specific to objective-c class ObjCDeclSpec { public: - /// ObjCDeclQualifier - Qualifier used on types in method declarations + /// ObjCDeclQualifier - Qualifier used on types in method + /// declarations. Not all combinations are sensible. Parameters + /// can be one of { in, out, inout } with one of { bycopy, byref }. + /// Returns can either be { oneway } or not. + /// + /// This should be kept in sync with Decl::ObjCDeclQualifier. enum ObjCDeclQualifier { DQ_None = 0x0, DQ_In = 0x1, @@ -661,7 +669,8 @@ public: }; /// PropertyAttributeKind - list of property attributes. - enum ObjCPropertyAttributeKind { DQ_PR_noattr = 0x0, + enum ObjCPropertyAttributeKind { + DQ_PR_noattr = 0x0, DQ_PR_readonly = 0x01, DQ_PR_getter = 0x02, DQ_PR_assign = 0x04, @@ -1037,11 +1046,8 @@ struct DeclaratorChunk { /// The qualifier bitmask values are the same as in QualType. unsigned TypeQuals : 3; - /// hasExceptionSpec - True if the function has an exception specification. - unsigned hasExceptionSpec : 1; - - /// hasAnyExceptionSpec - True if the function has a throw(...) specifier. - unsigned hasAnyExceptionSpec : 1; + /// ExceptionSpecType - An ExceptionSpecificationType value. + unsigned ExceptionSpecType : 3; /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo. unsigned DeleteArgInfo : 1; @@ -1053,28 +1059,34 @@ struct DeclaratorChunk { /// declarator. unsigned NumArgs; - /// NumExceptions - This is the number of types in the exception-decl, if - /// the function has one. + /// NumExceptions - This is the number of types in the dynamic-exception- + /// decl, if the function has one. unsigned NumExceptions; /// \brief The location of the ref-qualifier, if any. /// /// If this is an invalid location, there is no ref-qualifier. unsigned RefQualifierLoc; - - /// ThrowLoc - When hasExceptionSpec is true, the location of the throw + + /// \brief When ExceptionSpecType isn't EST_None, the location of the /// keyword introducing the spec. - unsigned ThrowLoc; + unsigned ExceptionSpecLoc; /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that /// describe the arguments for this function declarator. This is null if /// there are no arguments specified. ParamInfo *ArgInfo; - /// Exceptions - This is a pointer to a new[]'d array of TypeAndRange - /// objects that contain the types in the function's exception - /// specification and their locations. - TypeAndRange *Exceptions; + union { + /// \brief Pointer to a new[]'d array of TypeAndRange objects that + /// contain the types in the function's dynamic exception specification + /// and their locations, if there is one. + TypeAndRange *Exceptions; + + /// \brief Pointer to the expression in the noexcept-specifier of this + /// function, if it has one. + Expr *NoexceptExpr; + }; /// TrailingReturnType - If this isn't null, it's the trailing return type /// specified. This is actually a ParsedType, but stored as void* to @@ -1094,7 +1106,8 @@ struct DeclaratorChunk { void destroy() { if (DeleteArgInfo) delete[] ArgInfo; - delete[] Exceptions; + if (getExceptionSpecType() == EST_Dynamic) + delete[] Exceptions; } /// isKNRPrototype - Return true if this is a K&R style identifier list, @@ -1107,18 +1120,23 @@ struct DeclaratorChunk { SourceLocation getEllipsisLoc() const { return SourceLocation::getFromRawEncoding(EllipsisLoc); } - SourceLocation getThrowLoc() const { - return SourceLocation::getFromRawEncoding(ThrowLoc); + SourceLocation getExceptionSpecLoc() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLoc); } - + /// \brief Retrieve the location of the ref-qualifier, if any. SourceLocation getRefQualifierLoc() const { return SourceLocation::getFromRawEncoding(RefQualifierLoc); } - + /// \brief Determine whether this function declaration contains a /// ref-qualifier. bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } + + /// \brief Get the type of exception specification this function has. + ExceptionSpecificationType getExceptionSpecType() const { + return static_cast<ExceptionSpecificationType>(ExceptionSpecType); + } }; struct BlockPointerTypeInfo : TypeInfoCommon { @@ -1188,8 +1206,7 @@ struct DeclaratorChunk { static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, - SourceLocation RestrictQualLoc, - const ParsedAttributes &attrs) { + SourceLocation RestrictQualLoc) { DeclaratorChunk I; I.Kind = Pointer; I.Loc = Loc; @@ -1197,35 +1214,33 @@ struct DeclaratorChunk { I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding(); I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding(); I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding(); - I.Ptr.AttrList = attrs.getList(); + I.Ptr.AttrList = 0; return I; } /// getReference - Return a DeclaratorChunk for a reference. /// static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, - const ParsedAttributes &attrs, bool lvalue) { DeclaratorChunk I; I.Kind = Reference; I.Loc = Loc; I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0; I.Ref.LValueRef = lvalue; - I.Ref.AttrList = attrs.getList(); + I.Ref.AttrList = 0; return I; } /// getArray - Return a DeclaratorChunk for an array. /// static DeclaratorChunk getArray(unsigned TypeQuals, - const ParsedAttributes &attrs, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc) { DeclaratorChunk I; I.Kind = Array; I.Loc = LBLoc; I.EndLoc = RBLoc; - I.Arr.AttrList = attrs.getList(); + I.Arr.AttrList = 0; I.Arr.TypeQuals = TypeQuals; I.Arr.hasStatic = isStatic; I.Arr.isStar = isStar; @@ -1235,44 +1250,44 @@ struct DeclaratorChunk { /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. /// "TheDeclarator" is the declarator that this will be added to. - static DeclaratorChunk getFunction(const ParsedAttributes &attrs, - bool hasProto, bool isVariadic, + static DeclaratorChunk getFunction(bool hasProto, bool isVariadic, SourceLocation EllipsisLoc, ParamInfo *ArgInfo, unsigned NumArgs, unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, - bool hasExceptionSpec, - SourceLocation ThrowLoc, - bool hasAnyExceptionSpec, + ExceptionSpecificationType ESpecType, + SourceLocation ESpecLoc, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, - SourceLocation LPLoc, SourceLocation RPLoc, + Expr *NoexceptExpr, + SourceLocation LocalRangeBegin, + SourceLocation LocalRangeEnd, Declarator &TheDeclarator, - ParsedType TrailingReturnType = ParsedType()); + ParsedType TrailingReturnType = + ParsedType()); /// getBlockPointer - Return a DeclaratorChunk for a block. /// - static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc, - const ParsedAttributes &attrs) { + static DeclaratorChunk getBlockPointer(unsigned TypeQuals, + SourceLocation Loc) { DeclaratorChunk I; I.Kind = BlockPointer; I.Loc = Loc; I.Cls.TypeQuals = TypeQuals; - I.Cls.AttrList = attrs.getList(); + I.Cls.AttrList = 0; return I; } static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, - SourceLocation Loc, - const ParsedAttributes &attrs) { + SourceLocation Loc) { DeclaratorChunk I; I.Kind = MemberPointer; I.Loc = Loc; I.Mem.TypeQuals = TypeQuals; - I.Mem.AttrList = attrs.getList(); + I.Mem.AttrList = 0; new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS); return I; } @@ -1306,6 +1321,7 @@ public: enum TheContext { FileContext, // File scope declaration. PrototypeContext, // Within a function prototype. + ObjCPrototypeContext,// Within a method prototype. KNRTypeListContext, // K&R type definition list for formals. TypeNameContext, // Abstract declarator for types. MemberContext, // Struct/Union field. @@ -1315,7 +1331,8 @@ public: TemplateParamContext,// Within a template parameter list. CXXCatchContext, // C++ catch exception-declaration BlockLiteralContext, // Block literal declarator. - TemplateTypeArgContext // Template type argument. + TemplateTypeArgContext, // Template type argument. + AliasDeclContext // C++0x alias-declaration. }; private: @@ -1340,8 +1357,8 @@ private: /// GroupingParens - Set by Parser::ParseParenDeclarator(). bool GroupingParens : 1; - /// AttrList - Attributes. - AttributeList *AttrList; + /// Attrs - Attributes. + ParsedAttributes Attrs; /// AsmLabel - The asm label, if specified. Expr *AsmLabel; @@ -1365,8 +1382,8 @@ public: Declarator(const DeclSpec &ds, TheContext C) : DS(ds), Range(ds.getSourceRange()), Context(C), InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error), - GroupingParens(false), AttrList(0), AsmLabel(0), - InlineParamsUsed(false), Extension(false) { + GroupingParens(false), Attrs(ds.getAttributePool().getFactory()), + AsmLabel(0), InlineParamsUsed(false), Extension(false) { } ~Declarator() { @@ -1384,6 +1401,10 @@ public: /// be shared or when in error recovery etc. DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); } + AttributePool &getAttributePool() const { + return Attrs.getPool(); + } + /// getCXXScopeSpec - Return the C++ scope specifier (global scope or /// nested-name-specifier) that is part of the declarator-id. const CXXScopeSpec &getCXXScopeSpec() const { return SS; } @@ -1394,6 +1415,10 @@ public: TheContext getContext() const { return Context; } + bool isPrototypeContext() const { + return (Context == PrototypeContext || Context == ObjCPrototypeContext); + } + /// getSourceRange - Get the source range that spans this declarator. const SourceRange &getSourceRange() const { return Range; } @@ -1429,7 +1454,7 @@ public: for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) DeclTypeInfo[i].destroy(); DeclTypeInfo.clear(); - AttrList = 0; + Attrs.clear(); AsmLabel = 0; InlineParamsUsed = false; } @@ -1438,26 +1463,79 @@ public: /// not allowed. This is true for typenames, prototypes, and template /// parameter lists. bool mayOmitIdentifier() const { - return Context == TypeNameContext || Context == PrototypeContext || - Context == TemplateParamContext || Context == CXXCatchContext || - Context == BlockLiteralContext || Context == TemplateTypeArgContext; + switch (Context) { + case FileContext: + case KNRTypeListContext: + case MemberContext: + case BlockContext: + case ForContext: + case ConditionContext: + return false; + + case TypeNameContext: + case AliasDeclContext: + case PrototypeContext: + case ObjCPrototypeContext: + case TemplateParamContext: + case CXXCatchContext: + case BlockLiteralContext: + case TemplateTypeArgContext: + return true; + } + llvm_unreachable("unknown context kind!"); } /// mayHaveIdentifier - Return true if the identifier is either optional or /// required. This is true for normal declarators and prototypes, but not /// typenames. bool mayHaveIdentifier() const { - return Context != TypeNameContext && Context != BlockLiteralContext && - Context != TemplateTypeArgContext; + switch (Context) { + case FileContext: + case KNRTypeListContext: + case MemberContext: + case BlockContext: + case ForContext: + case ConditionContext: + case PrototypeContext: + case TemplateParamContext: + case CXXCatchContext: + return true; + + case TypeNameContext: + case AliasDeclContext: + case ObjCPrototypeContext: + case BlockLiteralContext: + case TemplateTypeArgContext: + return false; + } + llvm_unreachable("unknown context kind!"); } /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be /// followed by a C++ direct initializer, e.g. "int x(1);". bool mayBeFollowedByCXXDirectInit() const { - return !hasGroupingParens() && - (Context == FileContext || - Context == BlockContext || - Context == ForContext); + if (hasGroupingParens()) return false; + + switch (Context) { + case FileContext: + case BlockContext: + case ForContext: + return true; + + case KNRTypeListContext: + case MemberContext: + case ConditionContext: + case PrototypeContext: + case ObjCPrototypeContext: + case TemplateParamContext: + case CXXCatchContext: + case TypeNameContext: + case AliasDeclContext: + case BlockLiteralContext: + case TemplateTypeArgContext: + return false; + } + llvm_unreachable("unknown context kind!"); } /// isPastIdentifier - Return true if we have parsed beyond the point where @@ -1486,8 +1564,13 @@ public: /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to /// EndLoc, which should be the last token of the chunk. - void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) { + void AddTypeInfo(const DeclaratorChunk &TI, + ParsedAttributes &attrs, + SourceLocation EndLoc) { DeclTypeInfo.push_back(TI); + DeclTypeInfo.back().getAttrListRef() = attrs.getList(); + getAttributePool().takeAllFrom(attrs.getPool()); + if (!EndLoc.isInvalid()) SetRangeEnd(EndLoc); } @@ -1567,28 +1650,26 @@ public: return const_cast<Declarator*>(this)->getFunctionTypeInfo(); } - /// AddAttributes - simply adds the attribute list to the Declarator. + /// takeAttributes - Takes attributes from the given parsed-attributes + /// set and add them to this declarator. + /// /// These examples both add 3 attributes to "var": /// short int var __attribute__((aligned(16),common,deprecated)); /// short int x, __attribute__((aligned(16)) var /// __attribute__((common,deprecated)); /// /// Also extends the range of the declarator. - void addAttributes(AttributeList *alist, SourceLocation LastLoc) { - AttrList = addAttributeLists(AttrList, alist); + void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) { + Attrs.takeAllFrom(attrs); - if (!LastLoc.isInvalid()) - SetRangeEnd(LastLoc); + if (!lastLoc.isInvalid()) + SetRangeEnd(lastLoc); } - void addAttributes(const ParsedAttributes &attrs) { - addAttributes(attrs.getList(), SourceLocation()); - } - - const AttributeList *getAttributes() const { return AttrList; } - AttributeList *getAttributes() { return AttrList; } + const AttributeList *getAttributes() const { return Attrs.getList(); } + AttributeList *getAttributes() { return Attrs.getList(); } - AttributeList *&getAttrListRef() { return AttrList; } + AttributeList *&getAttrListRef() { return Attrs.getListRef(); } /// hasAttributes - do we contain any attributes? bool hasAttributes() const { @@ -1634,8 +1715,7 @@ public: enum Specifier { VS_None = 0, VS_Override = 1, - VS_Final = 2, - VS_New = 4 + VS_Final = 2 }; VirtSpecifiers() : Specifiers(0) { } @@ -1649,45 +1729,17 @@ public: bool isFinalSpecified() const { return Specifiers & VS_Final; } SourceLocation getFinalLoc() const { return VS_finalLoc; } - bool isNewSpecified() const { return Specifiers & VS_New; } - SourceLocation getNewLoc() const { return VS_newLoc; } - void clear() { Specifiers = 0; } static const char *getSpecifierName(Specifier VS); + SourceLocation getLastLocation() const { return LastLocation; } + private: unsigned Specifiers; - SourceLocation VS_overrideLoc, VS_finalLoc, VS_newLoc; -}; - -/// ClassVirtSpecifiers - Represents a C++0x class-virt-specifier-seq. -class ClassVirtSpecifiers { -public: - enum Specifier { - CVS_None = 0, - CVS_Final = 1, - CVS_Explicit = 2 - }; - - ClassVirtSpecifiers() : Specifiers(0) { } - - bool SetSpecifier(Specifier CVS, SourceLocation Loc, - const char *&PrevSpec); - - bool isFinalSpecified() const { return Specifiers & CVS_Final; } - SourceLocation getFinalLoc() const { return CVS_finalLoc; } - - bool isExplicitSpecified() const { return Specifiers & CVS_Explicit; } - SourceLocation getExplicitLoc() const { return CVS_explicitLoc; } - - static const char *getSpecifierName(Specifier CVS); - -private: - unsigned Specifiers; - - SourceLocation CVS_finalLoc, CVS_explicitLoc; + SourceLocation VS_overrideLoc, VS_finalLoc; + SourceLocation LastLocation; }; } // end namespace clang diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 6e808de..8395138 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -119,25 +119,11 @@ public: SourceLocation Loc; - void destroy() { - switch (Kind) { - case Access: getAccessData().~AccessedEntity(); break; - case Deprecation: break; - } - } + void Destroy(); static DelayedDiagnostic makeDeprecation(SourceLocation Loc, const NamedDecl *D, - llvm::StringRef Msg) { - DelayedDiagnostic DD; - DD.Kind = Deprecation; - DD.Triggered = false; - DD.Loc = Loc; - DD.DeprecationData.Decl = D; - DD.DeprecationData.Message = Msg.data(); - DD.DeprecationData.MessageLen = Msg.size(); - return DD; - } + llvm::StringRef Msg); static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity) { diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h index 7e9d338..8d79fc0 100644 --- a/include/clang/Sema/IdentifierResolver.h +++ b/include/clang/Sema/IdentifierResolver.h @@ -28,7 +28,7 @@ class Scope; /// IdentifierResolver - Keeps track of shadowed decls on enclosing /// scopes. It manages the shadowing chains of declaration names and -/// implements efficent decl lookup based on a declaration name. +/// implements efficient decl lookup based on a declaration name. class IdentifierResolver { /// IdDeclInfo - Keeps track of information about decls associated @@ -53,6 +53,11 @@ class IdentifierResolver { /// declaration was not found, returns false. bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); + /// \brief Insert the given declaration at the given position in the list. + void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { + Decls.insert(Pos, D); + } + private: DeclsTy Decls; }; @@ -146,8 +151,13 @@ public: /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns /// true if 'D' belongs to the given declaration context. + /// + /// \param ExplicitInstantiationOrSpecialization When true, we are checking + /// whether the declaration is in scope for the purposes of explicit template + /// instantiation or specialization. The default is false. bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context, - Scope *S = 0) const; + Scope *S = 0, + bool ExplicitInstantiationOrSpecialization = false) const; /// AddDecl - Link the decl to its shadowed decl chain. void AddDecl(NamedDecl *D); @@ -161,6 +171,10 @@ public: /// (and, therefore, replaced). bool ReplaceDecl(NamedDecl *Old, NamedDecl *New); + /// \brief Insert the given declaration after the given iterator + /// position. + void InsertDeclAfter(iterator Pos, NamedDecl *D); + /// \brief Link the declaration into the chain of declarations for /// the given identifier. /// diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index bdf0d8e..e83e5c0 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -64,6 +64,8 @@ public: EK_Temporary, /// \brief The entity being initialized is a base member subobject. EK_Base, + /// \brief The initialization is being done by a delegating constructor. + EK_Delegating, /// \brief The entity being initialized is an element of a vector. /// or vector. EK_VectorElement, @@ -210,6 +212,11 @@ public: static InitializedEntity InitializeBase(ASTContext &Context, CXXBaseSpecifier *Base, bool IsInheritedVirtualBase); + + /// \brief Create the initialization entity for a delegated constructor. + static InitializedEntity InitializeDelegation(QualType Type) { + return InitializedEntity(EK_Delegating, SourceLocation(), Type); + } /// \brief Create the initialization entity for a member subobject. static InitializedEntity InitializeMember(FieldDecl *Member, @@ -234,7 +241,7 @@ public: EntityKind getKind() const { return Kind; } /// \brief Retrieve the parent of the entity being initialized, when - /// the initialization itself is occuring within the context of a + /// the initialization itself is occurring within the context of a /// larger initialization. const InitializedEntity *getParent() const { return Parent; } @@ -590,6 +597,8 @@ public: FK_ReferenceInitFailed, /// \brief Implicit conversion failed. FK_ConversionFailed, + /// \brief Implicit conversion failed. + FK_ConversionFromPropertyFailed, /// \brief Too many initializers for scalar FK_TooManyInitsForScalar, /// \brief Reference initialization from an initializer list @@ -655,7 +664,7 @@ public: /// \param Kind the kind of initialization being performed. /// /// \param Args the argument(s) provided for initialization, ownership of - /// which is transfered into the routine. + /// which is transferred into the routine. /// /// \param ResultType if non-NULL, will be set to the type of the /// initialized object, which is the type of the declaration in most diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index aa58d14..400a7cc 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -439,6 +439,7 @@ public: Decls.clear(); if (Paths) deletePaths(Paths); Paths = NULL; + NamingClass = 0; } /// \brief Clears out any current state and re-initializes for a diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 3ce3513..e196e83 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -76,6 +76,7 @@ namespace clang { ICK_Vector_Splat, ///< A vector splat from an arithmetic type ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7) ICK_Block_Pointer_Conversion, ///< Block Pointer conversions + ICK_TransparentUnionConversion, /// Transparent Union Conversions ICK_Num_Conversion_Kinds ///< The number of conversion kinds }; @@ -647,8 +648,6 @@ namespace clang { /// \brief Clear out all of the candidates. void clear(); - - ~OverloadCandidateSet() { clear(); } /// Find the best viable function on this overload set, if it exists. OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index 5f2f0eb..cef93fe 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -383,11 +383,18 @@ namespace clang { template<typename T> T **takeAs() { return reinterpret_cast<T**>(take()); } }; + /// An opaque type for threading parsed type information through the + /// parser. + typedef OpaquePtr<QualType> ParsedType; + typedef UnionOpaquePtr<QualType> UnionParsedType; + /// A SmallVector of statements, with stack size 32 (as that is the only one /// used.) typedef ASTOwningVector<Stmt*, 32> StmtVector; /// A SmallVector of expressions, with stack size 12 (the maximum used.) typedef ASTOwningVector<Expr*, 12> ExprVector; + /// A SmallVector of types. + typedef ASTOwningVector<ParsedType, 12> TypeVector; template <class T, unsigned N> inline ASTMultiPtr<T> move_arg(ASTOwningVector<T, N> &vec) { @@ -421,11 +428,6 @@ namespace clang { static const bool value = true; }; - /// An opaque type for threading parsed type information through the - /// parser. - typedef OpaquePtr<QualType> ParsedType; - typedef UnionOpaquePtr<QualType> UnionParsedType; - typedef ActionResult<Expr*> ExprResult; typedef ActionResult<Stmt*> StmtResult; typedef ActionResult<ParsedType> TypeResult; @@ -440,6 +442,7 @@ namespace clang { typedef ASTMultiPtr<Expr*> MultiExprArg; typedef ASTMultiPtr<Stmt*> MultiStmtArg; + typedef ASTMultiPtr<ParsedType> MultiTypeArg; typedef ASTMultiPtr<TemplateParameterList*> MultiTemplateParamsArg; inline ExprResult ExprError() { return ExprResult(true); } diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index 9e1a616..1f572e5 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -139,6 +139,9 @@ namespace clang { /// tokens. All of the information about template arguments is allocated /// directly after this structure. struct TemplateIdAnnotation { + /// \brief The nested-name-specifier that precedes the template name. + CXXScopeSpec SS; + /// TemplateNameLoc - The location of the template name within the /// source. SourceLocation TemplateNameLoc; @@ -174,10 +177,13 @@ namespace clang { static TemplateIdAnnotation* Allocate(unsigned NumArgs) { TemplateIdAnnotation *TemplateId - = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + + = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + sizeof(ParsedTemplateArgument) * NumArgs); TemplateId->NumArgs = NumArgs; + // Default-construct nested-name-specifier. + new (&TemplateId->SS) CXXScopeSpec(); + // Default-construct parsed template arguments. ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs(); for (unsigned I = 0; I != NumArgs; ++I) @@ -186,7 +192,10 @@ namespace clang { return TemplateId; } - void Destroy() { free(this); } + void Destroy() { + SS.~CXXScopeSpec(); + free(this); + } }; /// Retrieves the range of the given template parameter lists. diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index d7fda35..6588a1d 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -16,6 +16,7 @@ #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" namespace clang { @@ -75,7 +76,10 @@ public: /// ObjCMethodScope - This scope corresponds to an Objective-C method body. /// It always has FnScope and DeclScope set as well. - ObjCMethodScope = 0x400 + ObjCMethodScope = 0x400, + + /// SwitchScope - This is a scope that corresponds to a switch statement. + SwitchScope = 0x800 }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -90,17 +94,25 @@ private: /// interrelates with other control flow statements. unsigned short Flags; + /// PrototypeDepth - This is the number of function prototype scopes + /// enclosing this scope, including this scope. + unsigned short PrototypeDepth; + + /// PrototypeIndex - This is the number of parameters currently + /// declared in this scope. + unsigned short PrototypeIndex; + /// FnParent - If this scope has a parent scope that is a function body, this /// pointer is non-null and points to it. This is used for label processing. Scope *FnParent; /// BreakParent/ContinueParent - This is a direct link to the immediately - /// preceeding BreakParent/ContinueParent if this scope is not one, or null if + /// preceding BreakParent/ContinueParent if this scope is not one, or null if /// there is no containing break/continue scope. Scope *BreakParent, *ContinueParent; /// ControlParent - This is a direct link to the immediately - /// preceeding ControlParent if this scope is not one, or null if + /// preceding ControlParent if this scope is not one, or null if /// there is no containing control scope. Scope *ControlParent; @@ -193,6 +205,19 @@ public: Scope *getTemplateParamParent() { return TemplateParamParent; } const Scope *getTemplateParamParent() const { return TemplateParamParent; } + /// Returns the number of function prototype scopes in this scope + /// chain. + unsigned getFunctionPrototypeDepth() const { + return PrototypeDepth; + } + + /// Return the number of parameters declared in this function + /// prototype, increasing it by one for the next call. + unsigned getNextFunctionPrototypeIndex() { + assert(isFunctionPrototypeScope()); + return PrototypeIndex++; + } + typedef DeclSetTy::iterator decl_iterator; decl_iterator decl_begin() const { return DeclsInScope.begin(); } decl_iterator decl_end() const { return DeclsInScope.end(); } @@ -260,6 +285,20 @@ public: return getFlags() & Scope::AtCatchScope; } + /// isSwitchScope - Return true if this scope is a switch scope. + bool isSwitchScope() const { + for (const Scope *S = this; S; S = S->getParent()) { + if (S->getFlags() & Scope::SwitchScope) + return true; + else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope | + Scope::BlockScope | Scope::TemplateParamScope | + Scope::FunctionPrototypeScope | + Scope::AtCatchScope | Scope::ObjCMethodScope)) + return false; + } + return false; + } + typedef UsingDirectivesTy::iterator udir_iterator; typedef UsingDirectivesTy::const_iterator const_udir_iterator; @@ -285,36 +324,7 @@ public: /// Init - This is used by the parser to implement scope caching. /// - void Init(Scope *Parent, unsigned ScopeFlags) { - AnyParent = Parent; - Depth = AnyParent ? AnyParent->Depth+1 : 0; - Flags = ScopeFlags; - - if (AnyParent) { - FnParent = AnyParent->FnParent; - BreakParent = AnyParent->BreakParent; - ContinueParent = AnyParent->ContinueParent; - ControlParent = AnyParent->ControlParent; - BlockParent = AnyParent->BlockParent; - TemplateParamParent = AnyParent->TemplateParamParent; - } else { - FnParent = BreakParent = ContinueParent = BlockParent = 0; - ControlParent = 0; - TemplateParamParent = 0; - } - - // If this scope is a function or contains breaks/continues, remember it. - if (Flags & FnScope) FnParent = this; - if (Flags & BreakScope) BreakParent = this; - if (Flags & ContinueScope) ContinueParent = this; - if (Flags & ControlScope) ControlParent = this; - if (Flags & BlockScope) BlockParent = this; - if (Flags & TemplateParamScope) TemplateParamParent = this; - DeclsInScope.clear(); - UsingDirectives.clear(); - Entity = 0; - ErrorTrap.reset(); - } + void Init(Scope *parent, unsigned flags); }; } // end namespace clang diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index a937398..07a14d2 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -27,6 +27,7 @@ #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" +#include "clang/Basic/ExpressionTraits.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -43,6 +44,7 @@ namespace clang { class ADLResult; class ASTConsumer; class ASTContext; + class ASTMutationListener; class ArrayType; class AttributeList; class BlockDecl; @@ -110,6 +112,7 @@ namespace clang { class ObjCPropertyDecl; class ObjCProtocolDecl; class OverloadCandidateSet; + class OverloadExpr; class ParenListExpr; class ParmVarDecl; class Preprocessor; @@ -128,7 +131,9 @@ namespace clang { class TemplatePartialOrderingContext; class TemplateTemplateParmDecl; class Token; + class TypeAliasDecl; class TypedefDecl; + class TypedefNameDecl; class TypeLoc; class UnqualifiedId; class UnresolvedLookupExpr; @@ -236,6 +241,8 @@ public: /// 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 /// VisContext - Manages the stack for #pragma GCC visibility. void *VisContext; // Really a "PragmaVisStack*" @@ -255,7 +262,7 @@ public: /// ExtVectorDecls - This is a list all the extended vector types. This allows /// us to associate a raw vector type with one of the ext_vector type names. /// This is only necessary for issuing pretty diagnostics. - llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls; + llvm::SmallVector<TypedefNameDecl*, 24> ExtVectorDecls; /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. llvm::OwningPtr<CXXFieldCollector> FieldCollector; @@ -305,6 +312,16 @@ public: /// and must warn if not used. Only contains the first declaration. llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls; + /// \brief Callback to the parser to parse templated functions when needed. + typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD); + LateTemplateParserCB *LateTemplateParser; + void *OpaqueParser; + + void SetLateTemplateParser(LateTemplateParserCB *LTP, void *P) { + LateTemplateParser = LTP; + OpaqueParser = P; + } + class DelayedDiagnostics; class ParsingDeclState { @@ -645,6 +662,7 @@ public: Preprocessor &getPreprocessor() const { return PP; } ASTContext &getASTContext() const { return Context; } ASTConsumer &getASTConsumer() const { return Consumer; } + ASTMutationListener *getASTMutationListener() const; /// \brief Helper class that creates diagnostics with optional /// template instantiation stacks. @@ -678,6 +696,8 @@ public: /// \brief Build a partial diagnostic. PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h + bool findMacroSpelling(SourceLocation &loc, llvm::StringRef name); + ExprResult Owned(Expr* E) { return E; } ExprResult Owned(ExprResult R) { return R; } StmtResult Owned(Stmt* S) { return S; } @@ -755,7 +775,9 @@ public: const FunctionProtoType *Old, SourceLocation OldLoc, const FunctionProtoType *New, SourceLocation NewLoc, bool *MissingExceptionSpecification = 0, - bool *MissingEmptyExceptionSpecification = 0); + bool *MissingEmptyExceptionSpecification = 0, + bool AllowNoexceptAllMatchWithNoSpec = false, + bool IsOperatorNew = false); bool CheckExceptionSpecSubset( const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, const FunctionProtoType *Superset, SourceLocation SuperLoc, @@ -792,14 +814,117 @@ public: Scope *S, CXXScopeSpec *SS = 0, bool isClassName = false, bool HasTrailingDot = false, - ParsedType ObjectType = ParsedType()); + ParsedType ObjectType = ParsedType(), + bool WantNontrivialTypeSourceInfo = false); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); + bool isMicrosoftMissingTypename(const CXXScopeSpec *SS); bool DiagnoseUnknownTypeName(const IdentifierInfo &II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType); + /// \brief Describes the result of the name lookup and resolution performed + /// by \c ClassifyName(). + enum NameClassificationKind { + NC_Unknown, + NC_Error, + NC_Keyword, + NC_Type, + NC_Expression, + NC_NestedNameSpecifier, + NC_TypeTemplate, + NC_FunctionTemplate + }; + + class NameClassification { + NameClassificationKind Kind; + ExprResult Expr; + TemplateName Template; + ParsedType Type; + const IdentifierInfo *Keyword; + + explicit NameClassification(NameClassificationKind Kind) : Kind(Kind) {} + + public: + NameClassification(ExprResult Expr) : Kind(NC_Expression), Expr(Expr) {} + + NameClassification(ParsedType Type) : Kind(NC_Type), Type(Type) {} + + NameClassification(const IdentifierInfo *Keyword) + : Kind(NC_Keyword), Keyword(Keyword) { } + + static NameClassification Error() { + return NameClassification(NC_Error); + } + + static NameClassification Unknown() { + return NameClassification(NC_Unknown); + } + + static NameClassification NestedNameSpecifier() { + return NameClassification(NC_NestedNameSpecifier); + } + + static NameClassification TypeTemplate(TemplateName Name) { + NameClassification Result(NC_TypeTemplate); + Result.Template = Name; + return Result; + } + + static NameClassification FunctionTemplate(TemplateName Name) { + NameClassification Result(NC_FunctionTemplate); + Result.Template = Name; + return Result; + } + + NameClassificationKind getKind() const { return Kind; } + + ParsedType getType() const { + assert(Kind == NC_Type); + return Type; + } + + ExprResult getExpression() const { + assert(Kind == NC_Expression); + return Expr; + } + + TemplateName getTemplateName() const { + assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); + return Template; + } + + TemplateNameKind getTemplateNameKind() const { + assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate); + return Kind == NC_TypeTemplate? TNK_Type_template : TNK_Function_template; + } +}; + + /// \brief Perform name lookup on the given name, classifying it based on + /// the results of name lookup and the following token. + /// + /// This routine is used by the parser to resolve identifiers and help direct + /// parsing. When the identifier cannot be found, this routine will attempt + /// to correct the typo and classify based on the resulting name. + /// + /// \param S The scope in which we're performing name lookup. + /// + /// \param SS The nested-name-specifier that precedes the name. + /// + /// \param Name The identifier. If typo correction finds an alternative name, + /// this pointer parameter will be updated accordingly. + /// + /// \param NameLoc The location of the identifier. + /// + /// \param NextToken The token following the identifier. Used to help + /// disambiguate the name. + NameClassification ClassifyName(Scope *S, + CXXScopeSpec &SS, + IdentifierInfo *&Name, + SourceLocation NameLoc, + const Token &NextToken); + Decl *ActOnDeclarator(Scope *S, Declarator &D); Decl *HandleDeclarator(Scope *S, Declarator &D, @@ -808,6 +933,7 @@ public: void RegisterLocallyScopedExternCDecl(NamedDecl *ND, const LookupResult &Previous, Scope *S); + bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info); void DiagnoseFunctionSpecifiers(Declarator& D); void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); void CheckShadow(Scope *S, VarDecl *D); @@ -815,6 +941,8 @@ public: NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, TypeSourceInfo *TInfo, LookupResult &Previous, bool &Redeclaration); + NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D, + LookupResult &Previous, bool &Redeclaration); NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -840,12 +968,10 @@ public: ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, SourceLocation Loc, QualType T); - ParmVarDecl *CheckParameter(DeclContext *DC, - TypeSourceInfo *TSInfo, QualType T, - IdentifierInfo *Name, - SourceLocation NameLoc, - StorageClass SC, - StorageClass SCAsWritten); + ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc, + SourceLocation NameLoc, IdentifierInfo *Name, + QualType T, TypeSourceInfo *TSInfo, + StorageClass SC, StorageClass SCAsWritten); void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg); @@ -860,6 +986,7 @@ public: bool TypeMayContainAuto); void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); void ActOnInitializerError(Decl *Dcl); + void ActOnCXXForRangeDecl(Decl *D); void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); void FinalizeDeclaration(Decl *D); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, @@ -869,6 +996,7 @@ public: bool TypeMayContainAuto = true); void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, SourceLocation LocAfterDecls); + void CheckForFunctionRedefinition(FunctionDecl *FD); Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D); Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); @@ -890,7 +1018,9 @@ public: NamedDecl *D); void DiagnoseInvalidJumps(Stmt *Body); - Decl *ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr); + Decl *ActOnFileScopeAsmDecl(Expr *expr, + SourceLocation AsmLoc, + SourceLocation RParenLoc); /// Scope actions. void ActOnPopScope(SourceLocation Loc, Scope *S); @@ -994,7 +1124,7 @@ public: /// C++ record definition's base-specifiers clause and are starting its /// member declarations. void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, - ClassVirtSpecifiers &CVS, + SourceLocation FinalLoc, SourceLocation LBraceLoc); /// ActOnTagFinishDefinition - Invoked once we have finished parsing @@ -1055,7 +1185,12 @@ public: /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns /// true if 'D' belongs to the given declaration context. - bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0); + /// + /// \param ExplicitInstantiationOrSpecialization When true, we are checking + /// whether the declaration is in scope for the purposes of explicit template + /// instantiation or specialization. The default is false. + bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0, + bool ExplicitInstantiationOrSpecialization = false); /// Finds the scope corresponding to the given decl context, if it /// happens to be an enclosing scope. Otherwise return NULL. @@ -1064,11 +1199,13 @@ public: /// Subroutines of ActOnDeclarator(). TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, TypeSourceInfo *TInfo); - void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls); + void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls); bool MergeFunctionDecl(FunctionDecl *New, Decl *Old); bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old); - void MergeVarDeclTypes(VarDecl *New, VarDecl *Old); + void mergeObjCMethodDecls(ObjCMethodDecl *New, const ObjCMethodDecl *Old); void MergeVarDecl(VarDecl *New, LookupResult &OldDecls); + void MergeVarDeclTypes(VarDecl *New, VarDecl *Old); + void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old); bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old); // AssignmentAction - This is used by all the assignment diagnostic functions @@ -1149,13 +1286,13 @@ public: ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init); - bool PerformObjectArgumentInitialization(Expr *&From, - NestedNameSpecifier *Qualifier, - NamedDecl *FoundDecl, - CXXMethodDecl *Method); + ExprResult PerformObjectArgumentInitialization(Expr *From, + NestedNameSpecifier *Qualifier, + NamedDecl *FoundDecl, + CXXMethodDecl *Method); - bool PerformContextuallyConvertToBool(Expr *&From); - bool PerformContextuallyConvertToObjCId(Expr *&From); + ExprResult PerformContextuallyConvertToBool(Expr *From); + ExprResult PerformContextuallyConvertToObjCId(Expr *From); ExprResult ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE, @@ -1167,10 +1304,10 @@ public: const PartialDiagnostic &AmbigNote, const PartialDiagnostic &ConvDiag); - bool PerformObjectMemberConversion(Expr *&From, - NestedNameSpecifier *Qualifier, - NamedDecl *FoundDecl, - NamedDecl *Member); + ExprResult PerformObjectMemberConversion(Expr *From, + NestedNameSpecifier *Qualifier, + NamedDecl *FoundDecl, + NamedDecl *Member); // Members have to be NamespaceDecl* or TranslationUnitDecl*. // TODO: make this is a typesafe union. @@ -1208,7 +1345,7 @@ public: void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, Expr **Args, unsigned NumArgs, @@ -1216,7 +1353,7 @@ public: bool SuppressUserConversions = false); void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false); @@ -1253,9 +1390,10 @@ public: void AddArgumentDependentLookupCandidates(DeclarationName Name, bool Operator, Expr **Args, unsigned NumArgs, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, OverloadCandidateSet& CandidateSet, - bool PartialOverloading = false); + bool PartialOverloading = false, + bool StdNamespaceIsAssociated = false); // Emit as a 'note' the specific overload candidate void NoteOverloadCandidate(FunctionDecl *Fn); @@ -1276,10 +1414,18 @@ public: bool Complain, DeclAccessPair &Found); - FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From, + FunctionDecl *ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain = false, DeclAccessPair* Found = 0); + ExprResult ResolveAndFixSingleFunctionTemplateSpecialization( + Expr *SrcExpr, bool DoFunctionPointerConverion = false, + bool Complain = false, + const SourceRange& OpRangeForComplaining = SourceRange(), + QualType DestTypeForComplaining = QualType(), + unsigned DiagIDForComplaining = 0); + + Expr *FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl, FunctionDecl *Fn); @@ -1444,15 +1590,16 @@ public: QualType T1, QualType T2, UnresolvedSetImpl &Functions); - LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, - bool isLocalLabel = false); - + LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, + SourceLocation GnuLabelLoc = SourceLocation()); + DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); void ArgumentDependentLookup(DeclarationName Name, bool Operator, Expr **Args, unsigned NumArgs, - ADLResult &Functions); + ADLResult &Functions, + bool StdNamespaceIsAssociated = false); void LookupVisibleDecls(Scope *S, LookupNameKind Kind, VisibleDeclConsumer &Consumer, @@ -1695,6 +1842,7 @@ public: /// initialization. void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI, llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars); + //===--------------------------------------------------------------------===// // Statement Parsing Callbacks: SemaStmt.cpp. public: @@ -1734,7 +1882,7 @@ public: StmtResult ActOnExprStmt(FullExprArg Expr); StmtResult ActOnNullStmt(SourceLocation SemiLoc, - bool LeadingEmptyMacro = false); + SourceLocation LeadingEmptyMacroLoc = SourceLocation()); StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, MultiStmtArg Elts, bool isStmtExpr); @@ -1782,6 +1930,17 @@ public: SourceLocation LParenLoc, Stmt *First, Expr *Second, SourceLocation RParenLoc, Stmt *Body); + StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, + SourceLocation LParenLoc, Stmt *LoopVar, + SourceLocation ColonLoc, Expr *Collection, + SourceLocation RParenLoc); + StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, + SourceLocation ColonLoc, + Stmt *RangeDecl, Stmt *BeginEndDecl, + Expr *Cond, Expr *Inc, + Stmt *LoopVarDecl, + SourceLocation RParenLoc); + StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body); StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, @@ -1811,7 +1970,8 @@ public: VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, - IdentifierInfo *Name, SourceLocation NameLoc, + SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, bool Invalid = false); Decl *ActOnObjCExceptionDecl(Scope *S, Declarator &D); @@ -1831,16 +1991,29 @@ public: Expr *SynchExpr, Stmt *SynchBody); - VarDecl *BuildExceptionDeclaration(Scope *S, - TypeSourceInfo *TInfo, - IdentifierInfo *Name, - SourceLocation Loc); + VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, + SourceLocation StartLoc, + SourceLocation IdLoc, + IdentifierInfo *Id); Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D); StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock); StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, MultiStmtArg Handlers); + + StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? + SourceLocation TryLoc, + Stmt *TryBlock, + Stmt *Handler); + + StmtResult ActOnSEHExceptBlock(SourceLocation Loc, + Expr *FilterExpr, + Stmt *Block); + + StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, + Stmt *Block); + void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const; @@ -1870,7 +2043,8 @@ public: } void EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, - SourceLocation Loc, bool UnknownObjCClass=false); + SourceLocation Loc, + const ObjCInterfaceDecl *UnknownObjCClass=0); void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); @@ -1878,7 +2052,8 @@ public: // Expression Parsing Callbacks: SemaExpr.cpp. bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, - bool UnknownObjCClass=false); + const ObjCInterfaceDecl *UnknownObjCClass=0); + std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc); @@ -1906,6 +2081,10 @@ public: // Primary Expressions. SourceRange getExprRange(Expr *E) const; + ObjCIvarDecl *SynthesizeProvisionalIvar(LookupResult &Lookup, + IdentifierInfo *II, + SourceLocation NameLoc); + ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, UnqualifiedId &Name, bool HasTrailingLParen, bool IsAddressOfOperand); @@ -1971,6 +2150,20 @@ public: /// fragments (e.g. "foo" "bar" L"baz"). ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks); + ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc, + SourceLocation DefaultLoc, + SourceLocation RParenLoc, + Expr *ControllingExpr, + MultiTypeArg Types, + MultiExprArg Exprs); + ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, + SourceLocation DefaultLoc, + SourceLocation RParenLoc, + Expr *ControllingExpr, + TypeSourceInfo **Types, + Expr **Exprs, + unsigned NumAssocs); + // Binary/Unary Operators. 'Tok' is the token for the operator. ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputArg); @@ -1979,19 +2172,25 @@ public: ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input); - ExprResult CreateSizeOfAlignOfExpr(TypeSourceInfo *T, - SourceLocation OpLoc, - bool isSizeOf, SourceRange R); - ExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc, - bool isSizeOf, SourceRange R); + ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *T, + SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + SourceRange R); + ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + SourceRange R); ExprResult - ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, - void *TyOrEx, const SourceRange &ArgRange); + ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, + UnaryExprOrTypeTrait ExprKind, + bool isType, void *TyOrEx, + const SourceRange &ArgRange); - ExprResult CheckPlaceholderExpr(Expr *E, SourceLocation Loc); + ExprResult CheckPlaceholderExpr(Expr *E); + bool CheckVecStepExpr(Expr *E, SourceLocation OpLoc, SourceRange R); - bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, - SourceRange R, bool isSizeof); + bool CheckUnaryExprOrTypeTraitOperand(QualType type, SourceLocation OpLoc, + SourceRange R, + UnaryExprOrTypeTrait ExprKind); ExprResult ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, @@ -2020,7 +2219,7 @@ public: const TemplateArgumentListInfo *TemplateArgs, bool SuppressQualifierCheck = false); - ExprResult LookupMemberExpr(LookupResult &R, Expr *&Base, + ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, Decl *ObjCImpDecl, @@ -2163,6 +2362,8 @@ public: // __null ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc); + bool CheckCaseExpression(Expr *expr); + //===------------------------- "Block" Extension ------------------------===// /// ActOnBlockStart - This callback is invoked when a block literal is @@ -2186,6 +2387,7 @@ public: // Act on C++ namespaces Decl *ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, + SourceLocation NamespaceLoc, SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, @@ -2250,6 +2452,11 @@ public: AttributeList *AttrList, bool IsTypeName, SourceLocation TypenameLoc); + Decl *ActOnAliasDeclaration(Scope *CurScope, + AccessSpecifier AS, + SourceLocation UsingLoc, + UnqualifiedId &Name, + TypeResult Type); /// AddCXXDirectInitializerToDecl - This action is called immediately after /// ActOnDeclarator, when a C++ direct initializer is present. @@ -2444,7 +2651,7 @@ public: //// ActOnCXXThrow - Parse throw expressions. ExprResult ActOnCXXThrow(SourceLocation OpLoc, Expr *expr); - bool CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E); + ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E); /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. /// Can be interpreted either as function-style casting ("int(x)") @@ -2542,6 +2749,32 @@ public: TypeSourceInfo *RhsT, SourceLocation RParen); + /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support + /// pseudo-functions. + ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, + SourceLocation KWLoc, + ParsedType LhsTy, + Expr *DimExpr, + SourceLocation RParen); + + ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, + SourceLocation KWLoc, + TypeSourceInfo *TSInfo, + Expr *DimExpr, + SourceLocation RParen); + + /// ActOnExpressionTrait - Parsed one of the unary type trait support + /// pseudo-functions. + ExprResult ActOnExpressionTrait(ExpressionTrait OET, + SourceLocation KWLoc, + Expr *Queried, + SourceLocation RParen); + + ExprResult BuildExpressionTrait(ExpressionTrait OET, + SourceLocation KWLoc, + Expr *Queried, + SourceLocation RParen); + ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, @@ -2659,25 +2892,41 @@ public: ParsedType ObjectType, bool EnteringContext); - /// \brief The parser has parsed a nested-name-specifier 'type::'. + /// \brief The parser has parsed a nested-name-specifier + /// 'template[opt] template-name < template-args >::'. /// /// \param S The scope in which this nested-name-specifier occurs. /// - /// \param Type The type, which will be a template specialization - /// type, preceding the '::'. - /// - /// \param CCLoc The location of the '::'. + /// \param TemplateLoc The location of the 'template' keyword, if any. /// /// \param SS The nested-name-specifier, which is both an input /// parameter (the nested-name-specifier before this type) and an /// output parameter (containing the full nested-name-specifier, /// including this new type). + /// + /// \param TemplateLoc the location of the 'template' keyword, if any. + /// \param TemplateName The template name. + /// \param TemplateNameLoc The location of the template name. + /// \param LAngleLoc The location of the opening angle bracket ('<'). + /// \param TemplateArgs The template arguments. + /// \param RAngleLoc The location of the closing angle bracket ('>'). + /// \param CCLoc The location of the '::'. + + /// \param EnteringContext Whether we're entering the context of the + /// nested-name-specifier. + /// /// /// \returns true if an error occurred, false otherwise. bool ActOnCXXNestedNameSpecifier(Scope *S, - ParsedType Type, + SourceLocation TemplateLoc, + CXXScopeSpec &SS, + TemplateTy Template, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgs, + SourceLocation RAngleLoc, SourceLocation CCLoc, - CXXScopeSpec &SS); + bool EnteringContext); /// \brief Given a C++ nested-name-specifier, produce an annotation value /// that the parser can use later to reconstruct the given @@ -2818,10 +3067,13 @@ public: MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr **Args, unsigned NumArgs, + SourceLocation BaseLoc, SourceLocation RParenLoc, SourceLocation LParenLoc, - CXXRecordDecl *ClassDecl, - SourceLocation EllipsisLoc); + CXXRecordDecl *ClassDecl); + + bool SetDelegatingInitializer(CXXConstructorDecl *Constructor, + CXXCtorInitializer *Initializer); bool SetCtorInitializers(CXXConstructorDecl *Constructor, CXXCtorInitializer **Initializers, @@ -2887,15 +3139,19 @@ public: AttributeList *AttrList); void ActOnReenterTemplateScope(Scope *S, Decl *Template); + void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D); void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); + void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true); + bool IsInsideALocalClassWithinATemplateFunction(); - Decl *ActOnStaticAssertDeclaration(SourceLocation AssertLoc, + Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, - Expr *AssertMessageExpr); + Expr *AssertMessageExpr, + SourceLocation RParenLoc); FriendDecl *CheckFriendTypeDecl(SourceLocation FriendLoc, TypeSourceInfo *TSInfo); @@ -3071,18 +3327,21 @@ public: //===--------------------------------------------------------------------===// // C++ Templates [C++ 14] // + void FilterAcceptableTemplateNames(LookupResult &R); + bool hasAnyAcceptableTemplateNames(LookupResult &R); + void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, bool EnteringContext, bool &MemberOfUnknownSpecialization); TemplateNameKind isTemplateName(Scope *S, - CXXScopeSpec &SS, - bool hasTemplateKeyword, - UnqualifiedId &Name, - ParsedType ObjectType, - bool EnteringContext, - TemplateTy &Template, - bool &MemberOfUnknownSpecialization); + CXXScopeSpec &SS, + bool hasTemplateKeyword, + UnqualifiedId &Name, + ParsedType ObjectType, + bool EnteringContext, + TemplateTy &Template, + bool &MemberOfUnknownSpecialization); bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, SourceLocation IILoc, @@ -3155,27 +3414,41 @@ public: IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, TemplateParameterList *TemplateParams, - AccessSpecifier AS); + AccessSpecifier AS, + unsigned NumOuterTemplateParamLists, + TemplateParameterList **OuterTemplateParamLists); void translateTemplateArguments(const ASTTemplateArgsPtr &In, TemplateArgumentListInfo &Out); + void NoteAllFoundTemplates(TemplateName Name); + QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, - const TemplateArgumentListInfo &TemplateArgs); + TemplateArgumentListInfo &TemplateArgs); TypeResult - ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc, + ActOnTemplateIdType(CXXScopeSpec &SS, + TemplateTy Template, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc); - TypeResult ActOnTagTemplateIdType(CXXScopeSpec &SS, - TypeResult Type, - TagUseKind TUK, + /// \brief Parsed an elaborated-type-specifier that refers to a template-id, + /// such as \c class T::template apply<U>. + /// + /// \param TUK + TypeResult ActOnTagTemplateIdType(TagUseKind TUK, TypeSpecifierType TagSpec, - SourceLocation TagLoc); + SourceLocation TagLoc, + CXXScopeSpec &SS, + TemplateTy TemplateD, + SourceLocation TemplateLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgsIn, + SourceLocation RAngleLoc); + ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, LookupResult &R, bool RequiresADL, @@ -3225,7 +3498,7 @@ public: LookupResult &Previous); bool CheckFunctionTemplateSpecialization(FunctionDecl *FD, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, LookupResult &Previous); bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous); @@ -3291,9 +3564,30 @@ public: llvm::SmallVectorImpl<TemplateArgument> &Converted, CheckTemplateArgumentKind CTAK = CTAK_Specified); + /// \brief Check that the given template arguments can be be provided to + /// the given template, converting the arguments along the way. + /// + /// \param Template The template to which the template arguments are being + /// provided. + /// + /// \param TemplateLoc The location of the template name in the source. + /// + /// \param TemplateArgs The list of template arguments. If the template is + /// a template template parameter, this function may extend the set of + /// template arguments to also include substituted, defaulted template + /// arguments. + /// + /// \param PartialTemplateArgs True if the list of template arguments is + /// intentionally partial, e.g., because we're checking just the initial + /// set of template arguments. + /// + /// \param Converted Will receive the converted, canonicalized template + /// arguments. + /// + /// \returns True if an error occurred, false otherwise. bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, - const TemplateArgumentListInfo &TemplateArgs, + TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, llvm::SmallVectorImpl<TemplateArgument> &Converted); @@ -3305,10 +3599,10 @@ public: TypeSourceInfo *Arg); bool CheckTemplateArgumentPointerToMember(Expr *Arg, TemplateArgument &Converted); - bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param, - QualType InstantiatedParamType, Expr *&Arg, - TemplateArgument &Converted, - CheckTemplateArgumentKind CTAK = CTAK_Specified); + ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param, + QualType InstantiatedParamType, Expr *Arg, + TemplateArgument &Converted, + CheckTemplateArgumentKind CTAK = CTAK_Specified); bool CheckTemplateArgument(TemplateTemplateParmDecl *Param, const TemplateArgumentLoc &Arg); @@ -3384,17 +3678,25 @@ public: /// \param TypenameLoc the location of the 'typename' keyword /// \param SS the nested-name-specifier following the typename (e.g., 'T::'). /// \param TemplateLoc the location of the 'template' keyword, if any. - /// \param Ty the type that the typename specifier refers to. + /// \param TemplateName The template name. + /// \param TemplateNameLoc The location of the template name. + /// \param LAngleLoc The location of the opening angle bracket ('<'). + /// \param TemplateArgs The template arguments. + /// \param RAngleLoc The location of the closing angle bracket ('>'). TypeResult ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, - const CXXScopeSpec &SS, SourceLocation TemplateLoc, - ParsedType Ty); + const CXXScopeSpec &SS, + SourceLocation TemplateLoc, + TemplateTy Template, + SourceLocation TemplateNameLoc, + SourceLocation LAngleLoc, + ASTTemplateArgsPtr TemplateArgs, + SourceLocation RAngleLoc); QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, - const IdentifierInfo &II, SourceLocation KeywordLoc, - SourceRange NNSRange, + NestedNameSpecifierLoc QualifierLoc, + const IdentifierInfo &II, SourceLocation IILoc); TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, @@ -3480,7 +3782,7 @@ public: /// \param T The type that is being checked for unexpanded parameter /// packs. /// - /// \returns true if an error ocurred, false otherwise. + /// \returns true if an error occurred, false otherwise. bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC); @@ -3490,7 +3792,7 @@ public: /// \param E The expression that is being checked for unexpanded /// parameter packs. /// - /// \returns true if an error ocurred, false otherwise. + /// \returns true if an error occurred, false otherwise. bool DiagnoseUnexpandedParameterPack(Expr *E, UnexpandedParameterPackContext UPPC = UPPC_Expression); @@ -3500,7 +3802,7 @@ public: /// \param SS The nested-name-specifier that is being checked for /// unexpanded parameter packs. /// - /// \returns true if an error ocurred, false otherwise. + /// \returns true if an error occurred, false otherwise. bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, UnexpandedParameterPackContext UPPC); @@ -3510,7 +3812,7 @@ public: /// \param NameInfo The name (with source location information) that /// is being checked for unexpanded parameter packs. /// - /// \returns true if an error ocurred, false otherwise. + /// \returns true if an error occurred, false otherwise. bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, UnexpandedParameterPackContext UPPC); @@ -3522,7 +3824,7 @@ public: /// \param Template The template name that is being checked for unexpanded /// parameter packs. /// - /// \returns true if an error ocurred, false otherwise. + /// \returns true if an error occurred, false otherwise. bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TemplateName Template, UnexpandedParameterPackContext UPPC); @@ -3533,7 +3835,7 @@ public: /// \param Arg The template argument that is being checked for unexpanded /// parameter packs. /// - /// \returns true if an error ocurred, false otherwise. + /// \returns true if an error occurred, false otherwise. bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, UnexpandedParameterPackContext UPPC); @@ -3751,7 +4053,7 @@ public: TemplateDeductionResult SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - const TemplateArgumentListInfo &ExplicitTemplateArgs, + TemplateArgumentListInfo &ExplicitTemplateArgs, llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced, llvm::SmallVectorImpl<QualType> &ParamTypes, QualType *FunctionType, @@ -3766,14 +4068,14 @@ public: TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, Expr **Args, unsigned NumArgs, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ArgFunctionType, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info); @@ -3786,11 +4088,12 @@ public: TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, - const TemplateArgumentListInfo *ExplicitTemplateArgs, + TemplateArgumentListInfo *ExplicitTemplateArgs, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info); - bool DeduceAutoType(QualType AutoType, Expr *Initializer, QualType &Result); + bool DeduceAutoType(TypeSourceInfo *AutoType, Expr *Initializer, + TypeSourceInfo *&Result); FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, @@ -4204,7 +4507,7 @@ public: /// types, static variables, enumerators, etc. std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations; - void PerformPendingInstantiations(bool LocalOnly = false); + bool PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, @@ -4224,6 +4527,7 @@ public: DeclarationName Entity); ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, + int indexAdjustment, llvm::Optional<unsigned> NumExpansions); bool SubstParmTypes(SourceLocation Loc, ParmVarDecl **Params, unsigned NumParams, @@ -4289,11 +4593,6 @@ public: ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK); - NestedNameSpecifier * - SubstNestedNameSpecifier(NestedNameSpecifier *NNS, - SourceRange Range, - const MultiLevelTemplateArgumentList &TemplateArgs); - NestedNameSpecifierLoc SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -4302,7 +4601,8 @@ public: SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo, const MultiLevelTemplateArgumentList &TemplateArgs); TemplateName - SubstTemplateName(TemplateName Name, SourceLocation Loc, + SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name, + SourceLocation Loc, const MultiLevelTemplateArgumentList &TemplateArgs); bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs, TemplateArgumentListInfo &Result, @@ -4475,7 +4775,7 @@ public: ObjCArgInfo *ArgInfo, DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind, - bool isVariadic = false); + bool isVariadic, bool MethodDefinition); // Helper method for ActOnClassMethod/ActOnInstanceMethod. // Will search "local" class/category implementations for a method decl. @@ -4485,6 +4785,9 @@ public: ObjCInterfaceDecl *CDecl); ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel, ObjCInterfaceDecl *ClassDecl); + ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, + const ObjCObjectPointerType *OPT, + bool IsInstance); ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, @@ -4586,6 +4889,11 @@ public: PPK_Pop // #pragma pack(pop, [identifier], [n]) }; + enum PragmaMSStructKind { + PMSST_OFF, // #pragms ms_struct off + PMSST_ON // #pragms ms_struct on + }; + /// ActOnPragmaPack - Called on well formed #pragma pack(...). void ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, @@ -4593,6 +4901,9 @@ public: SourceLocation PragmaLoc, SourceLocation LParenLoc, SourceLocation RParenLoc); + + /// ActOnPragmaMSStruct - Called on well formed #pragms ms_struct [on|off]. + void ActOnPragmaMSStruct(PragmaMSStructKind Kind); /// ActOnPragmaUnused - Called on well-formed '#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, @@ -4626,6 +4937,9 @@ public: /// a the record decl, to handle '#pragma pack' and '#pragma options align'. void AddAlignmentAttributesForRecord(RecordDecl *RD); + /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record. + void AddMsStructLayoutForRecord(RecordDecl *RD); + /// FreePackedContext - Deallocate and null out PackContext. void FreePackedContext(); @@ -4655,38 +4969,42 @@ public: /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit /// cast. If there is already an implicit cast, merge into the existing one. /// If isLvalue, the result of the cast is an lvalue. - void ImpCastExprToType(Expr *&Expr, QualType Type, CastKind CK, - ExprValueKind VK = VK_RValue, - const CXXCastPath *BasePath = 0); + ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, + ExprValueKind VK = VK_RValue, + const CXXCastPath *BasePath = 0); + + /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding + /// to the conversion from scalar type ScalarTy to the Boolean type. + static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy); /// IgnoredValueConversions - Given that an expression's result is /// syntactically ignored, perform any conversions that are /// required. - void IgnoredValueConversions(Expr *&expr); + ExprResult IgnoredValueConversions(Expr *E); // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts // functions and arrays to their respective pointers (C99 6.3.2.1). - Expr *UsualUnaryConversions(Expr *&expr); + ExprResult UsualUnaryConversions(Expr *E); // DefaultFunctionArrayConversion - converts functions and arrays // to their respective pointers (C99 6.3.2.1). - void DefaultFunctionArrayConversion(Expr *&expr); + ExprResult DefaultFunctionArrayConversion(Expr *E); // DefaultFunctionArrayLvalueConversion - converts functions and // arrays to their respective pointers and performs the // lvalue-to-rvalue conversion. - void DefaultFunctionArrayLvalueConversion(Expr *&expr); + ExprResult DefaultFunctionArrayLvalueConversion(Expr *E); // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on // the operand. This is DefaultFunctionArrayLvalueConversion, // except that it assumes the operand isn't of function or array // type. - void DefaultLvalueConversion(Expr *&expr); + ExprResult DefaultLvalueConversion(Expr *E); // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that // do not have a prototype. Integer promotions are performed on each // argument, and arguments that have type float are promoted to double. - void DefaultArgumentPromotion(Expr *&Expr); + ExprResult DefaultArgumentPromotion(Expr *E); // Used for emitting the right warning by DefaultVariadicArgumentPromotion enum VariadicCallType { @@ -4709,15 +5027,15 @@ public: // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but // will warn if the resulting type is not a POD type. - bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT, - FunctionDecl *FDecl); + ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, + FunctionDecl *FDecl); // UsualArithmeticConversions - performs the UsualUnaryConversions on it's // operands and then handles various conversions that are common to binary // operators (C99 6.3.1.8). If both operands aren't arithmetic, this // routine returns the first non-arithmetic type found. The client is // responsible for emitting appropriate error diagnostics. - QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr, + QualType UsualArithmeticConversions(ExprResult &lExpr, ExprResult &rExpr, bool isCompAssign = false); /// AssignConvertType - All of the 'assignment' semantic checks return this @@ -4805,94 +5123,102 @@ public: /// Check assignment constraints and prepare for a conversion of the /// RHS to the LHS type. - AssignConvertType CheckAssignmentConstraints(QualType lhs, Expr *&rhs, + AssignConvertType CheckAssignmentConstraints(QualType lhs, ExprResult &rhs, CastKind &Kind); // CheckSingleAssignmentConstraints - Currently used by // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, // this routine performs the default function/array converions. AssignConvertType CheckSingleAssignmentConstraints(QualType lhs, - Expr *&rExpr); + ExprResult &rExprRes); // \brief If the lhs type is a transparent union, check whether we // can initialize the transparent union with the given expression. AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs, - Expr *&rExpr); + ExprResult &rExpr); bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType); bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType); - bool PerformImplicitConversion(Expr *&From, QualType ToType, - AssignmentAction Action, - bool AllowExplicit = false); - bool PerformImplicitConversion(Expr *&From, QualType ToType, - AssignmentAction Action, - bool AllowExplicit, - ImplicitConversionSequence& ICS); - bool PerformImplicitConversion(Expr *&From, QualType ToType, - const ImplicitConversionSequence& ICS, - AssignmentAction Action, - bool CStyle = false); - bool PerformImplicitConversion(Expr *&From, QualType ToType, - const StandardConversionSequence& SCS, - AssignmentAction Action, - bool CStyle); + ExprResult PerformImplicitConversion(Expr *From, QualType ToType, + AssignmentAction Action, + bool AllowExplicit = false); + ExprResult PerformImplicitConversion(Expr *From, QualType ToType, + AssignmentAction Action, + bool AllowExplicit, + ImplicitConversionSequence& ICS); + ExprResult PerformImplicitConversion(Expr *From, QualType ToType, + const ImplicitConversionSequence& ICS, + AssignmentAction Action, + bool CStyle = false); + ExprResult PerformImplicitConversion(Expr *From, QualType ToType, + const StandardConversionSequence& SCS, + AssignmentAction Action, + bool CStyle); /// the following "Check" methods will return a valid/converted QualType /// or a null QualType (indicating an error diagnostic was issued). /// type checking binary operators (subroutines of CreateBuiltinBinOp). - QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex); + QualType InvalidOperands(SourceLocation l, ExprResult &lex, ExprResult &rex); QualType CheckPointerToMemberOperands( // C++ 5.5 - Expr *&lex, Expr *&rex, ExprValueKind &VK, + ExprResult &lex, ExprResult &rex, ExprValueKind &VK, SourceLocation OpLoc, bool isIndirect); QualType CheckMultiplyDivideOperands( // C99 6.5.5 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign, + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign, bool isDivide); QualType CheckRemainderOperands( // C99 6.5.5 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false); + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false); QualType CheckAdditionOperands( // C99 6.5.6 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0); + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0); QualType CheckSubtractionOperands( // C99 6.5.6 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0); + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0); QualType CheckShiftOperands( // C99 6.5.7 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc, + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc, bool isCompAssign = false); QualType CheckCompareOperands( // C99 6.5.8/9 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc, + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc, bool isRelational); QualType CheckBitwiseOperands( // C99 6.5.[10...12] - Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false); + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false); QualType CheckLogicalOperands( // C99 6.5.[13,14] - Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc); + ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc); // CheckAssignmentOperands is used for both simple and compound assignment. // For simple assignment, pass both expressions and a null converted type. // For compound assignment, pass both expressions and the converted type. QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] - Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType); + Expr *lex, ExprResult &rex, SourceLocation OpLoc, QualType convertedType); - void ConvertPropertyForRValue(Expr *&E); - void ConvertPropertyForLValue(Expr *&LHS, Expr *&RHS, QualType& LHSTy); + void ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, QualType& LHSTy); + ExprResult ConvertPropertyForRValue(Expr *E); QualType CheckConditionalOperands( // C99 6.5.15 - Expr *&cond, Expr *&lhs, Expr *&rhs, + ExprResult &cond, ExprResult &lhs, ExprResult &rhs, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); QualType CXXCheckConditionalOperands( // C++ 5.16 - Expr *&cond, Expr *&lhs, Expr *&rhs, + ExprResult &cond, ExprResult &lhs, ExprResult &rhs, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, bool *NonStandardCompositeType = 0); + QualType FindCompositePointerType(SourceLocation Loc, ExprResult &E1, ExprResult &E2, + bool *NonStandardCompositeType = 0) { + Expr *E1Tmp = E1.take(), *E2Tmp = E2.take(); + QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp, NonStandardCompositeType); + E1 = Owned(E1Tmp); + E2 = Owned(E2Tmp); + return Composite; + } - QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, + QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation questionLoc); bool DiagnoseConditionalForNull(Expr *LHS, Expr *RHS, SourceLocation QuestionLoc); /// type checking for vector binary operators. - QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex); - QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx, + QualType CheckVectorOperands(SourceLocation l, ExprResult &lex, ExprResult &rex); + QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx, SourceLocation l, bool isRel); /// type checking declaration initializers (C99 6.7.8) @@ -4930,9 +5256,13 @@ public: /// CheckCastTypes - Check type constraints for casting between types under /// C semantics, or forward to CXXCheckCStyleCast in C++. - bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath, - bool FunctionalStyle = false); + ExprResult CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *CastExpr, + CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath, + bool FunctionalStyle = false); + + ExprResult checkUnknownAnyCast(SourceRange TyRange, QualType castType, + Expr *castExpr, CastKind &castKind, + ExprValueKind &valueKind, CXXCastPath &BasePath); // CheckVectorCast - check type constraints for vectors. // Since vectors are an extension, there are no C standard reference for this. @@ -4945,15 +5275,15 @@ public: // Since vectors are an extension, there are no C standard reference for this. // We allow casting between vectors and integer datatypes of the same size, // or vectors and the element type of that vector. - // returns true if the cast is invalid - bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr, - CastKind &Kind); + // returns the cast expr + ExprResult CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *CastExpr, + CastKind &Kind); /// CXXCheckCStyleCast - Check constraints of a C-style or function-style /// cast under C++ semantics. - bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, - Expr *&CastExpr, CastKind &Kind, - CXXCastPath &BasePath, bool FunctionalStyle); + ExprResult CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, + Expr *CastExpr, CastKind &Kind, + CXXCastPath &BasePath, bool FunctionalStyle); /// CheckMessageArgumentTypes - Check types in an Obj-C message send. /// \param Method - May be null. @@ -4972,7 +5302,7 @@ public: /// \param Loc - A location associated with the condition, e.g. the /// 'if' keyword. /// \return true iff there were any errors - bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc); + ExprResult CheckBooleanCondition(Expr *CondExpr, SourceLocation Loc); ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, Expr *SubExpr); @@ -4986,7 +5316,7 @@ public: void DiagnoseEqualityWithExtraParens(ParenExpr *parenE); /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. - bool CheckCXXBooleanCondition(Expr *&CondExpr); + ExprResult CheckCXXBooleanCondition(Expr *CondExpr); /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have /// the specified width and sign. If an overflow occurs, detect it and emit @@ -5174,7 +5504,7 @@ public: unsigned ByteNo) const; private: - void CheckArrayAccess(const ArraySubscriptExpr *E); + void CheckArrayAccess(const Expr *E); bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall); @@ -5210,12 +5540,15 @@ private: bool isPrintf); void CheckNonNullArguments(const NonNullAttr *NonNull, - const CallExpr *TheCall); + const Expr * const *ExprArgs, + SourceLocation CallSiteLoc); void CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, bool isPrintf); + void CheckMemsetArguments(const CallExpr *Call); + void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc); void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex); diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index ae5aa33..83c0999 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -15,7 +15,8 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ + SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" #undef DIAG diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 53f4a9d..4d97f9b 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -335,7 +335,9 @@ namespace clang { Decl *VisitLabelDecl(LabelDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); + Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); Decl *VisitTypedefDecl(TypedefDecl *D); + Decl *VisitTypeAliasDecl(TypeAliasDecl *D); Decl *VisitVarDecl(VarDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitFieldDecl(FieldDecl *D); diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 7cc3571..c666979 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -56,7 +56,7 @@ public: } /// \brief Returns the location at which template argument is - /// occuring. + /// occurring. SourceLocation getLocation() const { return Loc; } |