diff options
Diffstat (limited to 'include/clang/Sema')
-rw-r--r-- | include/clang/Sema/AttributeList.h | 81 | ||||
-rw-r--r-- | include/clang/Sema/CodeCompleteConsumer.h | 142 | ||||
-rw-r--r-- | include/clang/Sema/CodeCompleteOptions.h | 37 | ||||
-rw-r--r-- | include/clang/Sema/DeclSpec.h | 188 | ||||
-rw-r--r-- | include/clang/Sema/DelayedDiagnostic.h | 66 | ||||
-rw-r--r-- | include/clang/Sema/Designator.h | 8 | ||||
-rw-r--r-- | include/clang/Sema/Initialization.h | 8 | ||||
-rw-r--r-- | include/clang/Sema/Overload.h | 23 | ||||
-rw-r--r-- | include/clang/Sema/ParsedTemplate.h | 10 | ||||
-rw-r--r-- | include/clang/Sema/Scope.h | 4 | ||||
-rw-r--r-- | include/clang/Sema/ScopeInfo.h | 19 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 1016 | ||||
-rw-r--r-- | include/clang/Sema/Template.h | 11 | ||||
-rw-r--r-- | include/clang/Sema/TemplateDeduction.h | 39 | ||||
-rw-r--r-- | include/clang/Sema/Weak.h | 2 |
15 files changed, 1075 insertions, 579 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 142f144..5239044 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -52,6 +52,16 @@ struct AvailabilityChange { /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. /// class AttributeList { // TODO: This should really be called ParsedAttribute +public: + /// The style used to specify an attribute. + enum Syntax { + AS_GNU, + AS_CXX11, + AS_Declspec, + // eg) __w64, __ptr32, etc. It is implied that an MSTypespec is also + // a declspec. + AS_MSTypespec + }; private: IdentifierInfo *AttrName; IdentifierInfo *ScopeName; @@ -64,11 +74,8 @@ private: /// 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; + /// Corresponds to the Syntax enum. + unsigned SyntaxUsed : 2; /// True if already diagnosed as invalid. mutable unsigned Invalid : 1; @@ -123,15 +130,14 @@ private: IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, - bool declspec, bool cxx0x) + Syntax syntaxUsed) : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - NumArgs(numArgs), - DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false), + NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), NextInPosition(0), NextInPool(0) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); - AttrKind = getKind(getName()); + AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } AttributeList(IdentifierInfo *attrName, SourceRange attrRange, @@ -142,17 +148,17 @@ private: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, - bool declspec, bool cxx0x) + Syntax syntaxUsed) : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - NumArgs(0), DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), + NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), UnavailableLoc(unavailable), MessageExpr(messageExpr), NextInPosition(0), NextInPool(0) { new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); - AttrKind = getKind(getName()); + AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } friend class AttributePool; @@ -162,17 +168,6 @@ public: enum Kind { #define PARSED_ATTR(NAME) AT_##NAME, #include "clang/Sema/AttrParsedAttrList.inc" - PARSED_ATTR(address_space) - PARSED_ATTR(base_check) - PARSED_ATTR(cf_returns_autoreleased) - PARSED_ATTR(ext_vector_type) - PARSED_ATTR(mode) - PARSED_ATTR(neon_polyvector_type) - PARSED_ATTR(neon_vector_type) - PARSED_ATTR(objc_gc) - PARSED_ATTR(objc_ownership) - PARSED_ATTR(opencl_image_access) - PARSED_ATTR(vector_size) #undef PARSED_ATTR IgnoredAttribute, UnknownAttribute @@ -189,8 +184,12 @@ public: IdentifierInfo *getParameterName() const { return ParmName; } SourceLocation getParameterLoc() const { return ParmLoc; } - bool isDeclspecAttribute() const { return DeclspecAttribute; } - bool isCXX0XAttribute() const { return CXX0XAttribute; } + /// Returns true if the attribute is a pure __declspec or a synthesized + /// declspec representing a type specification (like __w64 or __ptr32). + bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec || + SyntaxUsed == AS_MSTypespec; } + bool isCXX0XAttribute() const { return SyntaxUsed == AS_CXX11; } + bool isMSTypespecAttribute() const { return SyntaxUsed == AS_MSTypespec; } bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } @@ -199,7 +198,8 @@ public: void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } Kind getKind() const { return Kind(AttrKind); } - static Kind getKind(const IdentifierInfo *Name); + static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope, + Syntax SyntaxUsed); AttributeList *getNext() const { return NextInPosition; } void setNext(AttributeList *N) { NextInPosition = N; } @@ -256,27 +256,27 @@ public: } const AvailabilityChange &getAvailabilityIntroduced() const { - assert(getKind() == AT_availability && "Not an availability attribute"); + assert(getKind() == AT_Availability && "Not an availability attribute"); return getAvailabilitySlot(IntroducedSlot); } const AvailabilityChange &getAvailabilityDeprecated() const { - assert(getKind() == AT_availability && "Not an availability attribute"); + assert(getKind() == AT_Availability && "Not an availability attribute"); return getAvailabilitySlot(DeprecatedSlot); } const AvailabilityChange &getAvailabilityObsoleted() const { - assert(getKind() == AT_availability && "Not an availability attribute"); + assert(getKind() == AT_Availability && "Not an availability attribute"); return getAvailabilitySlot(ObsoletedSlot); } SourceLocation getUnavailableLoc() const { - assert(getKind() == AT_availability && "Not an availability attribute"); + assert(getKind() == AT_Availability && "Not an availability attribute"); return UnavailableLoc; } const Expr * getMessageExpr() const { - assert(getKind() == AT_availability && "Not an availability attribute"); + assert(getKind() == AT_Availability && "Not an availability attribute"); return MessageExpr; } }; @@ -383,14 +383,13 @@ public: IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, - bool declspec = false, bool cxx0x = false) { + AttributeList::Syntax syntax) { void *memory = allocate(sizeof(AttributeList) + numArgs * sizeof(Expr*)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, - declspec, cxx0x)); + args, numArgs, syntax)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, @@ -401,14 +400,13 @@ public: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, - bool declspec = false, bool cxx0x = false) { + AttributeList::Syntax syntax) { void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, introduced, deprecated, obsoleted, - unavailable, MessageExpr, - declspec, cxx0x)); + unavailable, MessageExpr, syntax)); } AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, @@ -510,10 +508,10 @@ public: IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, - bool declspec = false, bool cxx0x = false) { + AttributeList::Syntax syntax) { AttributeList *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, declspec, cxx0x); + args, numArgs, syntax); add(attr); return attr; } @@ -526,12 +524,11 @@ public: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, - bool declspec = false, bool cxx0x = false) { + AttributeList::Syntax syntax) { AttributeList *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, introduced, deprecated, obsoleted, unavailable, - MessageExpr, - declspec, cxx0x); + MessageExpr, syntax); add(attr); return attr; } diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index fe9bed5..d43aaaf 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -15,6 +15,7 @@ #include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" +#include "clang/Sema/CodeCompleteOptions.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" @@ -237,7 +238,7 @@ public: /// This context usually implies that no completions should be added, /// unless they come from an appropriate natural-language dictionary. CCC_NaturalLanguage, - /// \brief Code completion for a selector, as in an @selector expression. + /// \brief Code completion for a selector, as in an \@selector expression. CCC_SelectorName, /// \brief Code completion within a type-qualifier list. CCC_TypeQualifiers, @@ -379,7 +380,7 @@ public: CK_Equal, /// \brief Horizontal whitespace (' '). CK_HorizontalSpace, - /// \brief Verticle whitespace ('\n' or '\r\n', depending on the + /// \brief Vertical whitespace ('\\n' or '\\r\\n', depending on the /// platform). CK_VerticalSpace }; @@ -444,6 +445,10 @@ private: /// \brief The name of the parent context. StringRef ParentName; + + /// \brief A brief documentation comment attached to the declaration of + /// entity being completed by this result. + const char *BriefComment; CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT CodeCompletionString &operator=(const CodeCompletionString &); // DITTO @@ -451,7 +456,8 @@ private: CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, unsigned Priority, CXAvailabilityKind Availability, const char **Annotations, unsigned NumAnnotations, - CXCursorKind ParentKind, StringRef ParentName); + CXCursorKind ParentKind, StringRef ParentName, + const char *BriefComment); ~CodeCompletionString() { } friend class CodeCompletionBuilder; @@ -493,6 +499,10 @@ public: StringRef getParentContextName() const { return ParentName; } + + const char *getBriefComment() const { + return BriefComment; + } /// \brief Retrieve a string representation of the code completion string, /// which is mainly useful for debugging. @@ -569,6 +579,7 @@ private: CXAvailabilityKind Availability; CXCursorKind ParentKind; StringRef ParentName; + const char *BriefComment; /// \brief The chunks stored in this string. SmallVector<Chunk, 4> Chunks; @@ -580,14 +591,14 @@ public: CodeCompletionTUInfo &CCTUInfo) : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(0), Availability(CXAvailability_Available), - ParentKind(CXCursor_NotImplemented) { } + ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { } CodeCompletionBuilder(CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, unsigned Priority, CXAvailabilityKind Availability) : Allocator(Allocator), CCTUInfo(CCTUInfo), Priority(Priority), Availability(Availability), - ParentKind(CXCursor_NotImplemented) { } + ParentKind(CXCursor_NotImplemented), BriefComment(NULL) { } /// \brief Retrieve the allocator into which the code completion /// strings should be allocated. @@ -628,6 +639,8 @@ public: /// \brief Add the parent context information to this code completion. void addParentContext(DeclContext *DC); + + void addBriefComment(StringRef Comment); CXCursorKind getParentKind() const { return ParentKind; } StringRef getParentName() const { return ParentName; } @@ -638,15 +651,12 @@ class CodeCompletionResult { public: /// \brief Describes the kind of result generated. enum ResultKind { - RK_Declaration = 0, //< Refers to a declaration - RK_Keyword, //< Refers to a keyword or symbol. - RK_Macro, //< Refers to a macro - RK_Pattern //< Refers to a precomputed pattern. + RK_Declaration = 0, ///< Refers to a declaration + RK_Keyword, ///< Refers to a keyword or symbol. + RK_Macro, ///< Refers to a macro + RK_Pattern ///< Refers to a precomputed pattern. }; - /// \brief The kind of result stored here. - ResultKind Kind; - /// \brief When Kind == RK_Declaration or RK_Pattern, the declaration we are /// referring to. In the latter case, the declaration might be NULL. NamedDecl *Declaration; @@ -667,16 +677,19 @@ public: /// \brief The priority of this particular code-completion result. unsigned Priority; + /// \brief Specifies which parameter (of a function, Objective-C method, + /// macro, etc.) we should start with when formatting the result. + unsigned StartParameter; + + /// \brief The kind of result stored here. + ResultKind Kind; + /// \brief The cursor kind that describes this result. CXCursorKind CursorKind; /// \brief The availability of this result. CXAvailabilityKind Availability; - /// \brief Specifies which parameter (of a function, Objective-C method, - /// macro, etc.) we should start with when formatting the result. - unsigned StartParameter; - /// \brief Whether this result is hidden by another name. bool Hidden : 1; @@ -705,10 +718,10 @@ public: NestedNameSpecifier *Qualifier = 0, bool QualifierIsInformative = false, bool Accessible = true) - : Kind(RK_Declaration), Declaration(Declaration), - Priority(getPriorityFromDecl(Declaration)), - Availability(CXAvailability_Available), StartParameter(0), - Hidden(false), QualifierIsInformative(QualifierIsInformative), + : Declaration(Declaration), Priority(getPriorityFromDecl(Declaration)), + StartParameter(0), Kind(RK_Declaration), + Availability(CXAvailability_Available), Hidden(false), + QualifierIsInformative(QualifierIsInformative), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(Qualifier) { computeCursorKindAndAvailability(Accessible); @@ -716,22 +729,22 @@ public: /// \brief Build a result that refers to a keyword or symbol. CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword) - : Kind(RK_Keyword), Declaration(0), Keyword(Keyword), Priority(Priority), - Availability(CXAvailability_Available), - StartParameter(0), Hidden(false), QualifierIsInformative(0), - StartsNestedNameSpecifier(false), AllParametersAreInformative(false), - DeclaringEntity(false), Qualifier(0) { - computeCursorKindAndAvailability(); + : Declaration(0), Keyword(Keyword), Priority(Priority), StartParameter(0), + Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented), + Availability(CXAvailability_Available), Hidden(false), + QualifierIsInformative(0), StartsNestedNameSpecifier(false), + AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0) + { } /// \brief Build a result that refers to a macro. CodeCompletionResult(IdentifierInfo *Macro, unsigned Priority = CCP_Macro) - : Kind(RK_Macro), Declaration(0), Macro(Macro), Priority(Priority), - Availability(CXAvailability_Available), StartParameter(0), - Hidden(false), QualifierIsInformative(0), - StartsNestedNameSpecifier(false), AllParametersAreInformative(false), - DeclaringEntity(false), Qualifier(0) { - computeCursorKindAndAvailability(); + : Declaration(0), Macro(Macro), Priority(Priority), StartParameter(0), + Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition), + Availability(CXAvailability_Available), Hidden(false), + QualifierIsInformative(0), StartsNestedNameSpecifier(false), + AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0) + { } /// \brief Build a result that refers to a pattern. @@ -740,8 +753,8 @@ public: CXCursorKind CursorKind = CXCursor_NotImplemented, CXAvailabilityKind Availability = CXAvailability_Available, NamedDecl *D = 0) - : Kind(RK_Pattern), Declaration(D), Pattern(Pattern), Priority(Priority), - CursorKind(CursorKind), Availability(Availability), StartParameter(0), + : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0), + Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0) @@ -752,11 +765,10 @@ public: /// declaration. CodeCompletionResult(CodeCompletionString *Pattern, NamedDecl *D, unsigned Priority) - : Kind(RK_Pattern), Declaration(D), Pattern(Pattern), Priority(Priority), - Availability(CXAvailability_Available), StartParameter(0), - Hidden(false), QualifierIsInformative(false), - StartsNestedNameSpecifier(false), AllParametersAreInformative(false), - DeclaringEntity(false), Qualifier(0) { + : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0), + Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false), + QualifierIsInformative(false), StartsNestedNameSpecifier(false), + AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0) { computeCursorKindAndAvailability(); } @@ -781,11 +793,13 @@ public: /// string itself. CodeCompletionString *CreateCodeCompletionString(Sema &S, CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo); + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments); CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx, Preprocessor &PP, CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo); + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments); /// \brief Determine a base priority for the given declaration. static unsigned getPriorityFromDecl(NamedDecl *ND); @@ -819,16 +833,7 @@ raw_ostream &operator<<(raw_ostream &OS, /// information. class CodeCompleteConsumer { protected: - /// \brief Whether to include macros in the code-completion results. - bool IncludeMacros; - - /// \brief Whether to include code patterns (such as for loops) within - /// the completion results. - bool IncludeCodePatterns; - - /// \brief Whether to include global (top-level) declarations and names in - /// the completion results. - bool IncludeGlobals; + const CodeCompleteOptions CodeCompleteOpts; /// \brief Whether the output format for the code-completion consumer is /// binary. @@ -901,22 +906,31 @@ public: CodeCompletionTUInfo &CCTUInfo) const; }; - CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false), - IncludeGlobals(true), OutputIsBinary(false) { } - - CodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, - bool IncludeGlobals, bool OutputIsBinary) - : IncludeMacros(IncludeMacros), IncludeCodePatterns(IncludeCodePatterns), - IncludeGlobals(IncludeGlobals), OutputIsBinary(OutputIsBinary) { } + CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, + bool OutputIsBinary) + : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) + { } /// \brief Whether the code-completion consumer wants to see macros. - bool includeMacros() const { return IncludeMacros; } + bool includeMacros() const { + return CodeCompleteOpts.IncludeMacros; + } /// \brief Whether the code-completion consumer wants to see code patterns. - bool includeCodePatterns() const { return IncludeCodePatterns; } + bool includeCodePatterns() const { + return CodeCompleteOpts.IncludeCodePatterns; + } /// \brief Whether to include global (top-level) declaration results. - bool includeGlobals() const { return IncludeGlobals; } + bool includeGlobals() const { + return CodeCompleteOpts.IncludeGlobals; + } + + /// \brief Whether to include brief documentation comments within the set of + /// code completions returned. + bool includeBriefComments() const { + return CodeCompleteOpts.IncludeBriefComments; + } /// \brief Determine whether the output of this consumer is binary. bool isOutputBinary() const { return OutputIsBinary; } @@ -963,11 +977,9 @@ class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { public: /// \brief Create a new printing code-completion consumer that prints its /// results to the given raw output stream. - PrintingCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, - bool IncludeGlobals, + PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, raw_ostream &OS) - : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, - false), OS(OS), + : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS), CCTUInfo(new GlobalCodeCompletionAllocator) {} /// \brief Prints the finalized code-completion results. diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h new file mode 100644 index 0000000..30712db --- /dev/null +++ b/include/clang/Sema/CodeCompleteOptions.h @@ -0,0 +1,37 @@ +//===---- CodeCompleteOptions.h - Code Completion Options -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H +#define LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H + +/// Options controlling the behavior of code completion. +class CodeCompleteOptions { +public: + ///< Show macros in code completion results. + unsigned IncludeMacros : 1; + + ///< Show code patterns in code completion results. + unsigned IncludeCodePatterns : 1; + + ///< Show top-level decls in code completion results. + unsigned IncludeGlobals : 1; + + ///< Show brief documentation comments in code completion results. + unsigned IncludeBriefComments : 1; + + CodeCompleteOptions() : + IncludeMacros(0), + IncludeCodePatterns(0), + IncludeGlobals(1), + IncludeBriefComments(0) + { } +}; + +#endif + diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 67fd393..792b0c6 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -6,15 +6,18 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the classes used to store parsed information about -// declaration-specifiers and declarators. -// -// static const int volatile x, *y, *(*(*z)[10])(const void *x); -// ------------------------- - -- --------------------------- -// declaration-specifiers \ | / -// declarators -// +/// +/// \file +/// \brief This file defines the classes used to store parsed information about +/// declaration-specifiers and declarators. +/// +/// \verbatim +/// static const int volatile x, *y, *(*(*z)[10])(const void *x); +/// ------------------------- - -- --------------------------- +/// declaration-specifiers \ | / +/// declarators +/// \endverbatim +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_SEMA_DECLSPEC_H @@ -48,8 +51,9 @@ namespace clang { class Declarator; struct TemplateIdAnnotation; -/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope -/// specifier. These can be in 3 states: +/// \brief Represents a C++ nested-name-specifier or a global scope specifier. +/// +/// These can be in 3 states: /// 1) Not present, identified by isEmpty() /// 2) Present, identified by isNotEmpty() /// 2.a) Valid, idenified by isValid() @@ -158,9 +162,14 @@ public: NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; /// \brief Retrieve the location of the name in the last qualifier - /// in this nested name specifier. For example: - /// ::foo::bar<0>:: - /// ^~~ + /// in this nested name specifier. + /// + /// For example, the location of \c bar + /// in + /// \verbatim + /// \::foo::bar<0>:: + /// ^~~ + /// \endverbatim SourceLocation getLastQualifierNameLoc() const; /// No scope specifier. @@ -199,13 +208,14 @@ public: unsigned location_size() const { return Builder.getBuffer().second; } }; -/// DeclSpec - This class captures information about "declaration specifiers", -/// which encompasses storage-class-specifiers, type-specifiers, -/// type-qualifiers, and function-specifiers. +/// \brief Captures information about "declaration specifiers". +/// +/// "Declaration specifiers" encompasses storage-class-specifiers, +/// type-specifiers, type-qualifiers, and function-specifiers. class DeclSpec { public: - // storage-class-specifier - // Note: The order of these enumerators is important for diagnostics. + /// \brief storage-class-specifier + /// \note The order of these enumerators is important for diagnostics. enum SCS { SCS_unspecified = 0, SCS_typedef, @@ -466,8 +476,7 @@ public: SourceRange getTypeofParensRange() const { return TypeofParensRange; } void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } - /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool" - /// or "union". + /// \brief Turn a type-specifier-type into a string like "_Bool" or "union". static const char *getSpecifierName(DeclSpec::TST T); static const char *getSpecifierName(DeclSpec::TQ Q); static const char *getSpecifierName(DeclSpec::TSS S); @@ -510,7 +519,7 @@ public: FS_explicitLoc = SourceLocation(); } - /// hasTypeSpecifier - Return true if any type-specifier has been found. + /// \brief Return true if any type-specifier has been found. bool hasTypeSpecifier() const { return getTypeSpecType() != DeclSpec::TST_unspecified || getTypeSpecWidth() != DeclSpec::TSW_unspecified || @@ -518,9 +527,8 @@ public: getTypeSpecSign() != DeclSpec::TSS_unspecified; } - /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this + /// \brief Return a bitmask of which flavors of specifiers this /// DeclSpec includes. - /// unsigned getParsedSpecifiers() const; SCS getStorageClassSpecAsWritten() const { @@ -590,7 +598,8 @@ public: } bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang); + unsigned &DiagID, const LangOptions &Lang, + bool IsTypeSpec); bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); @@ -624,17 +633,22 @@ public: return Attrs.getPool(); } - /// AddAttributes - contatenates two attribute lists. + /// \brief Concatenates two attribute lists. + /// /// The GCC attribute syntax allows for the following: /// + /// \code /// short __attribute__(( unused, deprecated )) /// int __attribute__(( may_alias, aligned(16) )) var; + /// \endcode /// /// This declares 4 attributes using 2 lists. The following syntax is /// also allowed and equivalent to the previous declaration. /// + /// \code /// short __attribute__((unused)) __attribute__((deprecated)) /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; + /// \endcode /// void addAttributes(AttributeList *AL) { Attrs.addAll(AL); @@ -648,7 +662,7 @@ public: ParsedAttributes &getAttributes() { return Attrs; } const ParsedAttributes &getAttributes() const { return Attrs; } - /// TakeAttributes - Return the current attribute list and remove them from + /// \brief Return the current attribute list and remove them from /// the DeclSpec so that it doesn't own them. ParsedAttributes takeAttributes() { // The non-const "copy" constructor clears the operand automatically. @@ -684,13 +698,14 @@ public: ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; } void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; } - /// isMissingDeclaratorOk - This checks if this DeclSpec can stand alone, - /// without a Declarator. Only tag declspecs can stand alone. + /// \brief Checks if this DeclSpec can stand alone, without a Declarator. + /// + /// Only tag declspecs can stand alone. bool isMissingDeclaratorOk(); }; -/// ObjCDeclSpec - This class captures information about -/// "declaration specifiers" specific to objective-c +/// \brief Captures information about "declaration specifiers" specific to +/// Objective-C. class ObjCDeclSpec { public: /// ObjCDeclQualifier - Qualifier used on types in method @@ -853,12 +868,14 @@ public: assert(Other.Kind == IK_Identifier && "Cannot copy non-identifiers"); } - /// \brief Destroy this unqualified-id. - ~UnqualifiedId() { clear(); } - /// \brief Clear out this unqualified-id, setting it to default (invalid) /// state. - void clear(); + void clear() { + Kind = IK_Identifier; + Identifier = 0; + StartLocation = SourceLocation(); + EndLocation = SourceLocation(); + } /// \brief Determine whether this unqualified-id refers to a valid name. bool isValid() const { return StartLocation.isValid(); } @@ -979,12 +996,11 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; } SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; } }; - -/// CachedTokens - A set of tokens that has been cached for later -/// parsing. + +/// \brief A set of tokens that has been cached for later parsing. typedef SmallVector<Token, 4> CachedTokens; -/// DeclaratorChunk - One instance of this struct is used for each type in a +/// \brief One instance of this struct is used for each type in a /// declarator that is parsed. /// /// This is intended to be a small value object. @@ -1088,6 +1104,9 @@ struct DeclaratorChunk { /// contains the location of the ellipsis. unsigned isVariadic : 1; + /// Can this declaration be a constructor-style initializer? + unsigned isAmbiguous : 1; + /// \brief Whether the ref-qualifier (if any) is an lvalue reference. /// Otherwise, it's an rvalue reference. unsigned RefQualifierIsLValueRef : 1; @@ -1102,6 +1121,10 @@ struct DeclaratorChunk { /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo. unsigned DeleteArgInfo : 1; + /// HasTrailingReturnType - If this is true, a trailing return type was + /// specified. + unsigned HasTrailingReturnType : 1; + /// When isVariadic is true, the location of the ellipsis in the source. unsigned EllipsisLoc; @@ -1132,8 +1155,7 @@ struct DeclaratorChunk { /// any. unsigned MutableLoc; - /// \brief When ExceptionSpecType isn't EST_None or EST_Delayed, the - /// location of the keyword introducing the spec. + /// \brief The location of the keyword introducing the spec, if any. unsigned ExceptionSpecLoc; /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that @@ -1152,13 +1174,13 @@ struct DeclaratorChunk { 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 - /// allow union storage. - void *TrailingReturnType; + /// \brief If HasTrailingReturnType is true, this is the trailing return + /// type specified. + UnionParsedType TrailingReturnType; - /// freeArgs - reset the argument list to having zero arguments. This is - /// used in various places for error recovery. + /// \brief Reset the argument list to having zero arguments. + /// + /// This is used in various places for error recovery. void freeArgs() { if (DeleteArgInfo) { delete[] ArgInfo; @@ -1220,6 +1242,13 @@ struct DeclaratorChunk { ExceptionSpecificationType getExceptionSpecType() const { return static_cast<ExceptionSpecificationType>(ExceptionSpecType); } + + /// \brief Determine whether this function declarator had a + /// trailing-return-type. + bool hasTrailingReturnType() const { return HasTrailingReturnType; } + + /// \brief Get the trailing-return-type for this function declarator. + ParsedType getTrailingReturnType() const { return TrailingReturnType; } }; struct BlockPointerTypeInfo : TypeInfoCommon { @@ -1273,7 +1302,7 @@ struct DeclaratorChunk { } } - /// getAttrs - If there are attributes applied to this declaratorchunk, return + /// \brief If there are attributes applied to this declaratorchunk, return /// them. const AttributeList *getAttrs() const { return Common.AttrList; @@ -1283,8 +1312,7 @@ struct DeclaratorChunk { return Common.AttrList; } - /// getPointer - Return a DeclaratorChunk for a pointer. - /// + /// \brief Return a DeclaratorChunk for a pointer. static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, @@ -1300,8 +1328,7 @@ struct DeclaratorChunk { return I; } - /// getReference - Return a DeclaratorChunk for a reference. - /// + /// \brief Return a DeclaratorChunk for a reference. static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue) { DeclaratorChunk I; @@ -1313,8 +1340,7 @@ struct DeclaratorChunk { return I; } - /// getArray - Return a DeclaratorChunk for an array. - /// + /// \brief Return a DeclaratorChunk for an array. static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc) { @@ -1333,6 +1359,7 @@ struct DeclaratorChunk { /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. /// "TheDeclarator" is the declarator that this will be added to. static DeclaratorChunk getFunction(bool hasProto, bool isVariadic, + bool isAmbiguous, SourceLocation EllipsisLoc, ParamInfo *ArgInfo, unsigned NumArgs, unsigned TypeQuals, @@ -1350,11 +1377,10 @@ struct DeclaratorChunk { SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, - ParsedType TrailingReturnType = - ParsedType()); + TypeResult TrailingReturnType = + TypeResult()); - /// getBlockPointer - Return a DeclaratorChunk for a block. - /// + /// \brief Return a DeclaratorChunk for a block. static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc) { DeclaratorChunk I; @@ -1377,8 +1403,7 @@ struct DeclaratorChunk { return I; } - /// getParen - Return a DeclaratorChunk for a paren. - /// + /// \brief Return a DeclaratorChunk for a paren. static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc) { DeclaratorChunk I; @@ -1399,10 +1424,12 @@ enum FunctionDefinitionKind { FDK_Defaulted, FDK_Deleted }; - -/// Declarator - Information about one declarator, including the parsed type -/// information and the identifier. When the declarator is fully formed, this -/// is turned into the appropriate Decl object. + +/// \brief Information about one declarator, including the parsed type +/// information and the identifier. +/// +/// When the declarator is fully formed, this is turned into the appropriate +/// Decl object. /// /// Declarators come in two types: normal declarators and abstract declarators. /// Abstract declarators are used when parsing types, and don't have an @@ -1441,8 +1468,7 @@ private: UnqualifiedId Name; SourceRange Range; - /// Context - Where we are parsing this declarator. - /// + /// \brief Where we are parsing this declarator. TheContext Context; /// DeclTypeInfo - This holds each type that the declarator includes as it is @@ -1463,13 +1489,13 @@ private: /// Actually a FunctionDefinitionKind. unsigned FunctionDefinition : 2; - // Redeclaration - Is this Declarator is a redeclaration. + /// \brief Is this Declarator a redeclaration? bool Redeclaration : 1; /// Attrs - Attributes. ParsedAttributes Attrs; - /// AsmLabel - The asm label, if specified. + /// \brief The asm label, if specified. Expr *AsmLabel; /// InlineParams - This is a local array used for the first function decl @@ -1478,7 +1504,7 @@ private: DeclaratorChunk::ParamInfo InlineParams[16]; bool InlineParamsUsed; - /// Extension - true if the declaration is preceded by __extension__. + /// \brief true if the declaration is preceded by \c __extension__. bool Extension : 1; /// \brief If this is the second or subsequent declarator in this declaration, @@ -1536,7 +1562,7 @@ public: Context == ObjCResultContext); } - /// getSourceRange - Get the source range that spans this declarator. + /// \brief Get the source range that spans this declarator. const SourceRange &getSourceRange() const LLVM_READONLY { return Range; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -1564,7 +1590,7 @@ public: Range.setEnd(SR.getEnd()); } - /// clear - Reset the contents of this Declarator. + /// \brief Reset the contents of this Declarator. void clear() { SS.clear(); Name.clear(); @@ -1730,13 +1756,12 @@ public: SetRangeEnd(EndLoc); } - /// AddInnermostTypeInfo - Add a new innermost chunk to this declarator. + /// \brief Add a new innermost chunk to this declarator. void AddInnermostTypeInfo(const DeclaratorChunk &TI) { DeclTypeInfo.insert(DeclTypeInfo.begin(), TI); } - /// getNumTypeObjects() - Return the number of types applied to this - /// declarator. + /// \brief Return the number of types applied to this declarator. unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); } /// Return the specified TypeInfo from this declarator. TypeInfo #0 is @@ -1902,17 +1927,16 @@ public: bool isRedeclaration() const { return Redeclaration; } }; -/// FieldDeclarator - This little struct is used to capture information about +/// \brief This little struct is used to capture information about /// structure field declarators, which is basically just a bitfield size. struct FieldDeclarator { Declarator D; Expr *BitfieldSize; - explicit FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) { - BitfieldSize = 0; - } + explicit FieldDeclarator(const DeclSpec &DS) + : D(DS, Declarator::MemberContext), BitfieldSize(0) { } }; -/// VirtSpecifiers - Represents a C++0x virt-specifier-seq. +/// \brief Represents a C++11 virt-specifier-seq. class VirtSpecifiers { public: enum Specifier { @@ -1945,7 +1969,7 @@ private: SourceLocation LastLocation; }; -/// LambdaCapture - An individual capture in a lambda introducer. +/// \brief An individual capture in a lambda introducer. struct LambdaCapture { LambdaCaptureKind Kind; SourceLocation Loc; @@ -1959,7 +1983,7 @@ struct LambdaCapture { {} }; -/// LambdaIntroducer - Represents a complete lambda introducer. +/// \brief Represents a complete lambda introducer. struct LambdaIntroducer { SourceRange Range; SourceLocation DefaultLoc; @@ -1969,7 +1993,7 @@ struct LambdaIntroducer { LambdaIntroducer() : Default(LCD_None) {} - /// addCapture - Append a capture in a lambda introducer. + /// \brief Append a capture in a lambda introducer. void addCapture(LambdaCaptureKind Kind, SourceLocation Loc, IdentifierInfo* Id = 0, diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 3320cd8..c241266 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -21,7 +21,7 @@ #ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H #define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H -#include "clang/AST/DeclCXX.h" +#include "clang/Sema/Sema.h" namespace clang { namespace sema { @@ -40,17 +40,17 @@ public: bool isMemberAccess() const { return IsMember; } - AccessedEntity(ASTContext &Context, + AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator, MemberNonce _, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, QualType BaseObjectType) : Access(FoundDecl.getAccess()), IsMember(true), Target(FoundDecl.getDecl()), NamingClass(NamingClass), - BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) { + BaseObjectType(BaseObjectType), Diag(0, Allocator) { } - AccessedEntity(ASTContext &Context, + AccessedEntity(PartialDiagnostic::StorageAllocator &Allocator, BaseNonce _, CXXRecordDecl *BaseClass, CXXRecordDecl *DerivedClass, @@ -58,7 +58,7 @@ public: : Access(Access), IsMember(false), Target(BaseClass), NamingClass(DerivedClass), - Diag(0, Context.getDiagAllocator()) { + Diag(0, Allocator) { } bool isQuiet() const { return Diag.getDiagID() == 0; } @@ -214,7 +214,63 @@ private: }; }; +/// DelayedDiagnosticPool - A collection of diagnostics which were +/// delayed. +class DelayedDiagnosticPool { + const DelayedDiagnosticPool *Parent; + llvm::SmallVector<DelayedDiagnostic, 4> Diagnostics; + + // Do not implement. + DelayedDiagnosticPool(const DelayedDiagnosticPool &other); + DelayedDiagnosticPool &operator=(const DelayedDiagnosticPool &other); +public: + DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {} + ~DelayedDiagnosticPool() { + for (llvm::SmallVectorImpl<DelayedDiagnostic>::iterator + i = Diagnostics.begin(), e = Diagnostics.end(); i != e; ++i) + i->Destroy(); + } + + const DelayedDiagnosticPool *getParent() const { return Parent; } + + /// Does this pool, or any of its ancestors, contain any diagnostics? + bool empty() const { + return (Diagnostics.empty() && (Parent == NULL || Parent->empty())); + } + + /// Add a diagnostic to this pool. + void add(const DelayedDiagnostic &diag) { + Diagnostics.push_back(diag); + } + + /// Steal the diagnostics from the given pool. + void steal(DelayedDiagnosticPool &pool) { + if (pool.Diagnostics.empty()) return; + + if (Diagnostics.empty()) { + Diagnostics = llvm_move(pool.Diagnostics); + } else { + Diagnostics.append(pool.pool_begin(), pool.pool_end()); + } + pool.Diagnostics.clear(); + } + + typedef llvm::SmallVectorImpl<DelayedDiagnostic>::const_iterator + pool_iterator; + pool_iterator pool_begin() const { return Diagnostics.begin(); } + pool_iterator pool_end() const { return Diagnostics.end(); } + bool pool_empty() const { return Diagnostics.empty(); } +}; + } + +/// Add a diagnostic to the current delay pool. +inline void Sema::DelayedDiagnostics::add(const sema::DelayedDiagnostic &diag) { + assert(shouldDelayDiagnostics() && "trying to delay without pool"); + CurPool->add(diag); +} + + } #endif diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h index fe01f4d..55603fe 100644 --- a/include/clang/Sema/Designator.h +++ b/include/clang/Sema/Designator.h @@ -179,18 +179,10 @@ public: /// Designation - Represent a full designation, which is a sequence of /// designators. This class is mostly a helper for InitListDesignations. class Designation { - /// InitIndex - The index of the initializer expression this is for. For - /// example, if the initializer were "{ A, .foo=B, C }" a Designation would - /// exist with InitIndex=1, because element #1 has a designation. - unsigned InitIndex; - /// Designators - The actual designators for this initializer. SmallVector<Designator, 2> Designators; - Designation(unsigned Idx) : InitIndex(Idx) {} public: - Designation() : InitIndex(4000) {} - /// AddDesignator - Add a designator to the end of this list. void AddDesignator(Designator D) { Designators.push_back(D); diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 0dd6887..77659be 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -15,6 +15,7 @@ #include "clang/Sema/Ownership.h" #include "clang/Sema/Overload.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/SourceLocation.h" @@ -855,8 +856,8 @@ public: /// /// \param BaseType the base type to which we will be casting. /// - /// \param IsLValue true if the result of this cast will be treated as - /// an lvalue. + /// \param Category Indicates whether the result will be treated as an + /// rvalue, an xvalue, or an lvalue. void AddDerivedToBaseCastStep(QualType BaseType, ExprValueKind Category); @@ -865,9 +866,6 @@ public: /// \param BindingTemporary True if we are binding a reference to a temporary /// object (thereby extending its lifetime); false if we are binding to an /// lvalue or an lvalue treated as an rvalue. - /// - /// \param UnnecessaryCopy True if we should check for a copy - /// constructor for a completely unnecessary but void AddReferenceBindingStep(QualType T, bool BindingTemporary); /// \brief Add a new step that makes an extraneous copy of the input diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index d334447..d2fc285 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -659,12 +659,25 @@ namespace clang { /// A structure used to record information about a failed /// template argument deduction. struct DeductionFailureInfo { - // A Sema::TemplateDeductionResult. - unsigned Result; + /// A Sema::TemplateDeductionResult. + unsigned Result : 8; + + /// \brief Indicates whether a diagnostic is stored in Diagnostic. + unsigned HasDiagnostic : 1; /// \brief Opaque pointer containing additional data about /// this deduction failure. void *Data; + + /// \brief A diagnostic indicating why deduction failed. + union { + void *Align; + char Diagnostic[sizeof(PartialDiagnosticAt)]; + }; + + /// \brief Retrieve the diagnostic which caused this deduction failure, + /// if any. + PartialDiagnosticAt *getSFINAEDiagnostic(); /// \brief Retrieve the template parameter this deduction failure /// refers to, if any. @@ -740,11 +753,7 @@ namespace clang { public: OverloadCandidateSet(SourceLocation Loc) : Loc(Loc), NumInlineSequences(0){} - ~OverloadCandidateSet() { - for (iterator i = begin(), e = end(); i != e; ++i) - for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii) - i->Conversions[ii].~ImplicitConversionSequence(); - } + ~OverloadCandidateSet() { clear(); } SourceLocation getLocation() const { return Loc; } diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index c1b4710..69080ad 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -58,7 +58,7 @@ namespace clang { SourceLocation TemplateLoc) : Kind(ParsedTemplateArgument::Template), Arg(Template.getAsOpaquePtr()), - Loc(TemplateLoc), SS(SS), EllipsisLoc() { } + SS(SS), Loc(TemplateLoc), EllipsisLoc() { } /// \brief Determine whether the given template argument is invalid. bool isInvalid() const { return Arg == 0; } @@ -118,13 +118,13 @@ namespace clang { /// expression), or an ActionBase::TemplateTy (for a template). void *Arg; - /// \brief the location of the template argument. - SourceLocation Loc; - /// \brief The nested-name-specifier that can accompany a template template /// argument. CXXScopeSpec SS; - + + /// \brief the location of the template argument. + SourceLocation Loc; + /// \brief The ellipsis location that can accompany a template template /// argument (turning it into a template template argument expansion). SourceLocation EllipsisLoc; diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 48f5417..b78556e 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -71,7 +71,7 @@ public: FunctionPrototypeScope = 0x100, /// AtCatchScope - This is a scope that corresponds to the Objective-C - /// @catch statement. + /// \@catch statement. AtCatchScope = 0x200, /// ObjCMethodScope - This scope corresponds to an Objective-C method body. @@ -270,7 +270,7 @@ public: return getFlags() & Scope::FunctionPrototypeScope; } - /// isAtCatchScope - Return true if this scope is @catch. + /// isAtCatchScope - Return true if this scope is \@catch. bool isAtCatchScope() const { return getFlags() & Scope::AtCatchScope; } diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index ceaf586..b4752f5 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -74,7 +74,7 @@ public: /// ScopeKind Kind; - /// \brief Whether this function contains a VLA, @try, try, C++ + /// \brief Whether this function contains a VLA, \@try, try, C++ /// initializer, or anything else that can't be jumped past. bool HasBranchProtectedScope; @@ -84,6 +84,14 @@ public: /// \brief Whether this function contains any indirect gotos. bool HasIndirectGoto; + /// A flag that is set when parsing a -dealloc method and no [super dealloc] + /// call was found yet. + bool ObjCShouldCallSuperDealloc; + + /// A flag that is set when parsing a -finalize method and no [super finalize] + /// call was found yet. + bool ObjCShouldCallSuperFinalize; + /// \brief Used to determine if errors occurred in this function or block. DiagnosticErrorTrap ErrorTrap; @@ -93,7 +101,7 @@ public: /// \brief The list of return statements that occur within the function or /// block, if there is any chance of applying the named return value - /// optimization. + /// optimization, or if we need to infer a return type. SmallVector<ReturnStmt*, 4> Returns; /// \brief The stack of currently active compound stamement scopes in the @@ -127,6 +135,8 @@ public: HasBranchProtectedScope(false), HasBranchIntoScope(false), HasIndirectGoto(false), + ObjCShouldCallSuperDealloc(false), + ObjCShouldCallSuperFinalize(false), ErrorTrap(Diag) { } virtual ~FunctionScopeInfo(); @@ -344,6 +354,9 @@ public: /// \brief Whether any of the capture expressions requires cleanups. bool ExprNeedsCleanups; + /// \brief Whether the lambda contains an unexpanded parameter pack. + bool ContainsUnexpandedParameterPack; + /// \brief Variables used to index into by-copy array captures. llvm::SmallVector<VarDecl *, 4> ArrayIndexVars; @@ -355,7 +368,7 @@ public: CXXMethodDecl *CallOperator) : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), - ExprNeedsCleanups(false) + ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) { Kind = SK_Lambda; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index c8767b6..058e0d9 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -28,6 +28,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/LambdaMangleContext.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/NSAPI.h" #include "clang/Lex/ModuleLoader.h" @@ -36,7 +37,9 @@ #include "clang/Basic/TypeTraits.h" #include "clang/Basic/ExpressionTraits.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include <deque> @@ -167,8 +170,10 @@ namespace clang { namespace sema { class AccessedEntity; class BlockScopeInfo; + class CapturingScopeInfo; class CompoundScopeInfo; class DelayedDiagnostic; + class DelayedDiagnosticPool; class FunctionScopeInfo; class LambdaScopeInfo; class PossiblyUnreachableDiag; @@ -220,13 +225,13 @@ public: /// This is used as part of a hack to omit that class from ADL results. DeclarationName VAListTagName; - /// PackContext - Manages the stack for #pragma pack. An alignment + /// 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 + bool MSStructPragmaOn; // True when \#pragma ms_struct on - /// VisContext - Manages the stack for #pragma GCC visibility. + /// VisContext - Manages the stack for \#pragma GCC visibility. void *VisContext; // Really a "PragmaVisStack*" /// ExprNeedsCleanups - True if the current evaluation context @@ -262,10 +267,15 @@ public: /// /// This set is used to suppress redundant diagnostics. llvm::SmallPtrSet<NamedDecl *, 4> HiddenDefinitions; - + /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. OwningPtr<CXXFieldCollector> FieldCollector; + typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType; + + /// \brief Set containing all declared private fields that are not used. + NamedDeclSetType UnusedPrivateFields; + typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy; /// PureVirtualClassDiagSet - a set of class declarations which we have @@ -355,93 +365,63 @@ public: class DelayedDiagnostics; - class ParsingDeclState { - unsigned SavedStackSize; - friend class Sema::DelayedDiagnostics; - }; - - class ProcessingContextState { - unsigned SavedParsingDepth; - unsigned SavedActiveStackBase; + class DelayedDiagnosticsState { + sema::DelayedDiagnosticPool *SavedPool; friend class Sema::DelayedDiagnostics; }; + typedef DelayedDiagnosticsState ParsingDeclState; + typedef DelayedDiagnosticsState ProcessingContextState; /// A class which encapsulates the logic for delaying diagnostics /// during parsing and other processing. class DelayedDiagnostics { - /// \brief The stack of diagnostics that were delayed due to being - /// produced during the parsing of a declaration. - sema::DelayedDiagnostic *Stack; - - /// \brief The number of objects on the delayed-diagnostics stack. - unsigned StackSize; - - /// \brief The current capacity of the delayed-diagnostics stack. - unsigned StackCapacity; - - /// \brief The index of the first "active" delayed diagnostic in - /// the stack. When parsing class definitions, we ignore active - /// delayed diagnostics from the surrounding context. - unsigned ActiveStackBase; - - /// \brief The depth of the declarations we're currently parsing. - /// This gets saved and reset whenever we enter a class definition. - unsigned ParsingDepth; + /// \brief The current pool of diagnostics into which delayed + /// diagnostics should go. + sema::DelayedDiagnosticPool *CurPool; public: - DelayedDiagnostics() : Stack(0), StackSize(0), StackCapacity(0), - ActiveStackBase(0), ParsingDepth(0) {} - - ~DelayedDiagnostics() { - delete[] reinterpret_cast<char*>(Stack); - } + DelayedDiagnostics() : CurPool(0) {} /// Adds a delayed diagnostic. - void add(const sema::DelayedDiagnostic &diag); + void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h /// Determines whether diagnostics should be delayed. - bool shouldDelayDiagnostics() { return ParsingDepth > 0; } - - /// Observe that we've started parsing a declaration. Access and - /// deprecation diagnostics will be delayed; when the declaration - /// is completed, all active delayed diagnostics will be evaluated - /// in its context, and then active diagnostics stack will be - /// popped down to the saved depth. - ParsingDeclState pushParsingDecl() { - ParsingDepth++; - - ParsingDeclState state; - state.SavedStackSize = StackSize; - return state; - } - - /// Observe that we're completed parsing a declaration. - static void popParsingDecl(Sema &S, ParsingDeclState state, Decl *decl); + bool shouldDelayDiagnostics() { return CurPool != 0; } - /// Observe that we've started processing a different context, the - /// contents of which are semantically separate from the - /// declarations it may lexically appear in. This sets aside the - /// current stack of active diagnostics and starts afresh. - ProcessingContextState pushContext() { - assert(StackSize >= ActiveStackBase); + /// Returns the current delayed-diagnostics pool. + sema::DelayedDiagnosticPool *getCurrentPool() const { + return CurPool; + } - ProcessingContextState state; - state.SavedParsingDepth = ParsingDepth; - state.SavedActiveStackBase = ActiveStackBase; + /// Enter a new scope. Access and deprecation diagnostics will be + /// collected in this pool. + DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) { + DelayedDiagnosticsState state; + state.SavedPool = CurPool; + CurPool = &pool; + return state; + } - ActiveStackBase = StackSize; - ParsingDepth = 0; + /// Leave a delayed-diagnostic state that was previously pushed. + /// Do not emit any of the diagnostics. This is performed as part + /// of the bookkeeping of popping a pool "properly". + void popWithoutEmitting(DelayedDiagnosticsState state) { + CurPool = state.SavedPool; + } + /// Enter a new scope where access and deprecation diagnostics are + /// not delayed. + DelayedDiagnosticsState pushUndelayed() { + DelayedDiagnosticsState state; + state.SavedPool = CurPool; + CurPool = 0; return state; } - /// Observe that we've stopped processing a context. This - /// restores the previous stack of active diagnostics. - void popContext(ProcessingContextState state) { - assert(ActiveStackBase == StackSize); - assert(ParsingDepth == 0); - ActiveStackBase = state.SavedActiveStackBase; - ParsingDepth = state.SavedParsingDepth; + /// Undo a previous pushUndelayed(). + void popUndelayed(DelayedDiagnosticsState state) { + assert(CurPool == NULL); + CurPool = state.SavedPool; } } DelayedDiagnostics; @@ -452,11 +432,11 @@ public: DeclContext *SavedContext; ProcessingContextState SavedContextState; QualType SavedCXXThisTypeOverride; - + public: ContextRAII(Sema &S, DeclContext *ContextToPush) : S(S), SavedContext(S.CurContext), - SavedContextState(S.DelayedDiagnostics.pushContext()), + SavedContextState(S.DelayedDiagnostics.pushUndelayed()), SavedCXXThisTypeOverride(S.CXXThisTypeOverride) { assert(ContextToPush && "pushing null context"); @@ -466,7 +446,7 @@ public: void pop() { if (!SavedContext) return; S.CurContext = SavedContext; - S.DelayedDiagnostics.popContext(SavedContextState); + S.DelayedDiagnostics.popUndelayed(SavedContextState); S.CXXThisTypeOverride = SavedCXXThisTypeOverride; SavedContext = 0; } @@ -477,12 +457,12 @@ public: }; /// WeakUndeclaredIdentifiers - Identifiers contained in - /// #pragma weak before declared. rare. may alias another + /// \#pragma weak before declared. rare. may alias another /// identifier, declared or undeclared llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers; /// ExtnameUndeclaredIdentifiers - Identifiers contained in - /// #pragma redefine_extname before declared. Used in Solaris system headers + /// \#pragma redefine_extname before declared. Used in Solaris system headers /// to define functions that occur in multiple standards to call the version /// in the currently selected standard. llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*> ExtnameUndeclaredIdentifiers; @@ -492,7 +472,7 @@ public: void LoadExternalWeakUndeclaredIdentifiers(); /// WeakTopLevelDecl - Translation-unit scoped declarations generated by - /// #pragma weak during processing of other Decls. + /// \#pragma weak during processing of other Decls. /// I couldn't figure out a clean way to generate these in-line, so /// we store them here and handle separately -- which is a hack. /// It would be best to refactor this. @@ -513,10 +493,10 @@ public: LazyDeclPtr StdBadAlloc; /// \brief The C++ "std::initializer_list" template, which is defined in - /// <initializer_list>. + /// \<initializer_list>. ClassTemplateDecl *StdInitializerList; - /// \brief The C++ "type_info" declaration, which is defined in <typeinfo>. + /// \brief The C++ "type_info" declaration, which is defined in \<typeinfo>. RecordDecl *CXXTypeInfoDecl; /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files. @@ -527,16 +507,28 @@ public: /// \brief The declaration of the Objective-C NSNumber class. ObjCInterfaceDecl *NSNumberDecl; - + + /// \brief Pointer to NSNumber type (NSNumber *). + QualType NSNumberPointer; + /// \brief The Objective-C NSNumber methods used to create NSNumber literals. ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods]; - + + /// \brief The declaration of the Objective-C NSString class. + ObjCInterfaceDecl *NSStringDecl; + + /// \brief Pointer to NSString type (NSString *). + QualType NSStringPointer; + + /// \brief The declaration of the stringWithUTF8String: method. + ObjCMethodDecl *StringWithUTF8StringMethod; + /// \brief The declaration of the Objective-C NSArray class. ObjCInterfaceDecl *NSArrayDecl; /// \brief The declaration of the arrayWithObjects:count: method. ObjCMethodDecl *ArrayWithObjectsMethod; - + /// \brief The declaration of the Objective-C NSDictionary class. ObjCInterfaceDecl *NSDictionaryDecl; @@ -550,13 +542,6 @@ public: /// have been declared. bool GlobalNewDeleteDeclared; - /// A flag that is set when parsing a -dealloc method and no [super dealloc] - /// call was found yet. - bool ObjCShouldCallSuperDealloc; - /// A flag that is set when parsing a -finalize method and no [super finalize] - /// call was found yet. - bool ObjCShouldCallSuperFinalize; - /// \brief Describes how the expressions currently being parsed are /// evaluated at run-time, if at all. enum ExpressionEvaluationContext { @@ -611,10 +596,10 @@ public: llvm::SmallVector<LambdaExpr *, 2> Lambdas; /// \brief The declaration that provides context for the lambda expression - /// if the normal declaration context does not suffice, e.g., in a + /// if the normal declaration context does not suffice, e.g., in a /// default function argument. Decl *LambdaContextDecl; - + /// \brief The context information used to mangle lambda expressions /// within this context. /// @@ -629,7 +614,7 @@ public: /// \brief If we are processing a decltype type, a set of temporary binding /// expressions for which we have deferred checking the destructor. llvm::SmallVector<CXXBindTemporaryExpr*, 8> DelayedDecltypeBinds; - + ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, unsigned NumCleanupObjects, bool ParentNeedsCleanups, @@ -638,11 +623,11 @@ public: : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), LambdaContextDecl(LambdaContextDecl), LambdaMangle() { } - + ~ExpressionEvaluationContextRecord() { delete LambdaMangle; } - + /// \brief Retrieve the mangling context for lambdas. LambdaMangleContext &getLambdaMangleContext() { assert(LambdaContextDecl && "Need to have a lambda context declaration"); @@ -654,17 +639,12 @@ public: /// A stack of expression evaluation contexts. SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; - + /// SpecialMemberOverloadResult - The overloading result for a special member /// function. /// /// This is basically a wrapper around PointerIntPair. The lowest bits of the - /// integer are used to determine whether overload resolution succeeded, and - /// whether, when looking up a copy constructor or assignment operator, we - /// found a potential copy constructor/assignment operator whose first - /// parameter is const-qualified. This is used for determining parameter types - /// of other objects and is utterly meaningless on other types of special - /// members. + /// integer are used to determine whether overload resolution succeeded. class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode { public: enum Kind { @@ -735,7 +715,7 @@ public: /// of selectors are "overloaded"). GlobalMethodPool MethodPool; - /// Method selectors used in a @selector expression. Used for implementation + /// Method selectors used in a \@selector expression. Used for implementation /// of -Wselector. llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors; @@ -826,7 +806,8 @@ public: bool findMacroSpelling(SourceLocation &loc, StringRef name); /// \brief Get a string to suggest for zero-initialization of a type. - const char *getFixItZeroInitializerForType(QualType T) const; + std::string getFixItZeroInitializerForType(QualType T) const; + std::string getFixItZeroLiteralForType(QualType T) const; ExprResult Owned(Expr* E) { return E; } ExprResult Owned(ExprResult R) { return R; } @@ -861,9 +842,11 @@ public: /// \brief Retrieve the current lambda expression, if any. sema::LambdaScopeInfo *getCurLambda(); - /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls + /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } + void ActOnComment(SourceRange Comment); + //===--------------------------------------------------------------------===// // Type Analysis / Processing: SemaType.cpp. // @@ -899,7 +882,7 @@ public: TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, TypeSourceInfo *ReturnTypeInfo); - + /// \brief Package the given type and TSI into a ParsedType. ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo); DeclarationNameInfo GetNameForDeclarator(Declarator &D); @@ -936,19 +919,168 @@ public: /// in an Objective-C message declaration. Return the appropriate type. ParsedType ActOnObjCInstanceType(SourceLocation Loc); + /// \brief Abstract class used to diagnose incomplete types. + struct TypeDiagnoser { + bool Suppressed; + + TypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { } + + virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0; + virtual ~TypeDiagnoser() {} + }; + + static int getPrintable(int I) { return I; } + static unsigned getPrintable(unsigned I) { return I; } + static bool getPrintable(bool B) { return B; } + static const char * getPrintable(const char *S) { return S; } + static StringRef getPrintable(StringRef S) { return S; } + static const std::string &getPrintable(const std::string &S) { return S; } + static const IdentifierInfo *getPrintable(const IdentifierInfo *II) { + return II; + } + static DeclarationName getPrintable(DeclarationName N) { return N; } + static QualType getPrintable(QualType T) { return T; } + static SourceRange getPrintable(SourceRange R) { return R; } + static SourceRange getPrintable(SourceLocation L) { return L; } + static SourceRange getPrintable(Expr *E) { return E->getSourceRange(); } + static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} + + template<typename T1> + class BoundTypeDiagnoser1 : public TypeDiagnoser { + unsigned DiagID; + const T1 &Arg1; + + public: + BoundTypeDiagnoser1(unsigned DiagID, const T1 &Arg1) + : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { } + virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) { + if (Suppressed) return; + S.Diag(Loc, DiagID) << getPrintable(Arg1) << T; + } + + virtual ~BoundTypeDiagnoser1() { } + }; + + template<typename T1, typename T2> + class BoundTypeDiagnoser2 : public TypeDiagnoser { + unsigned DiagID; + const T1 &Arg1; + const T2 &Arg2; + + public: + BoundTypeDiagnoser2(unsigned DiagID, const T1 &Arg1, + const T2 &Arg2) + : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1), + Arg2(Arg2) { } + + virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) { + if (Suppressed) return; + S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T; + } + + virtual ~BoundTypeDiagnoser2() { } + }; + + template<typename T1, typename T2, typename T3> + class BoundTypeDiagnoser3 : public TypeDiagnoser { + unsigned DiagID; + const T1 &Arg1; + const T2 &Arg2; + const T3 &Arg3; + + public: + BoundTypeDiagnoser3(unsigned DiagID, const T1 &Arg1, + const T2 &Arg2, const T3 &Arg3) + : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1), + Arg2(Arg2), Arg3(Arg3) { } + + virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) { + if (Suppressed) return; + S.Diag(Loc, DiagID) + << getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T; + } + + virtual ~BoundTypeDiagnoser3() { } + }; + bool RequireCompleteType(SourceLocation Loc, QualType T, - const PartialDiagnostic &PD, - std::pair<SourceLocation, PartialDiagnostic> Note); - bool RequireCompleteType(SourceLocation Loc, QualType T, - const PartialDiagnostic &PD); + TypeDiagnoser &Diagnoser); bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID); - bool RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD, - std::pair<SourceLocation, - PartialDiagnostic> Note); + + template<typename T1> + bool RequireCompleteType(SourceLocation Loc, QualType T, + unsigned DiagID, const T1 &Arg1) { + BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); + return RequireCompleteType(Loc, T, Diagnoser); + } + + template<typename T1, typename T2> + bool RequireCompleteType(SourceLocation Loc, QualType T, + unsigned DiagID, const T1 &Arg1, const T2 &Arg2) { + BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); + return RequireCompleteType(Loc, T, Diagnoser); + } + + template<typename T1, typename T2, typename T3> + bool RequireCompleteType(SourceLocation Loc, QualType T, + unsigned DiagID, const T1 &Arg1, const T2 &Arg2, + const T3 &Arg3) { + BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, + Arg3); + return RequireCompleteType(Loc, T, Diagnoser); + } + + bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser); + bool RequireCompleteExprType(Expr *E, unsigned DiagID); + + template<typename T1> + bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1) { + BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); + return RequireCompleteExprType(E, Diagnoser); + } + + template<typename T1, typename T2> + bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1, + const T2 &Arg2) { + BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); + return RequireCompleteExprType(E, Diagnoser); + } + + template<typename T1, typename T2, typename T3> + bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1, + const T2 &Arg2, const T3 &Arg3) { + BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, + Arg3); + return RequireCompleteExprType(E, Diagnoser); + } bool RequireLiteralType(SourceLocation Loc, QualType T, - const PartialDiagnostic &PD); + TypeDiagnoser &Diagnoser); + bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID); + + template<typename T1> + bool RequireLiteralType(SourceLocation Loc, QualType T, + unsigned DiagID, const T1 &Arg1) { + BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); + return RequireLiteralType(Loc, T, Diagnoser); + } + + template<typename T1, typename T2> + bool RequireLiteralType(SourceLocation Loc, QualType T, + unsigned DiagID, const T1 &Arg1, const T2 &Arg2) { + BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); + return RequireLiteralType(Loc, T, Diagnoser); + } + + template<typename T1, typename T2, typename T3> + bool RequireLiteralType(SourceLocation Loc, QualType T, + unsigned DiagID, const T1 &Arg1, const T2 &Arg2, + const T3 &Arg3) { + BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, + Arg3); + return RequireLiteralType(Loc, T, Diagnoser); + } QualType getElaboratedType(ElaboratedTypeKeyword Keyword, const CXXScopeSpec &SS, QualType T); @@ -978,6 +1110,8 @@ public: void DiagnoseUseOfUnimplementedSelectors(); + bool isSimpleTypeSpecifier(tok::TokenKind Kind) const; + ParsedType getTypeName(IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS = 0, bool isClassName = false, @@ -988,7 +1122,7 @@ public: IdentifierInfo **CorrectedII = 0); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); - bool DiagnoseUnknownTypeName(const IdentifierInfo &II, + bool DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, @@ -1173,12 +1307,21 @@ public: unsigned NumDecls); DeclGroupPtrTy BuildDeclaratorGroup(Decl **Group, unsigned NumDecls, bool TypeMayContainAuto = true); + + /// Should be called on all declarations that might have attached + /// documentation comments. + void ActOnDocumentableDecl(Decl *D); + void ActOnDocumentableDecls(Decl **Group, unsigned NumDecls); + void 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); + bool isObjCMethodDecl(Decl *D) { + return D && isa<ObjCMethodDecl>(D); + } void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); @@ -1213,7 +1356,7 @@ public: /// \param ImportLoc The location of the 'import' keyword. /// /// \param Path The module access path. - DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, + DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, ModuleIdPath Path); /// \brief Retrieve a suitable printing policy. @@ -1286,13 +1429,15 @@ public: Declarator &D, Expr *BitfieldWidth); FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, - Declarator &D, Expr *BitfieldWidth, bool HasInit, + Declarator &D, Expr *BitfieldWidth, + InClassInitStyle InitStyle, AccessSpecifier AS); FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, TypeSourceInfo *TInfo, RecordDecl *Record, SourceLocation Loc, - bool Mutable, Expr *BitfieldWidth, bool HasInit, + bool Mutable, Expr *BitfieldWidth, + InClassInitStyle InitStyle, SourceLocation TSSL, AccessSpecifier AS, NamedDecl *PrevDecl, Declarator *D = 0); @@ -1432,6 +1577,24 @@ public: TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, TypeSourceInfo *TInfo); bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New); + + /// Attribute merging methods. Return true if a new attribute was added. + AvailabilityAttr *mergeAvailabilityAttr(Decl *D, SourceRange Range, + IdentifierInfo *Platform, + VersionTuple Introduced, + VersionTuple Deprecated, + VersionTuple Obsoleted, + bool IsUnavailable, + StringRef Message); + VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range, + VisibilityAttr::VisibilityType Vis); + DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range); + DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range); + FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, + int FormatIdx, int FirstArg); + SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name); + bool mergeDeclAttribute(Decl *New, InheritableAttr *Attr); + void mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation = true); void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls); bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S); @@ -1558,16 +1721,59 @@ public: ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); + /// \brief Abstract base class used to diagnose problems that occur while + /// trying to convert an expression to integral or enumeration type. + class ICEConvertDiagnoser { + public: + bool Suppress; + bool SuppressConversion; + + ICEConvertDiagnoser(bool Suppress = false, + bool SuppressConversion = false) + : Suppress(Suppress), SuppressConversion(SuppressConversion) { } + + /// \brief Emits a diagnostic complaining that the expression does not have + /// integral or enumeration type. + virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, + QualType T) = 0; + + /// \brief Emits a diagnostic when the expression has incomplete class type. + virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, + QualType T) = 0; + + /// \brief Emits a diagnostic when the only matching conversion function + /// is explicit. + virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, + QualType T, + QualType ConvTy) = 0; + + /// \brief Emits a note for the explicit conversion function. + virtual DiagnosticBuilder + noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) = 0; + + /// \brief Emits a diagnostic when there are multiple possible conversion + /// functions. + virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, + QualType T) = 0; + + /// \brief Emits a note for one of the candidate conversions. + virtual DiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, + QualType ConvTy) = 0; + + /// \brief Emits a diagnostic when we picked a conversion function + /// (for cases when we are not allowed to pick a conversion function). + virtual DiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, + QualType T, + QualType ConvTy) = 0; + + virtual ~ICEConvertDiagnoser() {} + }; + ExprResult ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE, - const PartialDiagnostic &NotIntDiag, - const PartialDiagnostic &IncompleteDiag, - const PartialDiagnostic &ExplicitConvDiag, - const PartialDiagnostic &ExplicitConvNote, - const PartialDiagnostic &AmbigDiag, - const PartialDiagnostic &AmbigNote, - const PartialDiagnostic &ConvDiag, + ICEConvertDiagnoser &Diagnoser, bool AllowScopedEnumerations); + enum ObjCSubscriptKind { OS_Array, OS_Dictionary, @@ -1910,14 +2116,16 @@ public: unsigned Quals); CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, bool RValueThis, unsigned ThisQuals); - CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class); - CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, bool RValueThis, - unsigned ThisQuals); + CXXConstructorDecl *LookupMovingConstructor(CXXRecordDecl *Class, + unsigned Quals); + CXXMethodDecl *LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, + bool RValueThis, unsigned ThisQuals); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R, ArrayRef<QualType> ArgTys, bool AllowRawAndTemplate); + bool isKnownName(StringRef name); void ArgumentDependentLookup(DeclarationName Name, bool Operator, SourceLocation Loc, @@ -2000,13 +2208,11 @@ public: bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl, ObjCInterfaceDecl *IDecl); - typedef llvm::DenseSet<Selector, llvm::DenseMapInfo<Selector> > SelectorSet; + typedef llvm::SmallPtrSet<Selector, 8> SelectorSet; typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap; /// CheckProtocolMethodDefs - This routine checks unimplemented /// methods declared in protocol, and those referenced by it. - /// \param IDecl - Used for checking for methods which may have been - /// inherited. void CheckProtocolMethodDefs(SourceLocation ImpLoc, ObjCProtocolDecl *PDecl, bool& IncompleteImpl, @@ -2021,7 +2227,7 @@ public: SourceLocation Loc); /// ImplMethodsVsClassMethods - This is main routine to warn if any method - /// remains unimplemented in the class or category @implementation. + /// remains unimplemented in the class or category \@implementation. void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, ObjCContainerDecl* IDecl, bool IncompleteImpl = false); @@ -2033,7 +2239,7 @@ public: const SelectorSet &InsMap); /// DefaultSynthesizeProperties - This routine default synthesizes all - /// properties which must be synthesized in class's @implementation. + /// properties which must be synthesized in the class's \@implementation. void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl, ObjCInterfaceDecl *IDecl); void DefaultSynthesizeProperties(Scope *S, Decl *D); @@ -2050,8 +2256,8 @@ public: ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl, IdentifierInfo *II); - /// Called by ActOnProperty to handle @property declarations in - //// class extensions. + /// Called by ActOnProperty to handle \@property declarations in + /// class extensions. Decl *HandlePropertyInClassExtension(Scope *S, SourceLocation AtLoc, SourceLocation LParenLoc, @@ -2067,7 +2273,7 @@ public: tok::ObjCKeywordKind MethodImplKind); /// Called by ActOnProperty and HandlePropertyInClassExtension to - /// handle creating the ObjcPropertyDecl for a category or @interface. + /// handle creating the ObjcPropertyDecl for a category or \@interface. ObjCPropertyDecl *CreatePropertyDecl(Scope *S, ObjCContainerDecl *CDecl, SourceLocation AtLoc, @@ -2123,7 +2329,7 @@ public: /// \brief Add the given method to the list of globally-known methods. void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); - + private: /// AddMethodToGlobalPool - Add an instance or factory method to the global /// pool. See descriptoin of AddInstanceMethodToGlobalPool. @@ -2213,7 +2419,10 @@ public: }; FullExprArg MakeFullExpr(Expr *Arg) { - return FullExprArg(ActOnFinishFullExpr(Arg).release()); + return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); + } + FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { + return FullExprArg(ActOnFinishFullExpr(Arg, CC).release()); } StmtResult ActOnExprStmt(FullExprArg Expr); @@ -2258,7 +2467,8 @@ public: StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt); - StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, const AttrVec &Attrs, + StmtResult ActOnAttributedStmt(SourceLocation AttrLoc, + ArrayRef<const Attr*> Attrs, Stmt *SubStmt); StmtResult ActOnIfStmt(SourceLocation IfLoc, @@ -2285,12 +2495,14 @@ public: FullExprArg Third, SourceLocation RParenLoc, Stmt *Body); - ExprResult ActOnObjCForCollectionOperand(SourceLocation forLoc, + ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection); StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, SourceLocation LParenLoc, - Stmt *First, Expr *Second, - SourceLocation RParenLoc, Stmt *Body); + Stmt *First, Expr *collection, + SourceLocation RParenLoc); + StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body); + StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, @@ -2329,6 +2541,10 @@ public: SourceLocation RParenLoc, bool MSAsm = false); + StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, + ArrayRef<Token> AsmToks, + ArrayRef<unsigned> LineEnds, + SourceLocation EndLoc); VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, @@ -2408,21 +2624,21 @@ public: void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody); - ParsingDeclState PushParsingDeclaration() { - return DelayedDiagnostics.pushParsingDecl(); - } - void PopParsingDeclaration(ParsingDeclState state, Decl *decl) { - DelayedDiagnostics::popParsingDecl(*this, state, decl); + ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) { + return DelayedDiagnostics.push(pool); } + void PopParsingDeclaration(ParsingDeclState state, Decl *decl); typedef ProcessingContextState ParsingClassState; ParsingClassState PushParsingClass() { - return DelayedDiagnostics.pushContext(); + return DelayedDiagnostics.pushUndelayed(); } void PopParsingClass(ParsingClassState state) { - DelayedDiagnostics.popContext(state); + DelayedDiagnostics.popUndelayed(state); } + void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); + void EmitDeprecationWarning(NamedDecl *D, StringRef Message, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=0); @@ -2484,13 +2700,13 @@ public: /// /// \param Loc The location at which the capture occurs. /// - /// \param Kind The kind of capture, which may be implicit (for either a + /// \param Kind The kind of capture, which may be implicit (for either a /// block or a lambda), or explicit by-value or by-reference (for a lambda). /// /// \param EllipsisLoc The location of the ellipsis, if one is provided in /// an explicit lambda capture. /// - /// \param BuildAndDiagnose Whether we are actually supposed to add the + /// \param BuildAndDiagnose Whether we are actually supposed to add the /// captures or diagnose errors. If false, this routine merely check whether /// the capture can occur without performing the capture itself or complaining /// if the variable cannot be captured. @@ -2499,14 +2715,14 @@ public: /// this variable in the innermost block or lambda. Only valid when the /// variable can be captured. /// - /// \param DeclRefType Will be set to the type of a refernce to the capture - /// from within the current scope. Only valid when the variable can be + /// \param DeclRefType Will be set to the type of a reference to the capture + /// from within the current scope. Only valid when the variable can be /// captured. /// /// \returns true if an error occurred (i.e., the variable cannot be /// captured) and false if the capture succeeded. bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind, - SourceLocation EllipsisLoc, bool BuildAndDiagnose, + SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType); @@ -2514,13 +2730,13 @@ public: bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind = TryCapture_Implicit, SourceLocation EllipsisLoc = SourceLocation()); - + /// \brief Given a variable, determine the type that a reference to that /// variable will have in the given scope. QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc); - + void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); - void MarkDeclarationsReferencedInExpr(Expr *E, + void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables = false); /// \brief Try to recover by turning the given expression into a @@ -2537,10 +2753,10 @@ public: /// \brief Conditionally issue a diagnostic based on the current /// evaluation context. /// - /// \param stmt - If stmt is non-null, delay reporting the diagnostic until - /// the function body is parsed, and then do a basic reachability analysis to - /// determine if the statement is reachable. If it is unreachable, the - /// diagnostic will not be emitted. + /// \param Statement If Statement is non-null, delay reporting the + /// diagnostic until the function body is parsed, and then do a basic + /// reachability analysis to determine if the statement is reachable. + /// If it is unreachable, the diagnostic will not be emitted. bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD); @@ -2696,6 +2912,18 @@ public: const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); + // This struct is for use by ActOnMemberAccess to allow + // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after + // changing the access operator from a '.' to a '->' (to see if that is the + // change needed to fix an error about an unknown member, e.g. when the class + // defines a custom operator->). + struct ActOnMemberAccessExtraArgs { + Scope *S; + UnqualifiedId &Id; + Decl *ObjCImpDecl; + bool HasTrailingLParen; + }; + ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, const CXXScopeSpec &SS, @@ -2703,7 +2931,8 @@ public: NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, - bool SuppressQualifierCheck = false); + bool SuppressQualifierCheck = false, + ActOnMemberAccessExtraArgs *ExtraArgs = 0); ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow); ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base, @@ -2901,7 +3130,8 @@ public: /// ActOnBlockArguments - This callback allows processing of block arguments. /// If there are no arguments, this is still invoked. - void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope); + void ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, + Scope *CurScope); /// ActOnBlockError - If there is an error parsing a block, this callback /// is invoked to pop the information about the block from the action impl. @@ -3010,7 +3240,7 @@ public: TypeResult Type); /// InitializeVarWithConstructor - Creates an CXXConstructExpr - /// and sets it as the initializer for the the passed in VarDecl. + /// and sets it as the initializer for the passed in VarDecl. bool InitializeVarWithConstructor(VarDecl *VD, CXXConstructorDecl *Constructor, MultiExprArg Exprs, @@ -3075,7 +3305,7 @@ public: public: explicit ImplicitExceptionSpecification(Sema &Self) : Self(&Self), ComputedEST(EST_BasicNoexcept) { - if (!Self.Context.getLangOpts().CPlusPlus0x) + if (!Self.getLangOpts().CPlusPlus0x) ComputedEST = EST_DynamicNone; } @@ -3098,17 +3328,16 @@ public: /// \brief Integrate an invoked expression into the collected data. void CalledExpr(Expr *E); - /// \brief Specify that the exception specification can't be detemined yet. - void SetDelayed() { - ClearExceptions(); - ComputedEST = EST_Delayed; - } - - FunctionProtoType::ExtProtoInfo getEPI() const { - FunctionProtoType::ExtProtoInfo EPI; + /// \brief Overwrite an EPI's exception specification with this + /// computed exception specification. + void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const { EPI.ExceptionSpecType = getExceptionSpecType(); EPI.NumExceptions = size(); EPI.Exceptions = data(); + } + FunctionProtoType::ExtProtoInfo getEPI() const { + FunctionProtoType::ExtProtoInfo EPI; + getEPI(EPI); return EPI; } }; @@ -3116,34 +3345,39 @@ public: /// \brief Determine what sort of exception specification a defaulted /// copy constructor of a class will have. ImplicitExceptionSpecification - ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl); + ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc, + CXXMethodDecl *MD); /// \brief Determine what sort of exception specification a defaulted /// default constructor of a class will have, and whether the parameter /// will be const. - std::pair<ImplicitExceptionSpecification, bool> - ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl); + ImplicitExceptionSpecification + ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD); /// \brief Determine what sort of exception specification a defautled /// copy assignment operator of a class will have, and whether the /// parameter will be const. - std::pair<ImplicitExceptionSpecification, bool> - ComputeDefaultedCopyAssignmentExceptionSpecAndConst(CXXRecordDecl *ClassDecl); + ImplicitExceptionSpecification + ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD); /// \brief Determine what sort of exception specification a defaulted move /// constructor of a class will have. ImplicitExceptionSpecification - ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl); + ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD); /// \brief Determine what sort of exception specification a defaulted move /// assignment operator of a class will have. ImplicitExceptionSpecification - ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl); + ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD); /// \brief Determine what sort of exception specification a defaulted /// destructor of a class will have. ImplicitExceptionSpecification - ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl); + ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD); + + /// \brief Evaluate the implicit exception specification for a defaulted + /// special member function. + void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD); /// \brief Check the given exception-specification and update the /// extended prototype information with the results. @@ -3191,8 +3425,7 @@ public: /// C++11 says that user-defined destructors with no exception spec get one /// that looks as if the destructor was implicitly declared. void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, - CXXDestructorDecl *Destructor, - bool WasDelayed = false); + CXXDestructorDecl *Destructor); /// \brief Declare all inherited constructors for the given class. /// @@ -3259,7 +3492,7 @@ public: /// \brief Determine whether the given function is an implicitly-deleted /// special member function. bool isImplicitlyDeleted(FunctionDecl *FD); - + /// \brief Check whether 'this' shows up in the type of a static member /// function after the (naturally empty) cv-qualifier-seq would be. /// @@ -3275,7 +3508,7 @@ public: /// /// \returns true if an error occurred. bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method); - + /// MaybeBindToTemporary - If the passed in expression has a record type with /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise /// it simply returns the passed in expression. @@ -3352,34 +3585,32 @@ public: /// \brief Try to retrieve the type of the 'this' pointer. /// - /// \param Capture If true, capture 'this' in this context. - /// /// \returns The type of 'this', if possible. Otherwise, returns a NULL type. QualType getCurrentThisType(); - /// \brief When non-NULL, the C++ 'this' expression is allowed despite the + /// \brief When non-NULL, the C++ 'this' expression is allowed despite the /// current context not being a non-static member function. In such cases, /// this provides the type used for 'this'. QualType CXXThisTypeOverride; - + /// \brief RAII object used to temporarily allow the C++ 'this' expression /// to be used, with the given qualifiers on the current class type. class CXXThisScopeRAII { Sema &S; QualType OldCXXThisTypeOverride; bool Enabled; - + public: /// \brief Introduce a new scope where 'this' may be allowed (when enabled), - /// using the given declaration (which is either a class template or a + /// using the given declaration (which is either a class template or a /// class) along with the given qualifiers. /// along with the qualifiers placed on '*this'. - CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals, + CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals, bool Enabled = true); - + ~CXXThisScopeRAII(); }; - + /// \brief Make sure the value of 'this' is actually available in the current /// context, if it is a potentially evaluated context. /// @@ -3390,14 +3621,14 @@ public: void CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false); /// \brief Determine whether the given type is the type of *this that is used - /// outside of the body of a member function for a type that is currently + /// outside of the body of a member function for a type that is currently /// being defined. bool isThisOutsideMemberFunctionBody(QualType BaseType); - + /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); - - + + /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); @@ -3513,7 +3744,7 @@ public: ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef<TypeSourceInfo *> Args, SourceLocation RParenLoc); - + /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support /// pseudo-functions. ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, @@ -3572,7 +3803,7 @@ public: ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, - SourceLocation TildeLoc, + SourceLocation TildeLoc, const DeclSpec& DS, bool HasTrailingLParen); @@ -3583,7 +3814,11 @@ public: Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); - ExprResult ActOnFinishFullExpr(Expr *Expr); + ExprResult ActOnFinishFullExpr(Expr *Expr) { + return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() + : SourceLocation()); + } + ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC); StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. @@ -3660,7 +3895,7 @@ public: ExprResult ActOnDecltypeExpression(Expr *E); bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, - const DeclSpec &DS, + const DeclSpec &DS, SourceLocation ColonColonLoc); bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS, @@ -3681,7 +3916,7 @@ public: /// including this new type). /// /// \param TemplateKWLoc the location of the 'template' keyword, if any. - /// \param TemplateName The template name. + /// \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. @@ -3696,7 +3931,7 @@ public: bool ActOnCXXNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - TemplateTy Template, + TemplateTy TemplateName, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, @@ -3759,17 +3994,14 @@ public: /// \brief Create a new lambda closure type. CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange, bool KnownDependent = false); - + /// \brief Start the definition of a lambda expression. CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, TypeSourceInfo *MethodType, SourceLocation EndLoc, - llvm::ArrayRef<ParmVarDecl *> Params, - llvm::Optional<unsigned> ManglingNumber - = llvm::Optional<unsigned>(), - Decl *ContextDecl = 0); - + llvm::ArrayRef<ParmVarDecl *> Params); + /// \brief Introduce the scope for a lambda expression. sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator, SourceRange IntroducerRange, @@ -3777,16 +4009,20 @@ public: bool ExplicitParams, bool ExplicitResultType, bool Mutable); - + /// \brief Note that we have finished the explicit captures for the /// given lambda. void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI); - + /// \brief Introduce the lambda parameters into scope. void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope); - + + /// \brief Deduce a block or lambda's return type based on the return + /// statements present in the body. + void deduceClosureReturnType(sema::CapturingScopeInfo &CSI); + /// ActOnStartOfLambdaDefinition - This is called just before we start - /// parsing the body of a lambda; it analyzes the explicit captures and + /// parsing the body of a lambda; it analyzes the explicit captures and /// arguments, and sets up various data-structures for the body of the /// lambda. void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, @@ -3800,10 +4036,10 @@ public: /// ActOnLambdaExpr - This is called when the body of a lambda expression /// was successfully completed. ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, - Scope *CurScope, + Scope *CurScope, bool IsInstantiation = false); - /// \brief Define the "body" of the conversion from a lambda object to a + /// \brief Define the "body" of the conversion from a lambda object to a /// function pointer. /// /// This routine doesn't actually define a sensible body; rather, it fills @@ -3813,7 +4049,7 @@ public: void DefineImplicitLambdaToFunctionPointerConversion( SourceLocation CurrentLoc, CXXConversionDecl *Conv); - /// \brief Define the "body" of the conversion from a lambda object to a + /// \brief Define the "body" of the conversion from a lambda object to a /// block pointer. /// /// This routine doesn't actually define a sensible body; rather, it fills @@ -3832,26 +4068,33 @@ public: ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, Expr **Strings, unsigned NumStrings); - + ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); - - /// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the + + /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the /// numeric literal expression. Type of the expression will be "NSNumber *" /// or "id" if NSNumber is unavailable. ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number); ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc, bool Value); ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements); - + + /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the + /// '@' prefixed parenthesized expression. The type of the expression will + /// either be "NSNumber *" or "NSString *" depending on the type of + /// ValueType, which is allowed to be a built-in numeric type or + /// "char *" or "const char *". + ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr); + ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod); - - ExprResult BuildObjCDictionaryLiteral(SourceRange SR, + + ExprResult BuildObjCDictionaryLiteral(SourceRange SR, ObjCDictionaryElement *Elements, unsigned NumElements); - + ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc); @@ -3865,18 +4108,19 @@ public: ParsedType Ty, SourceLocation RParenLoc); - // ParseObjCSelectorExpression - Build selector expression for @selector + /// ParseObjCSelectorExpression - Build selector expression for \@selector ExprResult ParseObjCSelectorExpression(Selector Sel, SourceLocation AtLoc, SourceLocation SelLoc, SourceLocation LParenLoc, SourceLocation RParenLoc); - // ParseObjCProtocolExpression - Build protocol expression for @protocol + /// ParseObjCProtocolExpression - Build protocol expression for \@protocol ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName, SourceLocation AtLoc, SourceLocation ProtoLoc, SourceLocation LParenLoc, + SourceLocation ProtoIdLoc, SourceLocation RParenLoc); //===--------------------------------------------------------------------===// @@ -3907,7 +4151,7 @@ public: Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, - bool HasDeferredInit); + InClassInitStyle InitStyle); void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, Expr *Init); @@ -4004,6 +4248,11 @@ public: void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, bool DefinitionRequired = false); + /// \brief Mark the exception specifications of all virtual member functions + /// in the given class as needed. + void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc, + const CXXRecordDecl *RD); + /// MarkVirtualMembersReferenced - Will mark all members of the given /// CXXRecordDecl referenced. void MarkVirtualMembersReferenced(SourceLocation Loc, @@ -4047,6 +4296,11 @@ public: Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc); + Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, + Expr *AssertExpr, + StringLiteral *AssertMessageExpr, + SourceLocation RParenLoc, + bool Failed); FriendDecl *CheckFriendTypeDecl(SourceLocation Loc, SourceLocation FriendLoc, @@ -4067,12 +4321,7 @@ public: Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); void CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record); - void CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *Ctor); - void CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *Ctor); - void CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *Method); - void CheckExplicitlyDefaultedMoveConstructor(CXXConstructorDecl *Ctor); - void CheckExplicitlyDefaultedMoveAssignment(CXXMethodDecl *Method); - void CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *Dtor); + void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD); //===--------------------------------------------------------------------===// // C++ Derived Classes @@ -4130,12 +4379,12 @@ public: bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); - /// CheckOverrideControl - Check C++0x override control semantics. - void CheckOverrideControl(const Decl *D); + /// CheckOverrideControl - Check C++11 override control semantics. + void CheckOverrideControl(Decl *D); /// CheckForFunctionMarkedFinal - Checks whether a virtual member function /// overrides a virtual member function marked 'final', according to - /// C++0x [class.virtual]p3. + /// C++11 [class.virtual]p4. bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, const CXXMethodDecl *Old); @@ -4178,9 +4427,7 @@ public: CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType = QualType()); - AccessResult CheckDirectMemberAccess(SourceLocation Loc, - NamedDecl *D, - const PartialDiagnostic &PDiag); + AccessResult CheckFriendAccess(NamedDecl *D); AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, Expr *ArgExpr, @@ -4206,36 +4453,10 @@ public: void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); - /// A flag to suppress access checking. - bool SuppressAccessChecking; - /// \brief When true, access checking violations are treated as SFINAE /// failures rather than hard errors. bool AccessCheckingSFINAE; - /// \brief RAII object used to temporarily suppress access checking. - class SuppressAccessChecksRAII { - Sema &S; - bool SuppressingAccess; - - public: - SuppressAccessChecksRAII(Sema &S, bool Suppress) - : S(S), SuppressingAccess(Suppress) { - if (Suppress) S.ActOnStartSuppressingAccessChecks(); - } - ~SuppressAccessChecksRAII() { - done(); - } - void done() { - if (!SuppressingAccess) return; - S.ActOnStopSuppressingAccessChecks(); - SuppressingAccess = false; - } - }; - - void ActOnStartSuppressingAccessChecks(); - void ActOnStopSuppressingAccessChecks(); - enum AbstractDiagSelID { AbstractNone = -1, AbstractReturnType, @@ -4246,7 +4467,31 @@ public: }; bool RequireNonAbstractType(SourceLocation Loc, QualType T, - const PartialDiagnostic &PD); + TypeDiagnoser &Diagnoser); + template<typename T1> + bool RequireNonAbstractType(SourceLocation Loc, QualType T, + unsigned DiagID, + const T1 &Arg1) { + BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); + return RequireNonAbstractType(Loc, T, Diagnoser); + } + + template<typename T1, typename T2> + bool RequireNonAbstractType(SourceLocation Loc, QualType T, + unsigned DiagID, + const T1 &Arg1, const T2 &Arg2) { + BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); + return RequireNonAbstractType(Loc, T, Diagnoser); + } + + template<typename T1, typename T2, typename T3> + bool RequireNonAbstractType(SourceLocation Loc, QualType T, + unsigned DiagID, + const T1 &Arg1, const T2 &Arg2, const T3 &Arg3) { + BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, Arg3); + return RequireNonAbstractType(Loc, T, Diagnoser); + } + void DiagnoseAbstractType(const CXXRecordDecl *RD); bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, @@ -4263,9 +4508,9 @@ public: //===--------------------------------------------------------------------===// // C++ Templates [C++ 14] // - void FilterAcceptableTemplateNames(LookupResult &R, + void FilterAcceptableTemplateNames(LookupResult &R, bool AllowFunctionTemplates = true); - bool hasAnyAcceptableTemplateNames(LookupResult &R, + bool hasAnyAcceptableTemplateNames(LookupResult &R, bool AllowFunctionTemplates = true); void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, @@ -4638,7 +4883,7 @@ public: ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, const CXXScopeSpec &SS, SourceLocation TemplateLoc, - TemplateTy Template, + TemplateTy TemplateName, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, @@ -4730,7 +4975,13 @@ public: UPPC_IfExists, /// \brief Microsoft __if_not_exists. - UPPC_IfNotExists + UPPC_IfNotExists, + + /// \brief Lambda expression. + UPPC_Lambda, + + /// \brief Block expression, + UPPC_Block }; /// \brief Diagnose unexpanded parameter packs. @@ -4741,7 +4992,9 @@ public: /// parameter packs. /// /// \param Unexpanded the set of unexpanded parameter packs. - void DiagnoseUnexpandedParameterPacks(SourceLocation Loc, + /// + /// \returns true if an error occurred, false otherwise. + bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc, UnexpandedParameterPackContext UPPC, ArrayRef<UnexpandedParameterPack> Unexpanded); @@ -4922,9 +5175,6 @@ public: /// \param Unexpanded The set of unexpanded parameter packs within the /// pattern. /// - /// \param NumUnexpanded The number of unexpanded parameter packs in - /// \p Unexpanded. - /// /// \param ShouldExpand Will be set to \c true if the transformer should /// expand the corresponding pack expansions into separate arguments. When /// set, \c NumExpansions must also be set. @@ -4957,10 +5207,11 @@ public: /// \brief Determine the number of arguments in the given pack expansion /// type. /// - /// This routine already assumes that the pack expansion type can be - /// expanded and that the number of arguments in the expansion is + /// This routine assumes that the number of arguments in the expansion is /// consistent across all of the unexpanded parameter packs in its pattern. - unsigned getNumArgumentsInExpansion(QualType T, + /// + /// Returns an empty Optional if the type can't be expanded. + llvm::Optional<unsigned> getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs); /// \brief Determine whether the given declarator contains any unexpanded @@ -5366,16 +5617,14 @@ public: /// template-id. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange = SourceRange()); /// \brief Note that we are instantiating a default argument in a /// template-id. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionTemplateDecl *FunctionTemplate, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, ActiveTemplateInstantiation::InstantiationKind Kind, sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); @@ -5385,15 +5634,13 @@ public: /// specialization. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ClassTemplatePartialSpecializationDecl *PartialSpec, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange = SourceRange()); /// \brief Note that we are substituting prior template arguments into a @@ -5401,15 +5648,13 @@ public: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template, NonTypeTemplateParmDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange); InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template, TemplateTemplateParmDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange); /// \brief Note that we are checking the default template argument @@ -5417,8 +5662,7 @@ public: InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, NamedDecl *Param, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange); @@ -5456,6 +5700,14 @@ public: /// diagnostics that will be suppressed. llvm::Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const; + /// \brief Determines whether we are currently in a context that + /// is not evaluated as per C++ [expr] p5. + bool isUnevaluatedContext() const { + assert(!ExprEvalContexts.empty() && + "Must be in an expression evaluation context"); + return ExprEvalContexts.back().Context == Sema::Unevaluated; + } + /// \brief RAII class used to determine whether SFINAE has /// trapped any errors that occur during template argument /// deduction.` @@ -5705,7 +5957,7 @@ public: SourceLocation EndProtoLoc, AttributeList *AttrList); - Decl *ActOnCompatiblityAlias( + Decl *ActOnCompatibilityAlias( SourceLocation AtCompatibilityAliasLoc, IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation); @@ -5768,28 +6020,27 @@ public: /// be modified to be consistent with \arg PropertyTy. void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, - unsigned &Attributes); + unsigned &Attributes, + bool propertyInPrimaryClass); /// Process the specified property declaration and create decls for the /// setters and getters as needed. /// \param property The property declaration being processed - /// \param DC The semantic container for the property + /// \param CD The semantic container for the property /// \param redeclaredProperty Declaration for property if redeclared /// in class extension. /// \param lexicalDC Container for redeclaredProperty. void ProcessPropertyDecl(ObjCPropertyDecl *property, - ObjCContainerDecl *DC, + ObjCContainerDecl *CD, ObjCPropertyDecl *redeclaredProperty = 0, ObjCContainerDecl *lexicalDC = 0); + void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name); void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl); - void CompareMethodParamsInBaseAndSuper(Decl *IDecl, - ObjCMethodDecl *MethodDecl, - bool IsInstance); void CompareProperties(Decl *CDecl, Decl *MergeProtocols); @@ -5855,14 +6106,6 @@ public: AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind, bool isVariadic, bool MethodDefinition); - // Helper method for ActOnClassMethod/ActOnInstanceMethod. - // Will search "local" class/category implementations for a method decl. - // Will also search in class's root looking for instance method. - // Returns 0 if no method is found. - ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel, - ObjCInterfaceDecl *CDecl); - ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel, - ObjCInterfaceDecl *ClassDecl); ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel, const ObjCObjectPointerType *OPT, bool IsInstance); @@ -5988,9 +6231,16 @@ public: const ObjCMethodDecl *Overridden, bool IsImplementation); - /// \brief Check whether the given method overrides any methods in its class, - /// calling \c CheckObjCMethodOverride for each overridden method. - bool CheckObjCMethodOverrides(ObjCMethodDecl *NewMethod, DeclContext *DC); + /// \brief Describes the compatibility of a result type with its method. + enum ResultTypeCompatibilityKind { + RTC_Compatible, + RTC_Incompatible, + RTC_Unknown + }; + + void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod, + ObjCInterfaceDecl *CurrentClass, + ResultTypeCompatibilityKind RTC); enum PragmaOptionsAlignKind { POAK_Native, // #pragma options align=native @@ -6001,7 +6251,7 @@ public: POAK_Reset // #pragma options align=reset }; - /// ActOnPragmaOptionsAlign - Called on well formed #pragma options align. + /// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align. void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc, SourceLocation KindLoc); @@ -6018,7 +6268,7 @@ public: PMSST_ON // #pragms ms_struct on }; - /// ActOnPragmaPack - Called on well formed #pragma pack(...). + /// ActOnPragmaPack - Called on well formed \#pragma pack(...). void ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, Expr *Alignment, @@ -6026,15 +6276,15 @@ public: SourceLocation LParenLoc, SourceLocation RParenLoc); - /// ActOnPragmaMSStruct - Called on well formed #pragms ms_struct [on|off]. + /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. void ActOnPragmaMSStruct(PragmaMSStructKind Kind); - /// ActOnPragmaUnused - Called on well-formed '#pragma unused'. + /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, SourceLocation PragmaLoc); - /// ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... . + /// ActOnPragmaVisibility - Called on well formed \#pragma GCC visibility... . void ActOnPragmaVisibility(const IdentifierInfo* VisType, SourceLocation PragmaLoc); @@ -6042,20 +6292,20 @@ public: SourceLocation Loc); void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W); - /// ActOnPragmaWeakID - Called on well formed #pragma weak ident. + /// ActOnPragmaWeakID - Called on well formed \#pragma weak ident. void ActOnPragmaWeakID(IdentifierInfo* WeakName, SourceLocation PragmaLoc, SourceLocation WeakNameLoc); - /// ActOnPragmaRedefineExtname - Called on well formed - /// #pragma redefine_extname oldname newname. + /// ActOnPragmaRedefineExtname - Called on well formed + /// \#pragma redefine_extname oldname newname. void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName, IdentifierInfo* AliasName, SourceLocation PragmaLoc, SourceLocation WeakNameLoc, SourceLocation AliasNameLoc); - /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident. + /// ActOnPragmaWeakAlias - Called on well formed \#pragma weak ident = ident. void ActOnPragmaWeakAlias(IdentifierInfo* WeakName, IdentifierInfo* AliasName, SourceLocation PragmaLoc, @@ -6063,11 +6313,11 @@ public: SourceLocation AliasNameLoc); /// ActOnPragmaFPContract - Called on well formed - /// #pragma {STDC,OPENCL} FP_CONTRACT + /// \#pragma {STDC,OPENCL} FP_CONTRACT void ActOnPragmaFPContract(tok::OnOffSwitch OOS); /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to - /// a the record decl, to handle '#pragma pack' and '#pragma options align'. + /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. void AddAlignmentAttributesForRecord(RecordDecl *RD); /// AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record. @@ -6081,25 +6331,27 @@ public: void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, SourceLocation Loc); - /// AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used, + /// AddPushedVisibilityAttribute - If '\#pragma GCC visibility' was used, /// add an appropriate visibility attribute. void AddPushedVisibilityAttribute(Decl *RD); /// PopPragmaVisibility - Pop the top element of the visibility stack; used - /// for '#pragma GCC visibility' and visibility attributes on namespaces. + /// for '\#pragma GCC visibility' and visibility attributes on namespaces. void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc); /// FreeVisContext - Deallocate and null out VisContext. void FreeVisContext(); /// AddCFAuditedAttribute - Check whether we're currently within - /// '#pragma clang arc_cf_code_audited' and, if so, consider adding + /// '\#pragma clang arc_cf_code_audited' and, if so, consider adding /// the appropriate attribute. void AddCFAuditedAttribute(Decl *D); /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. - void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E); - void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T); + void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, + bool isDeclSpec); + void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T, + bool isDeclSpec); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -6164,6 +6416,21 @@ public: VariadicDoesNotApply }; + VariadicCallType getVariadicCallType(FunctionDecl *FDecl, + const FunctionProtoType *Proto, + Expr *Fn); + + // Used for determining in which context a type is allowed to be passed to a + // vararg function. + enum VarArgKind { + VAK_Valid, + VAK_ValidInCXX11, + VAK_Invalid + }; + + // Determines which VarArgKind fits an expression. + VarArgKind isValidVarArgType(const QualType &Ty); + /// GatherArgumentsForCall - Collector argument expressions for various /// form of call prototypes. bool GatherArgumentsForCall(SourceLocation CallLoc, @@ -6176,10 +6443,14 @@ public: bool AllowExplicit = false); // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but - // will warn if the resulting type is not a POD type. + // will create a runtime trap if the resulting type is not a POD type. ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl); + /// Checks to see if the given expression is a valid argument to a variadic + /// function, issuing a diagnostic and returning NULL if not. + bool variadicArgumentPODCheck(const Expr *E, VariadicCallType CT); + // UsualArithmeticConversions - performs the UsualUnaryConversions on it's // operands and then handles various conversions that are common to binary // operators (C99 6.3.1.8). If both operands aren't arithmetic, this @@ -6269,6 +6540,11 @@ public: Expr *SrcExpr, AssignmentAction Action, bool *Complained = 0); + /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant + /// integer not in the range of enum values. + void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, + Expr *SrcExpr); + /// CheckAssignmentConstraints - Perform type checking for assignment, /// argument passing, variable initialization, and function return values. /// C99 6.5.16. @@ -6434,7 +6710,7 @@ public: /// \brief Force an expression with unknown-type to an expression of the /// given type. ExprResult forceUnknownAnyToType(Expr *E, QualType ToType); - + // CheckVectorCast - check type constraints for vectors. // Since vectors are an extension, there are no C standard reference for this. // We allow casting between vectors and integer datatypes of the same size. @@ -6540,20 +6816,29 @@ public: /// in the global scope. bool CheckObjCDeclScope(Decl *D); + /// \brief Abstract base class used for diagnosing integer constant + /// expression violations. + class VerifyICEDiagnoser { + public: + bool Suppress; + + VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { } + + virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) =0; + virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR); + virtual ~VerifyICEDiagnoser() { } + }; + /// VerifyIntegerConstantExpression - Verifies that an expression is an ICE, /// and reports the appropriate diagnostics. Returns false on success. /// Can optionally return the value of the expression. ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - const PartialDiagnostic &Diag, - bool AllowFold, - const PartialDiagnostic &FoldDiag); + VerifyICEDiagnoser &Diagnoser, + bool AllowFold = true); ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, - const PartialDiagnostic &Diag, - bool AllowFold = true) { - return VerifyIntegerConstantExpression(E, Result, Diag, AllowFold, - PDiag(0)); - } - ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result = 0); + unsigned DiagID, + bool AllowFold = true); + ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result=0); /// VerifyBitField - verifies that a bit field expression is an ICE and has /// the correct width, and that the field type is valid. @@ -6745,15 +7030,39 @@ private: const ArraySubscriptExpr *ASE=0, bool AllowOnePastEnd=true, bool IndexNegated=false); void CheckArrayAccess(const Expr *E); - bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); - bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, + // Used to grab the relevant information from a FormatAttr and a + // FunctionDeclaration. + struct FormatStringInfo { + unsigned FormatIdx; + unsigned FirstDataArg; + bool HasVAListArg; + }; + + bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, + FormatStringInfo *FSI); + bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, + const FunctionProtoType *Proto); + bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, Expr **Args, unsigned NumArgs); - bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall); + bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall, + const FunctionProtoType *Proto); + void CheckConstructorCall(FunctionDecl *FDecl, + Expr **Args, + unsigned NumArgs, + const FunctionProtoType *Proto, + SourceLocation Loc); + + void checkCall(NamedDecl *FDecl, Expr **Args, unsigned NumArgs, + unsigned NumProtoArgs, bool IsMemberFunction, + SourceLocation Loc, SourceRange Range, + VariadicCallType CallType); + bool CheckObjCString(Expr *Arg); ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); @@ -6783,23 +7092,36 @@ private: FST_Unknown }; static FormatStringType GetFormatStringType(const FormatAttr *Format); - bool SemaCheckStringLiteral(const Expr *E, Expr **Args, unsigned NumArgs, - bool HasVAListArg, unsigned format_idx, - unsigned firstDataArg, FormatStringType Type, - bool inFunctionCall = true); + + enum StringLiteralCheckType { + SLCT_NotALiteral, + SLCT_UncheckedLiteral, + SLCT_CheckedLiteral + }; + + StringLiteralCheckType checkFormatStringExpr(const Expr *E, + Expr **Args, unsigned NumArgs, + bool HasVAListArg, + unsigned format_idx, + unsigned firstDataArg, + FormatStringType Type, + VariadicCallType CallType, + bool inFunctionCall = true); void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr, Expr **Args, unsigned NumArgs, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, - FormatStringType Type, bool inFunctionCall); + FormatStringType Type, bool inFunctionCall, + VariadicCallType CallType); - void CheckFormatArguments(const FormatAttr *Format, CallExpr *TheCall); - void CheckFormatArguments(const FormatAttr *Format, Expr **Args, + bool CheckFormatArguments(const FormatAttr *Format, Expr **Args, unsigned NumArgs, bool IsCXXMember, + VariadicCallType CallType, SourceLocation Loc, SourceRange Range); - void CheckFormatArguments(Expr **Args, unsigned NumArgs, + bool CheckFormatArguments(Expr **Args, unsigned NumArgs, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, + VariadicCallType CallType, SourceLocation Loc, SourceRange range); void CheckNonNullArguments(const NonNullAttr *NonNull, diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index c16823a..273374d 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -152,10 +152,11 @@ namespace clang { /// \brief Construct an integral non-type template argument that /// has been deduced, possibly from an array bound. - DeducedTemplateArgument(const llvm::APSInt &Value, + DeducedTemplateArgument(ASTContext &Ctx, + const llvm::APSInt &Value, QualType ValueType, bool DeducedFromArrayBound) - : TemplateArgument(Value, ValueType), + : TemplateArgument(Ctx, Value, ValueType), DeducedFromArrayBound(DeducedFromArrayBound) { } /// \brief For a non-type template argument, determine whether the @@ -371,8 +372,10 @@ namespace clang { public: TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs) - : SemaRef(SemaRef), SubstIndex(SemaRef, -1), Owner(Owner), - TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0) { } + : SemaRef(SemaRef), + SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), + Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0) + { } // FIXME: Once we get closer to completion, replace these manually-written // declarations with automatically-generated ones from diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 100d56e..4c2d876 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -39,6 +39,9 @@ class TemplateDeductionInfo { /// deduction is occurring. SourceLocation Loc; + /// \brief Have we suppressed an error during deduction? + bool HasSFINAEDiagnostic; + /// \brief Warnings (and follow-on notes) that were suppressed due to /// SFINAE while performing template argument deduction. SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; @@ -49,7 +52,7 @@ class TemplateDeductionInfo { public: TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc) - : Context(Context), Deduced(0), Loc(Loc) { } + : Context(Context), Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { } ~TemplateDeductionInfo() { // FIXME: if (Deduced) Deduced->Destroy(Context); @@ -68,6 +71,15 @@ public: return Result; } + /// \brief Take ownership of the SFINAE diagnostic. + void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) { + assert(HasSFINAEDiagnostic); + PD.first = SuppressedDiagnostics.front().first; + PD.second.swap(SuppressedDiagnostics.front().second); + SuppressedDiagnostics.clear(); + HasSFINAEDiagnostic = false; + } + /// \brief Provide a new template argument list that contains the /// results of template argument deduction. void reset(TemplateArgumentList *NewDeduced) { @@ -75,10 +87,31 @@ public: Deduced = NewDeduced; } + /// \brief Is a SFINAE diagnostic available? + bool hasSFINAEDiagnostic() const { + return HasSFINAEDiagnostic; + } + + /// \brief Set the diagnostic which caused the SFINAE failure. + void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) { + // Only collect the first diagnostic. + if (HasSFINAEDiagnostic) + return; + SuppressedDiagnostics.clear(); + SuppressedDiagnostics.push_back( + std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); + SuppressedDiagnostics.back().second.swap(PD); + HasSFINAEDiagnostic = true; + } + /// \brief Add a new diagnostic to the set of diagnostics void addSuppressedDiagnostic(SourceLocation Loc, - const PartialDiagnostic &PD) { - SuppressedDiagnostics.push_back(std::make_pair(Loc, PD)); + PartialDiagnostic PD) { + if (HasSFINAEDiagnostic) + return; + SuppressedDiagnostics.push_back( + std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); + SuppressedDiagnostics.back().second.swap(PD); } /// \brief Iterator over the set of suppressed diagnostics. diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h index d36b970..6d1b64b 100644 --- a/include/clang/Sema/Weak.h +++ b/include/clang/Sema/Weak.h @@ -21,7 +21,7 @@ namespace clang { class IdentifierInfo; -/// \brief Captures information about a #pragma weak directive. +/// \brief Captures information about a \#pragma weak directive. class WeakInfo { IdentifierInfo *alias; // alias (optional) SourceLocation loc; // for diagnostics |