diff options
Diffstat (limited to 'include/clang/Sema')
-rw-r--r-- | include/clang/Sema/AttributeList.h | 108 | ||||
-rw-r--r-- | include/clang/Sema/CodeCompleteConsumer.h | 282 | ||||
-rw-r--r-- | include/clang/Sema/DeclSpec.h | 328 | ||||
-rw-r--r-- | include/clang/Sema/DelayedDiagnostic.h | 41 | ||||
-rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 8 | ||||
-rw-r--r-- | include/clang/Sema/Initialization.h | 55 | ||||
-rw-r--r-- | include/clang/Sema/Lookup.h | 20 | ||||
-rw-r--r-- | include/clang/Sema/Overload.h | 48 | ||||
-rw-r--r-- | include/clang/Sema/Ownership.h | 9 | ||||
-rw-r--r-- | include/clang/Sema/ParsedTemplate.h | 30 | ||||
-rw-r--r-- | include/clang/Sema/Scope.h | 23 | ||||
-rw-r--r-- | include/clang/Sema/ScopeInfo.h | 38 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 1325 | ||||
-rw-r--r-- | include/clang/Sema/SemaDiagnostic.h | 2 | ||||
-rw-r--r-- | include/clang/Sema/Template.h | 211 | ||||
-rw-r--r-- | include/clang/Sema/TemplateDeduction.h | 25 |
16 files changed, 1933 insertions, 620 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 5331647..45ee579 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_SEMA_ATTRLIST_H #define LLVM_CLANG_SEMA_ATTRLIST_H +#include "llvm/Support/Allocator.h" #include "clang/Sema/Ownership.h" #include "clang/Basic/SourceLocation.h" #include <cassert> @@ -32,6 +33,9 @@ namespace clang { /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. /// class AttributeList { +public: + class Factory; +private: IdentifierInfo *AttrName; SourceLocation AttrLoc; IdentifierInfo *ScopeName; @@ -42,17 +46,38 @@ class AttributeList { unsigned NumArgs; AttributeList *Next; bool DeclspecAttribute, CXX0XAttribute; - mutable bool Invalid; /// True if already diagnosed as invalid. + + /// True if already diagnosed as invalid. + mutable bool Invalid; + AttributeList(const AttributeList &); // DO NOT IMPLEMENT void operator=(const AttributeList &); // DO NOT IMPLEMENT -public: - AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc, + void operator delete(void *); // DO NOT IMPLEMENT + ~AttributeList(); // DO NOT IMPLEMENT + AttributeList(llvm::BumpPtrAllocator &Alloc, + IdentifierInfo *AttrName, SourceLocation AttrLoc, IdentifierInfo *ScopeName, SourceLocation ScopeLoc, IdentifierInfo *ParmName, SourceLocation ParmLoc, Expr **args, unsigned numargs, - AttributeList *Next, bool declspec = false, bool cxx0x = false); - ~AttributeList(); - + bool declspec, bool cxx0x); +public: + class Factory { + llvm::BumpPtrAllocator Alloc; + public: + Factory() {} + ~Factory() {} + AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc, + IdentifierInfo *ScopeName, SourceLocation ScopeLoc, + IdentifierInfo *ParmName, SourceLocation ParmLoc, + Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) { + AttributeList *Mem = Alloc.Allocate<AttributeList>(); + new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc, + ParmName, ParmLoc, args, numargs, + declspec, cxx0x); + return Mem; + } + }; + enum Kind { // Please keep this list alphabetized. AT_IBAction, // Clang-specific. AT_IBOutlet, // Clang-specific. @@ -68,35 +93,48 @@ public: AT_carries_dependency, AT_cdecl, AT_cleanup, + AT_common, AT_const, + AT_constant, AT_constructor, AT_deprecated, AT_destructor, + AT_device, AT_dllexport, AT_dllimport, AT_ext_vector_type, AT_fastcall, - AT_final, AT_format, AT_format_arg, + AT_global, AT_gnu_inline, - AT_hiding, + AT_host, + AT_launch_bounds, AT_malloc, + AT_may_alias, AT_mode, + AT_neon_polyvector_type, // Clang-specific. + AT_neon_vector_type, // Clang-specific. + AT_naked, AT_nodebug, AT_noinline, AT_no_instrument_function, + AT_nocommon, AT_nonnull, AT_noreturn, AT_nothrow, AT_nsobject, AT_objc_exception, - AT_override, AT_cf_returns_not_retained, // Clang-specific. AT_cf_returns_retained, // Clang-specific. AT_ns_returns_not_retained, // Clang-specific. AT_ns_returns_retained, // Clang-specific. + AT_ns_returns_autoreleased, // Clang-specific. + AT_cf_consumed, // Clang-specific. + AT_ns_consumed, // Clang-specific. + AT_ns_consumes_self, // Clang-specific. AT_objc_gc, + AT_opencl_kernel_function, // OpenCL-specific. AT_overloadable, // Clang-specific. AT_ownership_holds, // Clang-specific. AT_ownership_returns, // Clang-specific. @@ -107,12 +145,14 @@ public: AT_regparm, AT_section, AT_sentinel, + AT_shared, AT_stdcall, AT_thiscall, AT_transparent_union, AT_unavailable, AT_unused, AT_used, + AT_uuid, AT_vecreturn, // PS3 PPU-specific. AT_vector_size, AT_visibility, @@ -134,6 +174,7 @@ public: SourceLocation getScopeLoc() const { return ScopeLoc; } IdentifierInfo *getParameterName() const { return ParmName; } + SourceLocation getParameterLoc() const { return ParmLoc; } bool isDeclspecAttribute() const { return DeclspecAttribute; } bool isCXX0XAttribute() const { return CXX0XAttribute; } @@ -199,8 +240,8 @@ public: /// The right-hand list is appended to the left-hand list, if any /// A pointer to the joined list is returned. /// Note: the lists are not left unmodified. -inline AttributeList* addAttributeLists (AttributeList *Left, - AttributeList *Right) { +inline AttributeList *addAttributeLists(AttributeList *Left, + AttributeList *Right) { if (!Left) return Right; @@ -229,6 +270,51 @@ struct CXX0XAttributeList { } }; +/// ParsedAttributes - A collection of parsed attributes. Currently +/// we don't differentiate between the various attribute syntaxes, +/// which is basically silly. +/// +/// Right now this is a very lightweight container, but the expectation +/// is that this will become significantly more serious. +class ParsedAttributes { +public: + ParsedAttributes() : list(0) {} + + bool empty() const { return list == 0; } + + void add(AttributeList *newAttr) { + assert(newAttr); + assert(newAttr->getNext() == 0); + newAttr->setNext(list); + list = newAttr; + } + + void append(AttributeList *newList) { + if (!newList) return; + + AttributeList *lastInNewList = newList; + while (AttributeList *next = lastInNewList->getNext()) + lastInNewList = next; + + lastInNewList->setNext(list); + list = newList; + } + + void set(AttributeList *newList) { + list = newList; + } + + void clear() { list = 0; } + AttributeList *getList() const { return list; } + + /// Returns a reference to the attribute list. Try not to introduce + /// dependencies on this method, it may not be long-lived. + AttributeList *&getListRef() { return list; } + +private: + AttributeList *list; +}; + } // end namespace clang #endif diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 6c1ecbf..882440b 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -17,12 +17,13 @@ #include "clang/AST/CanonicalType.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" #include "clang-c/Index.h" -#include <memory> #include <string> namespace llvm { class raw_ostream; + class Twine; } namespace clang { @@ -35,31 +36,37 @@ enum { /// \brief Priority for the next initialization in a constructor initializer /// list. CCP_NextInitializer = 7, + /// \brief Priority for an enumeration constant inside a switch whose + /// condition is of the enumeration type. + CCP_EnumInCase = 7, /// \brief Priority for a send-to-super completion. - CCP_SuperCompletion = 8, + CCP_SuperCompletion = 20, /// \brief Priority for a declaration that is in the local scope. - CCP_LocalDeclaration = 8, + CCP_LocalDeclaration = 34, /// \brief Priority for a member declaration found from the current /// method or member function. - CCP_MemberDeclaration = 20, + CCP_MemberDeclaration = 35, /// \brief Priority for a language keyword (that isn't any of the other /// categories). - CCP_Keyword = 30, + CCP_Keyword = 40, /// \brief Priority for a code pattern. - CCP_CodePattern = 30, + CCP_CodePattern = 40, /// \brief Priority for a non-type declaration. CCP_Declaration = 50, - /// \brief Priority for a constant value (e.g., enumerator). - CCP_Constant = 60, /// \brief Priority for a type. - CCP_Type = 65, + CCP_Type = CCP_Declaration, + /// \brief Priority for a constant value (e.g., enumerator). + CCP_Constant = 65, /// \brief Priority for a preprocessor macro. CCP_Macro = 70, /// \brief Priority for a nested-name-specifier. CCP_NestedNameSpecifier = 75, /// \brief Priority for a result that isn't likely to be what the user wants, /// but is included for completeness. - CCP_Unlikely = 80 + CCP_Unlikely = 80, + + /// \brief Priority for the Objective-C "_cmd" implicit parameter. + CCP_ObjC_cmd = CCP_Unlikely }; /// \brief Priority value deltas that are added to code-completion results @@ -67,18 +74,21 @@ enum { enum { /// \brief The result is in a base class. CCD_InBaseClass = 2, - /// \brief The result is a type match against void. - /// - /// Since everything converts to "void", we don't give as drastic an - /// adjustment for matching void. - CCD_VoidMatch = -5, /// \brief The result is a C++ non-static member function whose qualifiers /// exactly match the object type on which the member function can be called. CCD_ObjectQualifierMatch = -1, /// \brief The selector of the given message exactly matches the selector /// of the current method, which might imply that some kind of delegation /// is occurring. - CCD_SelectorMatch = -3 + CCD_SelectorMatch = -3, + + /// \brief Adjustment to the "bool" type in Objective-C, where the typedef + /// "BOOL" is preferred. + CCD_bool_in_ObjC = 1, + + /// \brief Adjustment for KVC code pattern priorities when it doesn't look + /// like the + CCD_ProbablyNotObjCCollection = 15 }; /// \brief Priority value factors by which we will divide or multiply the @@ -119,9 +129,12 @@ QualType getDeclUsageType(ASTContext &C, NamedDecl *ND); /// /// \param MacroName The name of the macro. /// +/// \param LangOpts Options describing the current language dialect. +/// /// \param PreferredTypeIsPointer Whether the preferred type for the context /// of this macro is a pointer type. unsigned getMacroUsagePriority(llvm::StringRef MacroName, + const LangOptions &LangOpts, bool PreferredTypeIsPointer = false); /// \brief Determine the libclang cursor kind associated with the given @@ -143,6 +156,9 @@ public: enum Kind { /// \brief An unspecified code-completion context. CCC_Other, + /// \brief An unspecified code-completion context where we should also add + /// macro completions. + CCC_OtherWithMacros, /// \brief Code completion occurred within a "top-level" completion context, /// e.g., at namespace or global scope. CCC_TopLevel, @@ -212,7 +228,13 @@ public: /// \brief Code completion for a selector, as in an @selector expression. CCC_SelectorName, /// \brief Code completion within a type-qualifier list. - CCC_TypeQualifiers + CCC_TypeQualifiers, + /// \brief Code completion in a parenthesized expression, which means that + /// we may also have types here in C and Objective-C (as well as in C++). + CCC_ParenthesizedExpression, + /// \brief An unknown context, in which we are recovering from a parsing + /// error and don't know which completions we should give. + CCC_Recovery }; private: @@ -248,6 +270,10 @@ public: /// \brief Retrieve the type of the base object in a member-access /// expression. QualType getBaseType() const { return BaseType; } + + /// \brief Determines whether we want C++ constructors as results within this + /// context. + bool wantConstructorResults() const; }; @@ -339,127 +365,163 @@ public: Chunk() : Kind(CK_Text), Text(0) { } - Chunk(ChunkKind Kind, llvm::StringRef Text = ""); + Chunk(ChunkKind Kind, const char *Text = ""); /// \brief Create a new text chunk. - static Chunk CreateText(llvm::StringRef Text); + static Chunk CreateText(const char *Text); /// \brief Create a new optional chunk. - static Chunk CreateOptional(std::auto_ptr<CodeCompletionString> Optional); + static Chunk CreateOptional(CodeCompletionString *Optional); /// \brief Create a new placeholder chunk. - static Chunk CreatePlaceholder(llvm::StringRef Placeholder); + static Chunk CreatePlaceholder(const char *Placeholder); /// \brief Create a new informative chunk. - static Chunk CreateInformative(llvm::StringRef Informative); + static Chunk CreateInformative(const char *Informative); /// \brief Create a new result type chunk. - static Chunk CreateResultType(llvm::StringRef ResultType); + static Chunk CreateResultType(const char *ResultType); /// \brief Create a new current-parameter chunk. - static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter); - - /// \brief Clone the given chunk. - Chunk Clone() const; - - /// \brief Destroy this chunk, deallocating any memory it owns. - void Destroy(); + static Chunk CreateCurrentParameter(const char *CurrentParameter); }; private: - /// \brief The chunks stored in this string. - llvm::SmallVector<Chunk, 4> Chunks; + /// \brief The number of chunks stored in this string. + unsigned NumChunks; + + /// \brief The priority of this code-completion string. + unsigned Priority : 30; + + /// \brief The availability of this code-completion result. + unsigned Availability : 2; CodeCompletionString(const CodeCompletionString &); // DO NOT IMPLEMENT CodeCompletionString &operator=(const CodeCompletionString &); // DITTO -public: - CodeCompletionString() { } - ~CodeCompletionString() { clear(); } + CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, + unsigned Priority, CXAvailabilityKind Availability); + ~CodeCompletionString() { } - typedef llvm::SmallVector<Chunk, 4>::const_iterator iterator; - iterator begin() const { return Chunks.begin(); } - iterator end() const { return Chunks.end(); } - bool empty() const { return Chunks.empty(); } - unsigned size() const { return Chunks.size(); } - void clear(); + friend class CodeCompletionBuilder; + friend class CodeCompletionResult; - Chunk &operator[](unsigned I) { +public: + typedef const Chunk *iterator; + iterator begin() const { return reinterpret_cast<const Chunk *>(this + 1); } + iterator end() const { return begin() + NumChunks; } + bool empty() const { return NumChunks == 0; } + unsigned size() const { return NumChunks; } + + const Chunk &operator[](unsigned I) const { assert(I < size() && "Chunk index out-of-range"); - return Chunks[I]; + return begin()[I]; } + + /// \brief Returns the text in the TypedText chunk. + const char *getTypedText() const; - const Chunk &operator[](unsigned I) const { - assert(I < size() && "Chunk index out-of-range"); - return Chunks[I]; + /// \brief Retrieve the priority of this code completion result. + unsigned getPriority() const { return Priority; } + + /// \brief Reteirve the availability of this code completion result. + unsigned getAvailability() const { return Availability; } + + /// \brief Retrieve a string representation of the code completion string, + /// which is mainly useful for debugging. + std::string getAsString() const; +}; + +/// \brief An allocator used specifically for the purpose of code completion. +class CodeCompletionAllocator : public llvm::BumpPtrAllocator { +public: + /// \brief Copy the given string into this allocator. + const char *CopyString(llvm::StringRef String); + + /// \brief Copy the given string into this allocator. + const char *CopyString(llvm::Twine String); + + // \brief Copy the given string into this allocator. + const char *CopyString(const char *String) { + return CopyString(llvm::StringRef(String)); + } + + /// \brief Copy the given string into this allocator. + const char *CopyString(const std::string &String) { + return CopyString(llvm::StringRef(String)); + } +}; + +/// \brief A builder class used to construct new code-completion strings. +class CodeCompletionBuilder { +public: + typedef CodeCompletionString::Chunk Chunk; + +private: + CodeCompletionAllocator &Allocator; + unsigned Priority; + CXAvailabilityKind Availability; + + /// \brief The chunks stored in this string. + llvm::SmallVector<Chunk, 4> Chunks; + +public: + CodeCompletionBuilder(CodeCompletionAllocator &Allocator) + : Allocator(Allocator), Priority(0), Availability(CXAvailability_Available){ } + CodeCompletionBuilder(CodeCompletionAllocator &Allocator, + unsigned Priority, CXAvailabilityKind Availability) + : Allocator(Allocator), Priority(Priority), Availability(Availability) { } + + /// \brief Retrieve the allocator into which the code completion + /// strings should be allocated. + CodeCompletionAllocator &getAllocator() const { return Allocator; } + + /// \brief Take the resulting completion string. + /// + /// This operation can only be performed once. + CodeCompletionString *TakeString(); + /// \brief Add a new typed-text chunk. - /// The text string will be copied. - void AddTypedTextChunk(llvm::StringRef Text) { - Chunks.push_back(Chunk(CK_TypedText, Text)); + void AddTypedTextChunk(const char *Text) { + Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text)); } /// \brief Add a new text chunk. - /// The text string will be copied. - void AddTextChunk(llvm::StringRef Text) { + void AddTextChunk(const char *Text) { Chunks.push_back(Chunk::CreateText(Text)); } - + /// \brief Add a new optional chunk. - void AddOptionalChunk(std::auto_ptr<CodeCompletionString> Optional) { + void AddOptionalChunk(CodeCompletionString *Optional) { Chunks.push_back(Chunk::CreateOptional(Optional)); } /// \brief Add a new placeholder chunk. - /// The placeholder text will be copied. - void AddPlaceholderChunk(llvm::StringRef Placeholder) { + void AddPlaceholderChunk(const char *Placeholder) { Chunks.push_back(Chunk::CreatePlaceholder(Placeholder)); } - + /// \brief Add a new informative chunk. - /// The text will be copied. - void AddInformativeChunk(llvm::StringRef Text) { + void AddInformativeChunk(const char *Text) { Chunks.push_back(Chunk::CreateInformative(Text)); } - + /// \brief Add a new result-type chunk. - /// The text will be copied. - void AddResultTypeChunk(llvm::StringRef ResultType) { + void AddResultTypeChunk(const char *ResultType) { Chunks.push_back(Chunk::CreateResultType(ResultType)); } /// \brief Add a new current-parameter chunk. - /// The text will be copied. - void AddCurrentParameterChunk(llvm::StringRef CurrentParameter) { + void AddCurrentParameterChunk(const char *CurrentParameter) { Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter)); } /// \brief Add a new chunk. void AddChunk(Chunk C) { Chunks.push_back(C); } - - /// \brief Returns the text in the TypedText chunk. - const char *getTypedText() const; - - /// \brief Retrieve a string representation of the code completion string, - /// which is mainly useful for debugging. - std::string getAsString() const; - - /// \brief Clone this code-completion string. - /// - /// \param Result If non-NULL, points to an empty code-completion - /// result that will be given a cloned copy of - CodeCompletionString *Clone(CodeCompletionString *Result = 0) const; - - /// \brief Serialize this code-completion string to the given stream. - void Serialize(llvm::raw_ostream &OS) const; - - /// \brief Deserialize a code-completion string from the given string. - /// - /// \returns true if successful, false otherwise. - bool Deserialize(const char *&Str, const char *StrEnd); }; - + /// \brief Captures a result of code completion. class CodeCompletionResult { public: @@ -590,15 +652,12 @@ public: /// /// \param S The semantic analysis that created the result. /// - /// \param Result If non-NULL, the already-allocated, empty - /// code-completion string that will be populated with the - /// appropriate code completion string for this result. + /// \param Allocator The allocator that will be used to allocate the + /// string itself. CodeCompletionString *CreateCodeCompletionString(Sema &S, - CodeCompletionString *Result = 0); - - void Destroy(); + CodeCompletionAllocator &Allocator); - /// brief Determine a base priority for the given declaration. + /// \brief Determine a base priority for the given declaration. static unsigned getPriorityFromDecl(NamedDecl *ND); private: @@ -682,7 +741,7 @@ public: : Kind(CK_Function), Function(Function) { } OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl) - : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplate) { } + : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) { } OverloadCandidate(const FunctionType *Type) : Kind(CK_FunctionType), Type(Type) { } @@ -707,7 +766,8 @@ public: /// \brief Create a new code-completion string that describes the function /// signature of this overload candidate. CodeCompletionString *CreateSignatureString(unsigned CurrentArg, - Sema &S) const; + Sema &S, + CodeCompletionAllocator &Allocator) const; }; CodeCompleteConsumer() : IncludeMacros(false), IncludeCodePatterns(false), @@ -753,6 +813,10 @@ public: OverloadCandidate *Candidates, unsigned NumCandidates) { } //@} + + /// \brief Retrieve the allocator that will be used to allocate + /// code completion strings. + virtual CodeCompletionAllocator &getAllocator() = 0; }; /// \brief A simple code-completion consumer that prints the results it @@ -761,6 +825,8 @@ class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { /// \brief The raw output stream. llvm::raw_ostream &OS; + CodeCompletionAllocator Allocator; + public: /// \brief Create a new printing code-completion consumer that prints its /// results to the given raw output stream. @@ -779,34 +845,10 @@ public: virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, OverloadCandidate *Candidates, unsigned NumCandidates); -}; - -/// \brief A code-completion consumer that prints the results it receives -/// in a format that is parsable by the CIndex library. -class CIndexCodeCompleteConsumer : public CodeCompleteConsumer { - /// \brief The raw output stream. - llvm::raw_ostream &OS; - -public: - /// \brief Create a new CIndex code-completion consumer that prints its - /// results to the given raw output stream in a format readable to the CIndex - /// library. - CIndexCodeCompleteConsumer(bool IncludeMacros, bool IncludeCodePatterns, - bool IncludeGlobals, llvm::raw_ostream &OS) - : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, - true), OS(OS) {} - /// \brief Prints the finalized code-completion results. - virtual void ProcessCodeCompleteResults(Sema &S, - CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults); - - virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, - OverloadCandidate *Candidates, - unsigned NumCandidates); + virtual CodeCompletionAllocator &getAllocator() { return Allocator; } }; - + } // end namespace clang #endif // LLVM_CLANG_SEMA_CODECOMPLETECONSUMER_H diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 0893ae7..9c4bb64 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -26,6 +26,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { class LangOptions; @@ -169,32 +170,32 @@ private: // storage-class-specifier /*SCS*/unsigned StorageClassSpec : 3; - bool SCS_thread_specified : 1; - bool SCS_extern_in_linkage_spec : 1; + unsigned SCS_thread_specified : 1; + unsigned SCS_extern_in_linkage_spec : 1; // type-specifier /*TSW*/unsigned TypeSpecWidth : 2; /*TSC*/unsigned TypeSpecComplex : 2; /*TSS*/unsigned TypeSpecSign : 2; /*TST*/unsigned TypeSpecType : 5; - bool TypeAltiVecVector : 1; - bool TypeAltiVecPixel : 1; - bool TypeAltiVecBool : 1; - bool TypeSpecOwned : 1; + unsigned TypeAltiVecVector : 1; + unsigned TypeAltiVecPixel : 1; + unsigned TypeAltiVecBool : 1; + unsigned TypeSpecOwned : 1; // type-qualifiers unsigned TypeQualifiers : 3; // Bitwise OR of TQ. // function-specifier - bool FS_inline_specified : 1; - bool FS_virtual_specified : 1; - bool FS_explicit_specified : 1; + unsigned FS_inline_specified : 1; + unsigned FS_virtual_specified : 1; + unsigned FS_explicit_specified : 1; // friend-specifier - bool Friend_specified : 1; + unsigned Friend_specified : 1; // constexpr-specifier - bool Constexpr_specified : 1; + unsigned Constexpr_specified : 1; /*SCS*/unsigned StorageClassSpecAsWritten : 3; @@ -205,7 +206,7 @@ private: }; // attributes. - AttributeList *AttrList; + ParsedAttributes Attrs; // Scope specifier for the type spec, if applicable. CXXScopeSpec TypeScope; @@ -267,14 +268,12 @@ public: Friend_specified(false), Constexpr_specified(false), StorageClassSpecAsWritten(SCS_unspecified), - AttrList(0), ProtocolQualifiers(0), NumProtocolQualifiers(0), ProtocolLocs(0), writtenBS() { } ~DeclSpec() { - delete AttrList; delete [] ProtocolQualifiers; delete [] ProtocolLocs; } @@ -404,7 +403,7 @@ public: /// TODO: use a more general approach that still allows these /// diagnostics to be ignored when desired. bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); + unsigned &DiagID, const LangOptions &Lang); bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec, @@ -473,19 +472,29 @@ public: /// short __attribute__((unused)) __attribute__((deprecated)) /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; /// - void AddAttributes(AttributeList *alist) { - AttrList = addAttributeLists(AttrList, alist); + void addAttributes(AttributeList *AL) { + Attrs.append(AL); + } + void aetAttributes(AttributeList *AL) { + Attrs.set(AL); } - void SetAttributes(AttributeList *AL) { AttrList = AL; } - const AttributeList *getAttributes() const { return AttrList; } - AttributeList *getAttributes() { return AttrList; } + + bool hasAttributes() const { return !Attrs.empty(); } + + ParsedAttributes &getAttributes() { return Attrs; } + const ParsedAttributes &getAttributes() const { return Attrs; } /// TakeAttributes - Return the current attribute list and remove them from /// the DeclSpec so that it doesn't own them. - AttributeList *TakeAttributes() { - AttributeList *AL = AttrList; - AttrList = 0; - return AL; + ParsedAttributes takeAttributes() { + ParsedAttributes saved = Attrs; + Attrs.clear(); + return saved; + } + + void takeAttributesFrom(ParsedAttributes &attrs) { + Attrs.append(attrs.getList()); + attrs.clear(); } typedef Decl * const *ProtocolQualifierListTy; @@ -539,7 +548,8 @@ public: DQ_PR_retain = 0x10, DQ_PR_copy = 0x20, DQ_PR_nonatomic = 0x40, - DQ_PR_setter = 0x80 + DQ_PR_setter = 0x80, + DQ_PR_atomic = 0x100 }; @@ -573,7 +583,7 @@ private: ObjCDeclQualifier objcDeclQualifier : 6; // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind - unsigned PropertyAttributes : 8; + unsigned PropertyAttributes : 9; IdentifierInfo *GetterName; // getter name of NULL if no getter IdentifierInfo *SetterName; // setter name of NULL if no setter }; @@ -800,7 +810,7 @@ typedef llvm::SmallVector<Token, 4> CachedTokens; /// This is intended to be a small value object. struct DeclaratorChunk { enum { - Pointer, Reference, Array, Function, BlockPointer, MemberPointer + Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren } Kind; /// Loc - The place where this type was defined. @@ -808,27 +818,27 @@ struct DeclaratorChunk { /// EndLoc - If valid, the place where this chunck ends. SourceLocation EndLoc; - struct PointerTypeInfo { + struct TypeInfoCommon { + AttributeList *AttrList; + }; + + struct PointerTypeInfo : TypeInfoCommon { /// The type qualifiers: const/volatile/restrict. unsigned TypeQuals : 3; - AttributeList *AttrList; void destroy() { - delete AttrList; } }; - struct ReferenceTypeInfo { + struct ReferenceTypeInfo : TypeInfoCommon { /// The type qualifier: restrict. [GNU] C++ extension bool HasRestrict : 1; /// True if this is an lvalue reference, false if it's an rvalue reference. bool LValueRef : 1; - AttributeList *AttrList; void destroy() { - delete AttrList; } }; - struct ArrayTypeInfo { + struct ArrayTypeInfo : TypeInfoCommon { /// The type qualifiers for the array: const/volatile/restrict. unsigned TypeQuals : 3; @@ -842,6 +852,7 @@ struct DeclaratorChunk { /// Since the parser is multi-purpose, and we don't want to impose a root /// expression class on all clients, NumElts is untyped. Expr *NumElts; + void destroy() {} }; @@ -876,29 +887,33 @@ struct DeclaratorChunk { SourceRange Range; }; - struct FunctionTypeInfo { + struct FunctionTypeInfo : TypeInfoCommon { /// hasPrototype - This is true if the function had at least one typed /// argument. If the function is () or (a,b,c), then it has no prototype, /// and is treated as a K&R-style function. - bool hasPrototype : 1; + unsigned hasPrototype : 1; /// isVariadic - If this function has a prototype, and if that /// proto ends with ',...)', this is true. When true, EllipsisLoc /// contains the location of the ellipsis. - bool isVariadic : 1; + unsigned isVariadic : 1; + /// \brief Whether the ref-qualifier (if any) is an lvalue reference. + /// Otherwise, it's an rvalue reference. + unsigned RefQualifierIsLValueRef : 1; + /// The type qualifiers: const/volatile/restrict. /// The qualifier bitmask values are the same as in QualType. unsigned TypeQuals : 3; /// hasExceptionSpec - True if the function has an exception specification. - bool hasExceptionSpec : 1; + unsigned hasExceptionSpec : 1; /// hasAnyExceptionSpec - True if the function has a throw(...) specifier. - bool hasAnyExceptionSpec : 1; + unsigned hasAnyExceptionSpec : 1; /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo. - bool DeleteArgInfo : 1; + unsigned DeleteArgInfo : 1; /// When isVariadic is true, the location of the ellipsis in the source. unsigned EllipsisLoc; @@ -911,6 +926,11 @@ struct DeclaratorChunk { /// the function has one. unsigned NumExceptions; + /// \brief The location of the ref-qualifier, if any. + /// + /// If this is an invalid location, there is no ref-qualifier. + unsigned RefQualifierLoc; + /// ThrowLoc - When hasExceptionSpec is true, the location of the throw /// keyword introducing the spec. unsigned ThrowLoc; @@ -925,6 +945,11 @@ struct DeclaratorChunk { /// specification and their locations. TypeAndRange *Exceptions; + /// 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; + /// freeArgs - reset the argument list to having zero arguments. This is /// used in various places for error recovery. void freeArgs() { @@ -954,22 +979,29 @@ struct DeclaratorChunk { SourceLocation getThrowLoc() const { return SourceLocation::getFromRawEncoding(ThrowLoc); } + + /// \brief Retrieve the location of the ref-qualifier, if any. + SourceLocation getRefQualifierLoc() const { + return SourceLocation::getFromRawEncoding(RefQualifierLoc); + } + + /// \brief Determine whether this function declaration contains a + /// ref-qualifier. + bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } }; - struct BlockPointerTypeInfo { + struct BlockPointerTypeInfo : TypeInfoCommon { /// For now, sema will catch these as invalid. /// The type qualifiers: const/volatile/restrict. unsigned TypeQuals : 3; - AttributeList *AttrList; + void destroy() { - delete AttrList; } }; - struct MemberPointerTypeInfo { + struct MemberPointerTypeInfo : TypeInfoCommon { /// The type qualifiers: const/volatile/restrict. unsigned TypeQuals : 3; - AttributeList *AttrList; // CXXScopeSpec has a constructor, so it can't be a direct member. // So we need some pointer-aligned storage and a bit of trickery. union { @@ -983,12 +1015,12 @@ struct DeclaratorChunk { return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem); } void destroy() { - delete AttrList; Scope().~CXXScopeSpec(); } }; union { + TypeInfoCommon Common; PointerTypeInfo Ptr; ReferenceTypeInfo Ref; ArrayTypeInfo Arr; @@ -1006,58 +1038,57 @@ struct DeclaratorChunk { case DeclaratorChunk::Reference: return Ref.destroy(); case DeclaratorChunk::Array: return Arr.destroy(); case DeclaratorChunk::MemberPointer: return Mem.destroy(); + case DeclaratorChunk::Paren: return; } } /// getAttrs - If there are attributes applied to this declaratorchunk, return /// them. const AttributeList *getAttrs() const { - switch (Kind) { - default: assert(0 && "Unknown declarator kind!"); - case Pointer: return Ptr.AttrList; - case Reference: return Ref.AttrList; - case MemberPointer: return Mem.AttrList; - case Array: return 0; - case Function: return 0; - case BlockPointer: return Cls.AttrList; - } + return Common.AttrList; } + AttributeList *&getAttrListRef() { + return Common.AttrList; + } /// getPointer - Return a DeclaratorChunk for a pointer. /// static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, - AttributeList *AL) { + const ParsedAttributes &attrs) { DeclaratorChunk I; I.Kind = Pointer; I.Loc = Loc; I.Ptr.TypeQuals = TypeQuals; - I.Ptr.AttrList = AL; + I.Ptr.AttrList = attrs.getList(); return I; } /// getReference - Return a DeclaratorChunk for a reference. /// static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, - AttributeList *AL, bool lvalue) { + const ParsedAttributes &attrs, + bool lvalue) { DeclaratorChunk I; I.Kind = Reference; I.Loc = Loc; I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0; I.Ref.LValueRef = lvalue; - I.Ref.AttrList = AL; + I.Ref.AttrList = attrs.getList(); return I; } /// getArray - Return a DeclaratorChunk for an array. /// - static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, - bool isStar, Expr *NumElts, + static DeclaratorChunk getArray(unsigned TypeQuals, + const ParsedAttributes &attrs, + bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc) { DeclaratorChunk I; I.Kind = Array; I.Loc = LBLoc; I.EndLoc = RBLoc; + I.Arr.AttrList = attrs.getList(); I.Arr.TypeQuals = TypeQuals; I.Arr.hasStatic = isStatic; I.Arr.isStar = isStar; @@ -1067,42 +1098,60 @@ 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, + static DeclaratorChunk getFunction(const ParsedAttributes &attrs, + bool hasProto, bool isVariadic, SourceLocation EllipsisLoc, ParamInfo *ArgInfo, unsigned NumArgs, - unsigned TypeQuals, bool hasExceptionSpec, + unsigned TypeQuals, + bool RefQualifierIsLvalueRef, + SourceLocation RefQualifierLoc, + bool hasExceptionSpec, SourceLocation ThrowLoc, bool hasAnyExceptionSpec, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, SourceLocation LPLoc, SourceLocation RPLoc, - Declarator &TheDeclarator); + Declarator &TheDeclarator, + ParsedType TrailingReturnType = ParsedType()); /// getBlockPointer - Return a DeclaratorChunk for a block. /// static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc, - AttributeList *AL) { + const ParsedAttributes &attrs) { DeclaratorChunk I; I.Kind = BlockPointer; I.Loc = Loc; I.Cls.TypeQuals = TypeQuals; - I.Cls.AttrList = AL; + I.Cls.AttrList = attrs.getList(); return I; } static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation Loc, - AttributeList *AL) { + const ParsedAttributes &attrs) { DeclaratorChunk I; I.Kind = MemberPointer; I.Loc = Loc; I.Mem.TypeQuals = TypeQuals; - I.Mem.AttrList = AL; + I.Mem.AttrList = attrs.getList(); new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS); return I; } + + /// getParen - Return a DeclaratorChunk for a paren. + /// + static DeclaratorChunk getParen(SourceLocation LParenLoc, + SourceLocation RParenLoc) { + DeclaratorChunk I; + I.Kind = Paren; + I.Loc = LParenLoc; + I.EndLoc = RParenLoc; + I.Common.AttrList = 0; + return I; + } + }; /// Declarator - Information about one declarator, including the parsed type @@ -1128,7 +1177,8 @@ public: ConditionContext, // Condition declaration in a C++ if/switch/while/for. TemplateParamContext,// Within a template parameter list. CXXCatchContext, // C++ catch exception-declaration - BlockLiteralContext // Block literal declarator. + BlockLiteralContext, // Block literal declarator. + TemplateTypeArgContext // Template type argument. }; private: @@ -1168,6 +1218,10 @@ private: /// Extension - true if the declaration is preceded by __extension__. bool Extension : 1; + /// \brief If provided, the source location of the ellipsis used to describe + /// this declarator as a parameter pack. + SourceLocation EllipsisLoc; + friend struct DeclaratorChunk; public: @@ -1238,7 +1292,6 @@ public: for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) DeclTypeInfo[i].destroy(); DeclTypeInfo.clear(); - delete AttrList; AttrList = 0; AsmLabel = 0; InlineParamsUsed = false; @@ -1250,14 +1303,15 @@ public: bool mayOmitIdentifier() const { return Context == TypeNameContext || Context == PrototypeContext || Context == TemplateParamContext || Context == CXXCatchContext || - Context == BlockLiteralContext; + Context == BlockLiteralContext || Context == TemplateTypeArgContext; } /// mayHaveIdentifier - Return true if the identifier is either optional or /// required. This is true for normal declarators and prototypes, but not /// typenames. bool mayHaveIdentifier() const { - return Context != TypeNameContext && Context != BlockLiteralContext; + return Context != TypeNameContext && Context != BlockLiteralContext && + Context != TemplateTypeArgContext; } /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be @@ -1301,6 +1355,11 @@ public: SetRangeEnd(EndLoc); } + /// AddInnermostTypeInfo - 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. unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); } @@ -1323,11 +1382,52 @@ public: DeclTypeInfo.erase(DeclTypeInfo.begin()); } + /// isFunctionDeclarator - This method returns true if the declarator + /// is a function declarator (looking through parentheses). + /// If true is returned, then the reference type parameter idx is + /// assigned with the index of the declaration chunk. + bool isFunctionDeclarator(unsigned& idx) const { + for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { + switch (DeclTypeInfo[i].Kind) { + case DeclaratorChunk::Function: + idx = i; + return true; + case DeclaratorChunk::Paren: + continue; + case DeclaratorChunk::Pointer: + case DeclaratorChunk::Reference: + case DeclaratorChunk::Array: + case DeclaratorChunk::BlockPointer: + case DeclaratorChunk::MemberPointer: + return false; + } + llvm_unreachable("Invalid type chunk"); + return false; + } + return false; + } + /// isFunctionDeclarator - Once this declarator is fully parsed and formed, - /// this method returns true if the identifier is a function declarator. + /// this method returns true if the identifier is a function declarator + /// (looking through parentheses). bool isFunctionDeclarator() const { - return !DeclTypeInfo.empty() && - DeclTypeInfo[0].Kind == DeclaratorChunk::Function; + unsigned index; + return isFunctionDeclarator(index); + } + + /// getFunctionTypeInfo - Retrieves the function type info object + /// (looking through parentheses). + DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() { + assert(isFunctionDeclarator() && "Not a function declarator!"); + unsigned index = 0; + isFunctionDeclarator(index); + return DeclTypeInfo[index].Fun; + } + + /// getFunctionTypeInfo - Retrieves the function type info object + /// (looking through parentheses). + const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const { + return const_cast<Declarator*>(this)->getFunctionTypeInfo(); } /// AddAttributes - simply adds the attribute list to the Declarator. @@ -1337,19 +1437,25 @@ public: /// __attribute__((common,deprecated)); /// /// Also extends the range of the declarator. - void AddAttributes(AttributeList *alist, SourceLocation LastLoc) { + void addAttributes(AttributeList *alist, SourceLocation LastLoc) { AttrList = addAttributeLists(AttrList, alist); if (!LastLoc.isInvalid()) SetRangeEnd(LastLoc); } + void addAttributes(const ParsedAttributes &attrs) { + addAttributes(attrs.getList(), SourceLocation()); + } + const AttributeList *getAttributes() const { return AttrList; } AttributeList *getAttributes() { return AttrList; } + AttributeList *&getAttrListRef() { return AttrList; } + /// hasAttributes - do we contain any attributes? bool hasAttributes() const { - if (getAttributes() || getDeclSpec().getAttributes()) return true; + if (getAttributes() || getDeclSpec().hasAttributes()) return true; for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i) if (getTypeObject(i).getAttrs()) return true; @@ -1369,6 +1475,10 @@ public: void setGroupingParens(bool flag) { GroupingParens = flag; } bool hasGroupingParens() const { return GroupingParens; } + + bool hasEllipsis() const { return EllipsisLoc.isValid(); } + SourceLocation getEllipsisLoc() const { return EllipsisLoc; } + void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; } }; /// FieldDeclarator - This little struct is used to capture information about @@ -1380,7 +1490,69 @@ struct FieldDeclarator { BitfieldSize = 0; } }; - + +/// VirtSpecifiers - Represents a C++0x virt-specifier-seq. +class VirtSpecifiers { +public: + enum Specifier { + VS_None = 0, + VS_Override = 1, + VS_Final = 2, + VS_New = 4 + }; + + VirtSpecifiers() : Specifiers(0) { } + + bool SetSpecifier(Specifier VS, SourceLocation Loc, + const char *&PrevSpec); + + bool isOverrideSpecified() const { return Specifiers & VS_Override; } + SourceLocation getOverrideLoc() const { return VS_overrideLoc; } + + bool isFinalSpecified() const { return Specifiers & VS_Final; } + SourceLocation getFinalLoc() const { return VS_finalLoc; } + + bool isNewSpecified() const { return Specifiers & VS_New; } + SourceLocation getNewLoc() const { return VS_newLoc; } + + void clear() { Specifiers = 0; } + + static const char *getSpecifierName(Specifier VS); + +private: + unsigned Specifiers; + + SourceLocation VS_overrideLoc, VS_finalLoc, VS_newLoc; +}; + +/// ClassVirtSpecifiers - Represents a C++0x class-virt-specifier-seq. +class ClassVirtSpecifiers { +public: + enum Specifier { + CVS_None = 0, + CVS_Final = 1, + CVS_Explicit = 2 + }; + + ClassVirtSpecifiers() : Specifiers(0) { } + + bool SetSpecifier(Specifier CVS, SourceLocation Loc, + const char *&PrevSpec); + + bool isFinalSpecified() const { return Specifiers & CVS_Final; } + SourceLocation getFinalLoc() const { return CVS_finalLoc; } + + bool isExplicitSpecified() const { return Specifiers & CVS_Explicit; } + SourceLocation getExplicitLoc() const { return CVS_explicitLoc; } + + static const char *getSpecifierName(Specifier CVS); + +private: + unsigned Specifiers; + + SourceLocation CVS_finalLoc, CVS_explicitLoc; +}; + } // end namespace clang #endif diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 6a9a1bf..6e808de 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -101,7 +101,7 @@ public: private: unsigned Access : 2; - bool IsMember; + unsigned IsMember : 1; NamedDecl *Target; CXXRecordDecl *NamingClass; QualType BaseObjectType; @@ -119,14 +119,6 @@ public: SourceLocation Loc; - union { - /// Deprecation. - struct { NamedDecl *Decl; } DeprecationData; - - /// Access control. - char AccessData[sizeof(AccessedEntity)]; - }; - void destroy() { switch (Kind) { case Access: getAccessData().~AccessedEntity(); break; @@ -135,12 +127,15 @@ public: } static DelayedDiagnostic makeDeprecation(SourceLocation Loc, - NamedDecl *D) { + const NamedDecl *D, + llvm::StringRef Msg) { DelayedDiagnostic DD; DD.Kind = Deprecation; DD.Triggered = false; DD.Loc = Loc; DD.DeprecationData.Decl = D; + DD.DeprecationData.Message = Msg.data(); + DD.DeprecationData.MessageLen = Msg.size(); return DD; } @@ -155,11 +150,37 @@ public: } AccessedEntity &getAccessData() { + assert(Kind == Access && "Not an access diagnostic."); return *reinterpret_cast<AccessedEntity*>(AccessData); } const AccessedEntity &getAccessData() const { + assert(Kind == Access && "Not an access diagnostic."); return *reinterpret_cast<const AccessedEntity*>(AccessData); } + + const NamedDecl *getDeprecationDecl() const { + assert(Kind == Deprecation && "Not a deprecation diagnostic."); + return DeprecationData.Decl; + } + + llvm::StringRef getDeprecationMessage() const { + assert(Kind == Deprecation && "Not a deprecation diagnostic."); + return llvm::StringRef(DeprecationData.Message, + DeprecationData.MessageLen); + } + +private: + union { + /// Deprecation. + struct { + const NamedDecl *Decl; + const char *Message; + size_t MessageLen; + } DeprecationData; + + /// Access control. + char AccessData[sizeof(AccessedEntity)]; + }; }; } diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 7be0033..6d7bc63 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -14,10 +14,11 @@ #define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H #include "clang/AST/ExternalASTSource.h" -#include "clang/Sema/ObjCMethodList.h" +#include <utility> namespace clang { +struct ObjCMethodList; class Sema; /// \brief An abstract interface that should be implemented by @@ -44,10 +45,7 @@ public: /// /// \returns a pair of Objective-C methods lists containing the /// instance and factory methods, respectively, with this selector. - virtual std::pair<ObjCMethodList, ObjCMethodList> - ReadMethodPool(Selector Sel) { - return std::pair<ObjCMethodList, ObjCMethodList>(); - } + virtual std::pair<ObjCMethodList,ObjCMethodList> ReadMethodPool(Selector Sel); // isa/cast/dyn_cast support static bool classof(const ExternalASTSource *Source) { diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 0062b3a..c191565 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -88,6 +88,10 @@ private: /// the VarDecl, ParmVarDecl, or FieldDecl, respectively. DeclaratorDecl *VariableOrMember; + /// \brief When Kind == EK_Temporary, the type source information for + /// the temporary. + TypeSourceInfo *TypeInfo; + struct { /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the /// location of the 'return', 'throw', or 'new' keyword, @@ -114,12 +118,12 @@ private: /// \brief Create the initialization entity for a variable. InitializedEntity(VarDecl *Var) : Kind(EK_Variable), Parent(0), Type(Var->getType()), - VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Var)) { } + VariableOrMember(Var) { } /// \brief Create the initialization entity for a parameter. InitializedEntity(ParmVarDecl *Parm) : Kind(EK_Parameter), Parent(0), Type(Parm->getType().getUnqualifiedType()), - VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Parm)) { } + VariableOrMember(Parm) { } /// \brief Create the initialization entity for the result of a /// function, throwing an object, performing an explicit cast, or @@ -135,7 +139,7 @@ private: /// \brief Create the initialization entity for a member subobject. InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) : Kind(EK_Member), Parent(Parent), Type(Member->getType()), - VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Member)) { } + VariableOrMember(Member) { } /// \brief Create the initialization entity for an array element. InitializedEntity(ASTContext &Context, unsigned Index, @@ -148,16 +152,20 @@ public: } /// \brief Create the initialization entity for a parameter. - static InitializedEntity InitializeParameter(ParmVarDecl *Parm) { - return InitializedEntity(Parm); + static InitializedEntity InitializeParameter(ASTContext &Context, + ParmVarDecl *Parm) { + InitializedEntity Res(Parm); + Res.Type = Context.getVariableArrayDecayedType(Res.Type); + return Res; } /// \brief Create the initialization entity for a parameter that is /// only known by its type. - static InitializedEntity InitializeParameter(QualType Type) { + static InitializedEntity InitializeParameter(ASTContext &Context, + QualType Type) { InitializedEntity Entity; Entity.Kind = EK_Parameter; - Entity.Type = Type; + Entity.Type = Context.getVariableArrayDecayedType(Type); Entity.Parent = 0; Entity.VariableOrMember = 0; return Entity; @@ -189,7 +197,15 @@ public: static InitializedEntity InitializeTemporary(QualType Type) { return InitializedEntity(EK_Temporary, SourceLocation(), Type); } - + + /// \brief Create the initialization entity for a temporary. + static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) { + InitializedEntity Result(EK_Temporary, SourceLocation(), + TypeInfo->getType()); + Result.TypeInfo = TypeInfo; + return Result; + } + /// \brief Create the initialization entity for a base class subobject. static InitializedEntity InitializeBase(ASTContext &Context, CXXBaseSpecifier *Base, @@ -201,6 +217,12 @@ public: return InitializedEntity(Member, Parent); } + /// \brief Create the initialization entity for a member subobject. + static InitializedEntity InitializeMember(IndirectFieldDecl *Member, + const InitializedEntity *Parent = 0) { + return InitializedEntity(Member->getAnonField(), Parent); + } + /// \brief Create the initialization entity for an array element. static InitializedEntity InitializeElement(ASTContext &Context, unsigned Index, @@ -219,6 +241,15 @@ public: /// \brief Retrieve type being initialized. QualType getType() const { return Type; } + /// \brief Retrieve complete type-source information for the object being + /// constructed, if known. + TypeSourceInfo *getTypeSourceInfo() const { + if (Kind == EK_Temporary) + return TypeInfo; + + return 0; + } + /// \brief Retrieve the name of the entity being initialized. DeclarationName getName() const; @@ -760,12 +791,18 @@ public: return FailedCandidateSet; } + /// brief Get the overloading result, for when the initialization + /// sequence failed due to a bad overload. + OverloadingResult getFailedOverloadResult() const { + return FailedOverloadResult; + } + /// \brief Determine why initialization failed. FailureKind getFailureKind() const { assert(getKind() == FailedSequence && "Not an initialization failure!"); return Failure; } - + /// \brief Dump a representation of this initialization sequence to /// the given stream, for debugging purposes. void dump(llvm::raw_ostream &OS) const; diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 1c7720a..aa58d14 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -365,6 +365,11 @@ public: if (Decls.empty()) { if (ResultKind != NotFoundInCurrentInstantiation) ResultKind = NotFound; + + if (Paths) { + deletePaths(Paths); + Paths = 0; + } } else { AmbiguityKind SavedAK = Ambiguity; ResultKind = Found; @@ -492,25 +497,18 @@ public: LookupResult &Results; LookupResult::iterator I; bool Changed; -#ifndef NDEBUG bool CalledDone; -#endif friend class LookupResult; Filter(LookupResult &Results) - : Results(Results), I(Results.begin()), Changed(false) -#ifndef NDEBUG - , CalledDone(false) -#endif + : Results(Results), I(Results.begin()), Changed(false), CalledDone(false) {} public: -#ifndef NDEBUG ~Filter() { assert(CalledDone && "LookupResult::Filter destroyed without done() call"); } -#endif bool hasNext() const { return I != Results.end(); @@ -541,10 +539,8 @@ public: } void done() { -#ifndef NDEBUG assert(!CalledDone && "done() called twice"); CalledDone = true; -#endif if (Changed) Results.resolveKindAfterFilter(); @@ -573,11 +569,7 @@ private: void configure(); // Sanity checks. -#ifndef NDEBUG void sanity() const; -#else - void sanity() const {} -#endif bool sanityCheckUnresolved() const { for (iterator I = begin(), E = end(); I != E; ++I) diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 851d68a..3ce3513 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -75,6 +75,7 @@ namespace clang { ICK_Vector_Conversion, ///< Vector conversions ICK_Vector_Splat, ///< A vector splat from an arithmetic type ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7) + ICK_Block_Pointer_Conversion, ///< Block Pointer conversions ICK_Num_Conversion_Kinds ///< The number of conversion kinds }; @@ -130,27 +131,37 @@ namespace clang { /// Third - The third conversion can be a qualification conversion. ImplicitConversionKind Third : 8; - /// Deprecated - Whether this the deprecated conversion of a + /// \brief Whether this is the deprecated conversion of a /// string literal to a pointer to non-const character data /// (C++ 4.2p2). - bool DeprecatedStringLiteralToCharPtr : 1; + unsigned DeprecatedStringLiteralToCharPtr : 1; /// IncompatibleObjC - Whether this is an Objective-C conversion /// that we should warn about (if we actually use it). - bool IncompatibleObjC : 1; + unsigned IncompatibleObjC : 1; /// ReferenceBinding - True when this is a reference binding /// (C++ [over.ics.ref]). - bool ReferenceBinding : 1; + unsigned ReferenceBinding : 1; /// DirectBinding - True when this is a reference binding that is a /// direct binding (C++ [dcl.init.ref]). - bool DirectBinding : 1; - - /// RRefBinding - True when this is a reference binding of an rvalue - /// reference to an rvalue (C++0x [over.ics.rank]p3b4). - bool RRefBinding : 1; + unsigned DirectBinding : 1; + /// \brief Whether this is an lvalue reference binding (otherwise, it's + /// an rvalue reference binding). + unsigned IsLvalueReference : 1; + + /// \brief Whether we're binding to a function lvalue. + unsigned BindsToFunctionLvalue : 1; + + /// \brief Whether we're binding to an rvalue. + unsigned BindsToRvalue : 1; + + /// \brief Whether this binds an implicit object argument to a + /// non-static member function without a ref-qualifier. + unsigned BindsImplicitObjectArgumentWithoutRefQualifier : 1; + /// FromType - The type that this conversion is converting /// from. This is an opaque pointer that can be translated into a /// QualType. @@ -231,6 +242,11 @@ namespace clang { /// user-defined conversion. FunctionDecl* ConversionFunction; + /// \brief The declaration that we found via name lookup, which might be + /// the same as \c ConversionFunction or it might be a using declaration + /// that refers to \c ConversionFunction. + NamedDecl *FoundConversionFunction; + void DebugPrint() const; }; @@ -283,7 +299,9 @@ namespace clang { no_conversion, unrelated_class, suppressed_user, - bad_qualifiers + bad_qualifiers, + lvalue_ref_to_rvalue, + rvalue_ref_to_lvalue }; // This can be null, e.g. for implicit object arguments. @@ -549,6 +567,10 @@ namespace clang { /// Actually an OverloadFailureKind. unsigned char FailureKind; + /// \brief The number of call arguments that were explicitly provided, + /// to be used while performing partial ordering of function templates. + unsigned ExplicitCallArguments; + /// A structure used to record information about a failed /// template argument deduction. struct DeductionFailureInfo { @@ -630,7 +652,8 @@ namespace clang { /// Find the best viable function on this overload set, if it exists. OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, - OverloadCandidateSet::iterator& Best); + OverloadCandidateSet::iterator& Best, + bool UserDefinedConversion = false); void NoteCandidates(Sema &S, OverloadCandidateDisplayKind OCD, @@ -642,7 +665,8 @@ namespace clang { bool isBetterOverloadCandidate(Sema &S, const OverloadCandidate& Cand1, const OverloadCandidate& Cand2, - SourceLocation Loc); + SourceLocation Loc, + bool UserDefinedConversion = false); } // end namespace clang #endif // LLVM_CLANG_SEMA_OVERLOAD_H diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index 7739f3a..5f2f0eb 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -23,7 +23,7 @@ namespace clang { class Attr; - class CXXBaseOrMemberInitializer; + class CXXCtorInitializer; class CXXBaseSpecifier; class Decl; class DeclGroupRef; @@ -106,6 +106,9 @@ namespace llvm { } enum { NumLowBitsAvailable = 0 }; }; + + template <class T> + struct isPodLike<clang::OpaquePtr<T> > { static const bool value = true; }; } @@ -414,7 +417,7 @@ namespace clang { template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> { static const bool value = true; }; - template<> struct IsResultPtrLowBitFree<CXXBaseOrMemberInitializer*> { + template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> { static const bool value = true; }; @@ -427,7 +430,7 @@ namespace clang { typedef ActionResult<Stmt*> StmtResult; typedef ActionResult<ParsedType> TypeResult; typedef ActionResult<CXXBaseSpecifier*> BaseResult; - typedef ActionResult<CXXBaseOrMemberInitializer*> MemInitResult; + typedef ActionResult<CXXCtorInitializer*> MemInitResult; typedef ActionResult<Decl*> DeclResult; typedef OpaquePtr<TemplateName> ParsedTemplateTy; diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index da68a49..5aa6f47 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -32,7 +32,9 @@ namespace clang { Template }; - /// \brief Build an empty template argument. This template argument + /// \brief Build an empty template argument. + /// + /// This template argument is invalid. ParsedTemplateArgument() : Kind(Type), Arg(0) { } /// \brief Create a template type argument or non-type template argument. @@ -56,7 +58,7 @@ namespace clang { SourceLocation TemplateLoc) : Kind(ParsedTemplateArgument::Template), Arg(Template.getAsOpaquePtr()), - Loc(TemplateLoc), SS(SS) { } + Loc(TemplateLoc), SS(SS), EllipsisLoc() { } /// \brief Determine whether the given template argument is invalid. bool isInvalid() const { return Arg == 0; } @@ -93,6 +95,21 @@ namespace clang { return SS; } + /// \brief Retrieve the location of the ellipsis that makes a template + /// template argument into a pack expansion. + SourceLocation getEllipsisLoc() const { + assert(Kind == Template && + "Only template template arguments can have an ellipsis"); + return EllipsisLoc; + } + + /// \brief Retrieve a pack expansion of the given template template + /// argument. + /// + /// \param EllipsisLoc The location of the ellipsis. + ParsedTemplateArgument getTemplatePackExpansion( + SourceLocation EllipsisLoc) const; + private: KindType Kind; @@ -107,6 +124,10 @@ namespace clang { /// \brief The nested-name-specifier that can accompany a template template /// argument. CXXScopeSpec SS; + + /// \brief The ellipsis location that can accompany a template template + /// argument (turning it into a template template argument expansion). + SourceLocation EllipsisLoc; }; /// \brief Information about a template-id annotation @@ -161,7 +182,10 @@ namespace clang { void Destroy() { free(this); } }; - + + /// Retrieves the range of the given template parameter lists. + SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, + unsigned NumParams); inline const ParsedTemplateArgument & ASTTemplateArgsPtr::operator[](unsigned Arg) const { diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 4229c6c..d7fda35 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_SCOPE_H #define LLVM_CLANG_SEMA_SCOPE_H +#include "clang/Basic/Diagnostic.h" #include "llvm/ADT/SmallPtrSet.h" namespace clang { @@ -52,7 +53,7 @@ public: /// ClassScope - The scope of a struct/union/class definition. ClassScope = 0x20, - /// BlockScope - This is a scope that corresponds to a block object. + /// BlockScope - This is a scope that corresponds to a block/closure object. /// Blocks serve as top-level scopes for some objects like labels, they /// also prevent things like break and continue. BlockScopes always have /// the FnScope, BreakScope, ContinueScope, and DeclScope flags set as well. @@ -131,11 +132,12 @@ private: typedef llvm::SmallVector<UsingDirectiveDecl *, 2> UsingDirectivesTy; UsingDirectivesTy UsingDirectives; - /// \brief The number of errors at the start of the given scope. - unsigned NumErrorsAtStart; + /// \brief Used to determine if errors occurred in this scope. + DiagnosticErrorTrap ErrorTrap; public: - Scope(Scope *Parent, unsigned ScopeFlags) { + Scope(Scope *Parent, unsigned ScopeFlags, Diagnostic &Diag) + : ErrorTrap(Diag) { Init(Parent, ScopeFlags); } @@ -144,8 +146,7 @@ public: unsigned getFlags() const { return Flags; } void setFlags(unsigned F) { Flags = F; } - /// isBlockScope - Return true if this scope does not correspond to a - /// closure. + /// isBlockScope - Return true if this scope correspond to a closure. bool isBlockScope() const { return Flags & BlockScope; } /// getParent - Return the scope that this is nested in. @@ -214,13 +215,7 @@ public: void* getEntity() const { return Entity; } void setEntity(void *E) { Entity = E; } - /// \brief Retrieve the number of errors that had been emitted when we - /// entered this scope. - unsigned getNumErrorsAtStart() const { return NumErrorsAtStart; } - - void setNumErrorsAtStart(unsigned NumErrors) { - NumErrorsAtStart = NumErrors; - } + bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); } /// isClassScope - Return true if this scope is a class/struct/union scope. bool isClassScope() const { @@ -318,7 +313,7 @@ public: DeclsInScope.clear(); UsingDirectives.clear(); Entity = 0; - NumErrorsAtStart = 0; + ErrorTrap.reset(); } }; diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 50cfa9b..b0bb955 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -17,12 +17,13 @@ #include "clang/AST/Type.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SetVector.h" namespace clang { class BlockDecl; class IdentifierInfo; -class LabelStmt; +class LabelDecl; class ReturnStmt; class Scope; class SwitchStmt; @@ -48,14 +49,8 @@ public: /// \brief Whether this function contains any indirect gotos. bool HasIndirectGoto; - /// \brief The number of errors that had occurred before starting this - /// function or block. - unsigned NumErrorsAtStartOfFunction; - - /// LabelMap - This is a mapping from label identifiers to the LabelStmt for - /// it (which acts like the label decl in some ways). Forward referenced - /// labels have a LabelStmt created for them with a null location & SubStmt. - llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap; + /// \brief Used to determine if errors occurred in this function or block. + DiagnosticErrorTrap ErrorTrap; /// SwitchStack - This is the current set of active switch statements in the /// block. @@ -64,7 +59,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. - llvm::SmallVector<ReturnStmt *, 4> Returns; + llvm::SmallVector<ReturnStmt*, 4> Returns; void setHasBranchIntoScope() { HasBranchIntoScope = true; @@ -83,18 +78,18 @@ public: (HasBranchProtectedScope && HasBranchIntoScope); } - FunctionScopeInfo(unsigned NumErrors) + FunctionScopeInfo(Diagnostic &Diag) : IsBlockInfo(false), HasBranchProtectedScope(false), HasBranchIntoScope(false), HasIndirectGoto(false), - NumErrorsAtStartOfFunction(NumErrors) { } + ErrorTrap(Diag) { } virtual ~FunctionScopeInfo(); /// \brief Clear out the information in this function scope, making it /// suitable for reuse. - void Clear(unsigned NumErrors); + void Clear(); static bool classof(const FunctionScopeInfo *FSI) { return true; } }; @@ -102,8 +97,6 @@ public: /// \brief Retains information about a block that is currently being parsed. class BlockScopeInfo : public FunctionScopeInfo { public: - bool hasBlockDeclRefExprs; - BlockDecl *TheDecl; /// TheScope - This is the scope for the block itself, which contains @@ -118,9 +111,18 @@ public: /// Its return type may be BuiltinType::Dependent. QualType FunctionType; - BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block) - : FunctionScopeInfo(NumErrors), hasBlockDeclRefExprs(false), - TheDecl(Block), TheScope(BlockScope) + /// CaptureMap - A map of captured variables to (index+1) into Captures. + llvm::DenseMap<VarDecl*, unsigned> CaptureMap; + + /// Captures - The captured variables. + llvm::SmallVector<BlockDecl::Capture, 4> Captures; + + /// CapturesCXXThis - Whether this block captures 'this'. + bool CapturesCXXThis; + + BlockScopeInfo(Diagnostic &Diag, Scope *BlockScope, BlockDecl *Block) + : FunctionScopeInfo(Diag), TheDecl(Block), TheScope(BlockScope), + CapturesCXXThis(false) { IsBlockInfo = true; } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 4741028..91d6914 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -20,9 +20,10 @@ #include "clang/Sema/IdentifierResolver.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/DeclSpec.h" -#include "clang/AST/OperationKinds.h" +#include "clang/AST/Expr.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" @@ -62,6 +63,7 @@ namespace clang { class ClassTemplatePartialSpecializationDecl; class ClassTemplateSpecializationDecl; class CodeCompleteConsumer; + class CodeCompletionAllocator; class CodeCompletionResult; class Decl; class DeclAccessPair; @@ -78,7 +80,6 @@ namespace clang { class ExternalSemaSource; class FormatAttr; class FriendDecl; - class FullExpr; class FunctionDecl; class FunctionProtoType; class FunctionTemplateDecl; @@ -121,7 +122,6 @@ namespace clang { class TargetAttributesSema; class TemplateArgument; class TemplateArgumentList; - class TemplateArgumentListBuilder; class TemplateArgumentLoc; class TemplateDecl; class TemplateParameterList; @@ -129,6 +129,7 @@ namespace clang { class TemplateTemplateParmDecl; class Token; class TypedefDecl; + class TypeLoc; class UnqualifiedId; class UnresolvedLookupExpr; class UnresolvedMemberExpr; @@ -140,7 +141,8 @@ namespace clang { class VarDecl; class VisibilityAttr; class VisibleDeclConsumer; - + class IndirectFieldDecl; + namespace sema { class AccessedEntity; class BlockScopeInfo; @@ -165,7 +167,10 @@ class LocInfoType : public Type { TypeSourceInfo *DeclInfo; LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType()), DeclInfo(TInfo) { + : Type((TypeClass)LocInfo, ty, ty->isDependentType(), + ty->isVariablyModifiedType(), + ty->containsUnexpandedParameterPack()), + DeclInfo(TInfo) { assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); } friend class Sema; @@ -183,6 +188,11 @@ public: static bool classof(const LocInfoType *) { return true; } }; +// FIXME: No way to easily map from TemplateTypeParmTypes to +// TemplateTypeParmDecls, so we have this horrible PointerUnion. +typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, + SourceLocation> UnexpandedParameterPack; + /// Sema - This implements semantic analysis and AST building for C. class Sema { Sema(const Sema&); // DO NOT IMPLEMENT @@ -194,12 +204,15 @@ public: typedef OpaquePtr<QualType> TypeTy; typedef Attr AttrTy; typedef CXXBaseSpecifier BaseTy; - typedef CXXBaseOrMemberInitializer MemInitTy; + typedef CXXCtorInitializer MemInitTy; typedef Expr ExprTy; typedef Stmt StmtTy; typedef TemplateParameterList TemplateParamsTy; typedef NestedNameSpecifier CXXScopeTy; + OpenCLOptions OpenCLFeatures; + FPOptions FPFeatures; + const LangOptions &LangOpts; Preprocessor &PP; ASTContext &Context; @@ -220,30 +233,6 @@ public: /// This is used as part of a hack to omit that class from ADL results. DeclarationName VAListTagName; - /// A RAII object to temporarily push a declaration context. - class ContextRAII { - private: - Sema &S; - DeclContext *SavedContext; - - public: - ContextRAII(Sema &S, DeclContext *ContextToPush) - : S(S), SavedContext(S.CurContext) { - assert(ContextToPush && "pushing null context"); - S.CurContext = ContextToPush; - } - - void pop() { - if (!SavedContext) return; - S.CurContext = SavedContext; - SavedContext = 0; - } - - ~ContextRAII() { - pop(); - } - }; - /// PackContext - Manages the stack for #pragma pack. An alignment /// of 0 indicates default alignment. void *PackContext; // Really a "PragmaPackStack*" @@ -312,14 +301,125 @@ public: /// and must warn if not used. Only contains the first declaration. llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls; - /// \brief The stack of diagnostics that were delayed due to being - /// produced during the parsing of a declaration. - llvm::SmallVector<sema::DelayedDiagnostic, 0> DelayedDiagnostics; + class DelayedDiagnostics; + + class ParsingDeclState { + unsigned SavedStackSize; + friend class Sema::DelayedDiagnostics; + }; + + class ProcessingContextState { + unsigned SavedParsingDepth; + unsigned SavedActiveStackBase; + friend class Sema::DelayedDiagnostics; + }; + + /// 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; + + public: + DelayedDiagnostics() : Stack(0), StackSize(0), StackCapacity(0), + ActiveStackBase(0), ParsingDepth(0) {} + + ~DelayedDiagnostics() { + delete[] reinterpret_cast<char*>(Stack); + } - /// \brief The depth of the current ParsingDeclaration stack. - /// If nonzero, we are currently parsing a declaration (and - /// hence should delay deprecation warnings). - unsigned ParsingDeclDepth; + /// Adds a delayed diagnostic. + void add(const sema::DelayedDiagnostic &diag); + + /// 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); + + /// 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); + + ProcessingContextState state; + state.SavedParsingDepth = ParsingDepth; + state.SavedActiveStackBase = ActiveStackBase; + + ActiveStackBase = StackSize; + ParsingDepth = 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; + } + } DelayedDiagnostics; + + /// A RAII object to temporarily push a declaration context. + class ContextRAII { + private: + Sema &S; + DeclContext *SavedContext; + ProcessingContextState SavedContextState; + + public: + ContextRAII(Sema &S, DeclContext *ContextToPush) + : S(S), SavedContext(S.CurContext), + SavedContextState(S.DelayedDiagnostics.pushContext()) + { + assert(ContextToPush && "pushing null context"); + S.CurContext = ContextToPush; + } + + void pop() { + if (!SavedContext) return; + S.CurContext = SavedContext; + S.DelayedDiagnostics.popContext(SavedContextState); + SavedContext = 0; + } + + ~ContextRAII() { + pop(); + } + }; /// WeakUndeclaredIdentifiers - Identifiers contained in /// #pragma weak before declared. rare. may alias another @@ -365,6 +465,12 @@ public: /// standard library. LazyDeclPtr StdBadAlloc; + /// \brief The C++ "type_info" declaration, which is defined in <typeinfo>. + RecordDecl *CXXTypeInfoDecl; + + /// \brief The MSVC "_GUID" struct, which is defined in MSVC header files. + RecordDecl *MSVCGuidDecl; + /// A flag to remember whether the implicit forms of operator new and delete /// have been declared. bool GlobalNewDeleteDeclared; @@ -398,7 +504,17 @@ public: /// This evaluation context is used primary for the operand of the C++ /// \c typeid expression, whose argument is potentially evaluated only when /// it is an lvalue of polymorphic class type (C++ [basic.def.odr]p2). - PotentiallyPotentiallyEvaluated + PotentiallyPotentiallyEvaluated, + + /// \brief The current expression is potentially evaluated, but any + /// declarations referenced inside that expression are only used if + /// in fact the current expression is used. + /// + /// This value is used when parsing default function arguments, for which + /// we would like to provide diagnostics (e.g., passing non-POD arguments + /// through varargs) but do not want to mark declarations as "referenced" + /// until the default argument is used. + PotentiallyEvaluatedIfUsed }; /// \brief Data structure used to record current or nested @@ -468,6 +584,26 @@ public: /// \brief The number of SFINAE diagnostics that have been trapped. unsigned NumSFINAEErrors; + typedef llvm::DenseMap<ParmVarDecl *, llvm::SmallVector<ParmVarDecl *, 1> > + UnparsedDefaultArgInstantiationsMap; + + /// \brief A mapping from parameters with unparsed default arguments to the + /// set of instantiations of each parameter. + /// + /// This mapping is a temporary data structure used when parsing + /// nested class templates or nested classes of class templates, + /// where we might end up instantiating an inner class before the + /// default arguments of its methods have been parsed. + UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations; + + // Contains the locations of the beginning of unparsed default + // argument locations. + llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs; + + /// UndefinedInternals - all the used, undefined objects with + /// internal linkage in this translation unit. + llvm::DenseMap<NamedDecl*, SourceLocation> UndefinedInternals; + typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; @@ -481,7 +617,6 @@ public: /// of -Wselector. llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors; - GlobalMethodPool::iterator ReadMethodPool(Selector Sel); /// Private Helper predicate to check for 'self'. @@ -497,6 +632,9 @@ public: void Initialize(); const LangOptions &getLangOptions() const { return LangOpts; } + OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; } + FPOptions &getFPOptions() { return FPFeatures; } + Diagnostic &getDiagnostics() const { return Diags; } SourceManager &getSourceManager() const { return SourceMgr; } const TargetAttributesSema &getTargetAttributesSema() const; @@ -580,16 +718,20 @@ public: SourceLocation AttrLoc); QualType BuildFunctionType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, - bool Variadic, unsigned Quals, + bool Variadic, unsigned Quals, + RefQualifierKind RefQualifier, SourceLocation Loc, DeclarationName Entity, - const FunctionType::ExtInfo &Info); + FunctionType::ExtInfo Info); QualType BuildMemberPointerType(QualType T, QualType Class, SourceLocation Loc, DeclarationName Entity); QualType BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity); + QualType BuildParenType(QualType T); + TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S, - TagDecl **OwnedDecl = 0); + TagDecl **OwnedDecl = 0, + bool AllowAutoInTypeName = false); TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T, TypeSourceInfo *ReturnTypeInfo); /// \brief Package the given type and TSI into a ParsedType. @@ -630,8 +772,8 @@ public: QualType getElaboratedType(ElaboratedTypeKeyword Keyword, const CXXScopeSpec &SS, QualType T); - QualType BuildTypeofExprType(Expr *E); - QualType BuildDecltypeType(Expr *E); + QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); + QualType BuildDecltypeType(Expr *E, SourceLocation Loc); //===--------------------------------------------------------------------===// // Symbol table / Decl tracking callbacks: SemaDecl.cpp. @@ -644,6 +786,7 @@ public: ParsedType getTypeName(IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS = 0, bool isClassName = false, + bool HasTrailingDot = false, ParsedType ObjectType = ParsedType()); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); bool DiagnoseUnknownTypeName(const IdentifierInfo &II, @@ -674,18 +817,19 @@ public: bool &Redeclaration); void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous, bool &Redeclaration); + void CheckCompleteVariableDeclaration(VarDecl *var); NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, TypeSourceInfo *TInfo, LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists, bool IsFunctionDefinition, bool &Redeclaration); - void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); + bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); + void DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD); void CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, bool IsExplicitSpecialization, - bool &Redeclaration, - bool &OverloadableAttrRequired); + bool &Redeclaration); void CheckMain(FunctionDecl *FD); Decl *ActOnParamDeclarator(Scope *S, Declarator &D); ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC, @@ -707,14 +851,9 @@ public: bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); - - // Contains the locations of the beginning of unparsed default - // argument locations. - llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs; - - void AddInitializerToDecl(Decl *dcl, Expr *init); - void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit); - void ActOnUninitializedDecl(Decl *dcl, bool TypeContainsUndeducedAuto); + void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit, + bool TypeMayContainAuto); + void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); void ActOnInitializerError(Decl *Dcl); void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, @@ -734,6 +873,14 @@ public: void DiagnoseUnusedParameters(ParmVarDecl * const *Begin, ParmVarDecl * const *End); + /// \brief Diagnose whether the size of parameters or return value of a + /// function or obj-c method definition is pass-by-value and larger than a + /// specified threshold. + void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin, + ParmVarDecl * const *End, + QualType ReturnTy, + NamedDecl *D); + void DiagnoseInvalidJumps(Stmt *Body); Decl *ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr); @@ -745,11 +892,16 @@ public: /// no declarator (e.g. "struct foo;") is parsed. Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS); + + StmtResult ActOnVlaStmt(const DeclSpec &DS); Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, AccessSpecifier AS, RecordDecl *Record); + Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, + RecordDecl *Record); + bool isAcceptableTagRedeclaration(const TagDecl *Previous, TagTypeKind NewTag, SourceLocation NewTagLoc, @@ -767,7 +919,15 @@ public: IdentifierInfo *Name, SourceLocation NameLoc, AttributeList *Attr, AccessSpecifier AS, MultiTemplateParamsArg TemplateParameterLists, - bool &OwnedDecl, bool &IsDependent); + bool &OwnedDecl, bool &IsDependent, bool ScopedEnum, + bool ScopedEnumUsesClassTag, TypeResult UnderlyingType); + + Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, + unsigned TagSpec, SourceLocation TagLoc, + CXXScopeSpec &SS, + IdentifierInfo *Name, SourceLocation NameLoc, + AttributeList *Attr, + MultiTemplateParamsArg TempParamLists); TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, @@ -826,6 +986,7 @@ public: /// C++ record definition's base-specifiers clause and are starting its /// member declarations. void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, + ClassVirtSpecifiers &CVS, SourceLocation LBraceLoc); /// ActOnTagFinishDefinition - Invoked once we have finished parsing @@ -845,6 +1006,7 @@ public: Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, + AttributeList *Attrs, SourceLocation EqualLoc, Expr *Val); void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, Decl *EnumDecl, @@ -897,6 +1059,7 @@ public: void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls); bool MergeFunctionDecl(FunctionDecl *New, Decl *Old); bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old); + void MergeVarDeclTypes(VarDecl *New, VarDecl *Old); void MergeVarDecl(VarDecl *New, LookupResult &OldDecls); bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old); @@ -927,7 +1090,7 @@ public: Ovl_NonFunction }; OverloadKind CheckOverload(Scope *S, - FunctionDecl *New, + FunctionDecl *New, const LookupResult &OldDecls, NamedDecl *&OldDecl, bool IsForUsingDecl); @@ -938,7 +1101,8 @@ public: Expr *From, bool SuppressUserConversions, bool AllowExplicit, - bool InOverloadResolution); + bool InOverloadResolution, + bool CStyle); bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType); bool IsFloatingPointPromotion(QualType FromType, QualType ToType); @@ -948,8 +1112,10 @@ public: QualType& ConvertedType, bool &IncompatibleObjC); bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType, bool &IncompatibleObjC); - bool FunctionArgTypesAreEqual (FunctionProtoType* OldType, - FunctionProtoType* NewType); + bool IsBlockPointerConversion(QualType FromType, QualType ToType, + QualType& ConvertedType); + bool FunctionArgTypesAreEqual(const FunctionProtoType *OldType, + const FunctionProtoType *NewType); bool CheckPointerConversion(Expr *From, QualType ToType, CastKind &Kind, @@ -962,10 +1128,16 @@ public: CastKind &Kind, CXXCastPath &BasePath, bool IgnoreBaseAccess); - bool IsQualificationConversion(QualType FromType, QualType ToType); + bool IsQualificationConversion(QualType FromType, QualType ToType, + bool CStyle); bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); + ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, + const VarDecl *NRVOCandidate, + QualType ResultType, + Expr *Value); + ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init); @@ -1014,12 +1186,14 @@ public: bool SuppressUserConversions = false); void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, + Expr::Classification ObjectClassification, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversion = false); void AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, + Expr::Classification ObjectClassification, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false); @@ -1028,6 +1202,7 @@ public: CXXRecordDecl *ActingContext, const TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, + Expr::Classification ObjectClassification, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions = false); @@ -1051,7 +1226,7 @@ public: DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, const FunctionProtoType *Proto, - QualType ObjectTy, Expr **Args, unsigned NumArgs, + Expr *Object, Expr **Args, unsigned NumArgs, OverloadCandidateSet& CandidateSet); void AddMemberOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, @@ -1074,12 +1249,28 @@ public: OverloadCandidateSet& CandidateSet, bool PartialOverloading = false); + // Emit as a 'note' the specific overload candidate void NoteOverloadCandidate(FunctionDecl *Fn); - - FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, + + // Emit as a series of 'note's all template and non-templates + // identified by the expression Expr + void NoteAllOverloadCandidates(Expr* E); + + // [PossiblyAFunctionType] --> [Return] + // NonFunctionType --> NonFunctionType + // R (A) --> R(A) + // R (*)(A) --> R (A) + // R (&)(A) --> R (A) + // R (S::*)(A) --> R (A) + QualType ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType); + + FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType, bool Complain, DeclAccessPair &Found); - FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From); + + FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From, + bool Complain = false, + DeclAccessPair* Found = 0); Expr *FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl, @@ -1097,8 +1288,8 @@ public: UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + Expr *ExecConfig); ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned Opc, @@ -1117,12 +1308,10 @@ public: ExprResult BuildCallToMemberFunction(Scope *S, Expr *MemExpr, SourceLocation LParenLoc, Expr **Args, - unsigned NumArgs, SourceLocation *CommaLocs, - SourceLocation RParenLoc); + unsigned NumArgs, SourceLocation RParenLoc); ExprResult BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, - SourceLocation *CommaLocs, SourceLocation RParenLoc); ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, @@ -1135,7 +1324,8 @@ public: CallExpr *CE, FunctionDecl *FD); /// Helpers for dealing with blocks and functions. - bool CheckParmsForFunctionDef(FunctionDecl *FD); + bool CheckParmsForFunctionDef(ParmVarDecl **Param, ParmVarDecl **ParamEnd, + bool CheckParameterNames); void CheckCXXDefaultArguments(FunctionDecl *FD); void CheckExtraCXXDefaultArguments(Declarator &D); Scope *getNonFieldDeclScope(Scope *S); @@ -1176,13 +1366,14 @@ public: /// Tag name lookup, which finds the names of enums, classes, /// structs, and unions. LookupTagName, + /// Label name lookup. + LookupLabel, /// Member name lookup, which finds the names of /// class/struct/union members. LookupMemberName, - // Look up of an operator name (e.g., operator+) for use with - // operator overloading. This lookup is similar to ordinary name - // lookup, but will ignore any declarations that are class - // members. + /// Look up of an operator name (e.g., operator+) for use with + /// operator overloading. This lookup is similar to ordinary name + /// lookup, but will ignore any declarations that are class members. LookupOperatorName, /// Look up of a name that precedes the '::' scope resolution /// operator in C++. This lookup completely ignores operator, object, @@ -1245,6 +1436,9 @@ public: QualType T1, QualType T2, UnresolvedSetImpl &Functions); + LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, + bool isLocalLabel = false); + DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); @@ -1277,6 +1471,10 @@ public: CTC_CXXCasts, /// \brief A member lookup context. CTC_MemberLookup, + /// \brief An Objective-C ivar lookup context (e.g., self->ivar). + CTC_ObjCIvarLookup, + /// \brief An Objective-C property lookup context (e.g., self.prop). + CTC_ObjCPropertyLookup, /// \brief The receiver of an Objective-C message send within an /// Objective-C method where 'super' is a valid keyword. CTC_ObjCMessageReceiver @@ -1308,8 +1506,14 @@ public: // More parsing and symbol table subroutines. // Decl attributes - this routine is the top level dispatcher. - void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); - void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL); + void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, + bool NonInheritable = true, bool Inheritable = true); + void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, + bool NonInheritable = true, bool Inheritable = true); + + bool CheckRegparmAttr(const AttributeList &attr, unsigned &value); + bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC); + bool CheckNoReturnAttr(const AttributeList &attr); void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, bool &IncompleteImpl, unsigned DiagID); @@ -1338,6 +1542,14 @@ public: ObjCIvarDecl **Fields, unsigned nIvars, SourceLocation Loc); + /// \brief Determine whether we can synthesize a provisional ivar for the + /// given name. + ObjCPropertyDecl *canSynthesizeProvisionalIvar(IdentifierInfo *II); + + /// \brief Determine whether we can synthesize a provisional ivar for the + /// given property. + bool canSynthesizeProvisionalIvar(ObjCPropertyDecl *Property); + /// ImplMethodsVsClassMethods - This is main routine to warn if any method /// remains unimplemented in the class or category @implementation. void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl, @@ -1484,7 +1696,7 @@ public: // FIXME: The const_cast here is ugly. RValue references would make this // much nicer (or we could duplicate a bunch of the move semantics // emulation code from Ownership.h). - FullExprArg(const FullExprArg& Other): E(Other.E) {} + FullExprArg(const FullExprArg& Other) : E(Other.E) {} ExprResult release() { return move(E); @@ -1498,7 +1710,7 @@ public: private: // FIXME: No need to make the entire Sema class a friend when it's just - // Sema::FullExpr that needs access to the constructor below. + // Sema::MakeFullExpr that needs access to the constructor below. friend class Sema; explicit FullExprArg(Expr *expr) : E(expr) {} @@ -1512,7 +1724,8 @@ public: StmtResult ActOnExprStmt(FullExprArg Expr); - StmtResult ActOnNullStmt(SourceLocation SemiLoc); + StmtResult ActOnNullStmt(SourceLocation SemiLoc, + bool LeadingEmptyMacro = false); StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, MultiStmtArg Elts, bool isStmtExpr); @@ -1520,6 +1733,7 @@ public: SourceLocation StartLoc, SourceLocation EndLoc); void ActOnForEachDeclStmt(DeclGroupPtrTy Decl); + StmtResult ActOnForEachLValueExpr(Expr *E); StmtResult ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal, SourceLocation DotDotDotLoc, Expr *RHSVal, SourceLocation ColonLoc); @@ -1528,22 +1742,21 @@ public: StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope); - StmtResult ActOnLabelStmt(SourceLocation IdentLoc, - IdentifierInfo *II, - SourceLocation ColonLoc, - Stmt *SubStmt); + StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, + SourceLocation ColonLoc, Stmt *SubStmt); + StmtResult ActOnIfStmt(SourceLocation IfLoc, - FullExprArg CondVal, Decl *CondVar, - Stmt *ThenVal, - SourceLocation ElseLoc, Stmt *ElseVal); + FullExprArg CondVal, Decl *CondVar, + Stmt *ThenVal, + SourceLocation ElseLoc, Stmt *ElseVal); StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond, Decl *CondVar); StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body); StmtResult ActOnWhileStmt(SourceLocation WhileLoc, - FullExprArg Cond, - Decl *CondVar, Stmt *Body); + FullExprArg Cond, + Decl *CondVar, Stmt *Body); StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, @@ -1563,13 +1776,16 @@ public: StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, - IdentifierInfo *LabelII); + LabelDecl *TheDecl); StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp); StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope); StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope); + const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, + bool AllowFunctionParameters); + StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); StmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); @@ -1606,11 +1822,10 @@ public: Expr *SynchExpr, Stmt *SynchBody); - VarDecl *BuildExceptionDeclaration(Scope *S, QualType ExDeclType, + VarDecl *BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, IdentifierInfo *Name, - SourceLocation Loc, - SourceRange Range); + SourceLocation Loc); Decl *ActOnExceptionDeclarator(Scope *S, Declarator &D); StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, @@ -1630,18 +1845,31 @@ public: void DiagnoseUnusedExprResult(const Stmt *S); void DiagnoseUnusedDecl(const NamedDecl *ND); - typedef uintptr_t ParsingDeclStackState; + ParsingDeclState PushParsingDeclaration() { + return DelayedDiagnostics.pushParsingDecl(); + } + void PopParsingDeclaration(ParsingDeclState state, Decl *decl) { + DelayedDiagnostics::popParsingDecl(*this, state, decl); + } + + typedef ProcessingContextState ParsingClassState; + ParsingClassState PushParsingClass() { + return DelayedDiagnostics.pushContext(); + } + void PopParsingClass(ParsingClassState state) { + DelayedDiagnostics.popContext(state); + } - ParsingDeclStackState PushParsingDeclaration(); - void PopParsingDeclaration(ParsingDeclStackState S, Decl *D); - void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc); + void EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, + SourceLocation Loc, bool UnknownObjCClass=false); void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. - bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc); + bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, + bool UnknownObjCClass=false); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, SourceLocation Loc); @@ -1654,6 +1882,7 @@ public: void MarkDeclarationReferenced(SourceLocation Loc, Decl *D); void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); + void MarkDeclarationsReferencedInExpr(Expr *E); bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD); // Primary Expressions. @@ -1674,18 +1903,19 @@ public: const TemplateArgumentListInfo *TemplateArgs); ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, + ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS = 0); ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, + ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS = 0); - VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field, - llvm::SmallVectorImpl<FieldDecl *> &Path); ExprResult - BuildAnonymousStructUnionMemberReference(SourceLocation Loc, - FieldDecl *Field, - Expr *BaseObjectExpr = 0, - SourceLocation OpLoc = SourceLocation()); + BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, + SourceLocation nameLoc, + IndirectFieldDecl *indirectField, + Expr *baseObjectExpr = 0, + SourceLocation opLoc = SourceLocation()); ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs); @@ -1724,7 +1954,7 @@ public: ExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks); // Binary/Unary Operators. 'Tok' is the token for the operator. - ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, unsigned OpcIn, + ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputArg); ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *input); @@ -1740,10 +1970,15 @@ public: ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, void *TyOrEx, const SourceRange &ArgRange); - bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R); - bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, - const SourceRange &R, bool isSizeof); + ExprResult CheckPlaceholderExpr(Expr *E, SourceLocation Loc); + bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, + SourceRange R, bool isSizeof); + ExprResult ActOnSizeofParameterPackExpr(Scope *S, + SourceLocation OpLoc, + IdentifierInfo &Name, + SourceLocation NameLoc, + SourceLocation RParenLoc); ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Kind, Expr *Input); @@ -1803,12 +2038,16 @@ public: /// This provides the location of the left/right parens and a list of comma /// locations. ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, - MultiExprArg Args, SourceLocation *CommaLocs, - SourceLocation RParenLoc); + MultiExprArg Args, SourceLocation RParenLoc, + Expr *ExecConfig = 0); ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + Expr *ExecConfig = 0); + + ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, + MultiExprArg ExecConfig, SourceLocation GGGLoc); ExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc, @@ -1851,7 +2090,7 @@ public: ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *lhs, Expr *rhs); ExprResult CreateBuiltinBinOp(SourceLocation TokLoc, - unsigned Opc, Expr *lhs, Expr *rhs); + BinaryOperatorKind Opc, Expr *lhs, Expr *rhs); /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null /// in the case of a the GNU conditional expr extension. @@ -1860,10 +2099,9 @@ public: Expr *Cond, Expr *LHS, Expr *RHS); /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". - ExprResult ActOnAddrLabel(SourceLocation OpLoc, - SourceLocation LabLoc, - IdentifierInfo *LabelII); - + ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, + LabelDecl *LD); + ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc); // "({..})" @@ -1891,16 +2129,6 @@ public: unsigned NumComponents, SourceLocation RParenLoc); - // __builtin_types_compatible_p(type1, type2) - ExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc, - ParsedType arg1, - ParsedType arg2, - SourceLocation RPLoc); - ExprResult BuildTypesCompatibleExpr(SourceLocation BuiltinLoc, - TypeSourceInfo *argTInfo1, - TypeSourceInfo *argTInfo2, - SourceLocation RPLoc); - // __builtin_choose_expr(constExpr, expr1, expr2) ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *cond, Expr *expr1, @@ -1993,6 +2221,8 @@ public: bool IsTypeName, SourceLocation TypenameLoc); + bool CheckInheritedConstructorUsingDecl(UsingDecl *UD); + Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, bool HasUsingKeyword, @@ -2009,8 +2239,8 @@ public: void AddCXXDirectInitializerToDecl(Decl *Dcl, SourceLocation LParenLoc, MultiExprArg Exprs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + bool TypeMayContainAuto); /// InitializeVarWithConstructor - Creates an CXXConstructExpr /// and sets it as the initializer for the the passed in VarDecl. @@ -2025,7 +2255,8 @@ public: ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, CXXConstructorDecl *Constructor, MultiExprArg Exprs, - bool RequiresZeroInit, unsigned ConstructKind); + bool RequiresZeroInit, unsigned ConstructKind, + SourceRange ParenRange); // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if // the constructor can be elidable? @@ -2033,7 +2264,8 @@ public: BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, CXXConstructorDecl *Constructor, bool Elidable, MultiExprArg Exprs, bool RequiresZeroInit, - unsigned ConstructKind); + unsigned ConstructKind, + SourceRange ParenRange); /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating /// the default expr if needed. @@ -2072,6 +2304,12 @@ public: void DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor); + /// \brief Declare all inherited constructors for the given class. + /// + /// \param ClassDecl The class declaration into which the inherited + /// constructors will be added. + void DeclareInheritedConstructors(CXXRecordDecl *ClassDecl); + /// \brief Declare the implicit copy constructor for the given class. /// /// \param S The scope of the class, which may be NULL if this is a @@ -2156,8 +2394,29 @@ public: void *TyOrExpr, SourceLocation RParenLoc); + ExprResult BuildCXXUuidof(QualType TypeInfoType, + SourceLocation TypeidLoc, + TypeSourceInfo *Operand, + SourceLocation RParenLoc); + ExprResult BuildCXXUuidof(QualType TypeInfoType, + SourceLocation TypeidLoc, + Expr *Operand, + SourceLocation RParenLoc); + + /// ActOnCXXUuidof - Parse __uuidof( something ). + ExprResult ActOnCXXUuidof(SourceLocation OpLoc, + SourceLocation LParenLoc, bool isType, + void *TyOrExpr, + SourceLocation RParenLoc); + + //// ActOnCXXThis - Parse 'this' pointer. - ExprResult ActOnCXXThis(SourceLocation ThisLoc); + ExprResult ActOnCXXThis(SourceLocation loc); + + /// tryCaptureCXXThis - Try to capture a 'this' pointer. Returns a + /// pointer to an instance method whose 'this' pointer is + /// capturable, or null if this is not possible. + CXXMethodDecl *tryCaptureCXXThis(); /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); @@ -2173,11 +2432,14 @@ public: /// Can be interpreted either as function-style casting ("int(x)") /// or class type construction ("ClassType(x,y,z)") /// or creation of a value-initialized type ("int()"). - ExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange, - ParsedType TypeRep, + ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, + SourceLocation LParenLoc, + MultiExprArg Exprs, + SourceLocation RParenLoc); + + ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, MultiExprArg Exprs, - SourceLocation *CommaLocs, SourceLocation RParenLoc); /// ActOnCXXNew - Parsed a C++ 'new' expression. @@ -2195,12 +2457,12 @@ public: SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, - SourceLocation TypeLoc, - SourceRange TypeRange, + TypeSourceInfo *AllocTypeInfo, Expr *ArraySize, SourceLocation ConstructorLParen, MultiExprArg ConstructorArgs, - SourceLocation ConstructorRParen); + SourceLocation ConstructorRParen, + bool TypeMayContainAuto = true); bool CheckAllocatedType(QualType AllocType, SourceLocation Loc, SourceRange R); @@ -2231,14 +2493,37 @@ public: SourceLocation StmtLoc, bool ConvertToBoolean); + ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, + Expr *Operand, SourceLocation RParen); + ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, + SourceLocation RParen); + /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support /// pseudo-functions. ExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT, SourceLocation KWLoc, - SourceLocation LParen, ParsedType Ty, SourceLocation RParen); + ExprResult BuildUnaryTypeTrait(UnaryTypeTrait OTT, + SourceLocation KWLoc, + TypeSourceInfo *T, + SourceLocation RParen); + + /// ActOnBinaryTypeTrait - Parsed one of the bianry type trait support + /// pseudo-functions. + ExprResult ActOnBinaryTypeTrait(BinaryTypeTrait OTT, + SourceLocation KWLoc, + ParsedType LhsTy, + ParsedType RhsTy, + SourceLocation RParen); + + ExprResult BuildBinaryTypeTrait(BinaryTypeTrait BTT, + SourceLocation KWLoc, + TypeSourceInfo *LhsT, + TypeSourceInfo *RhsT, + SourceLocation RParen); + ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, @@ -2268,14 +2553,15 @@ public: UnqualifiedId &SecondTypeName, bool HasTrailingLParen); - /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is - /// non-empty, will create a new CXXExprWithTemporaries expression. - /// Otherwise, just returs the passed in expression. - Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr); - ExprResult MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr); - FullExpr CreateFullExpr(Expr *SubExpr); + /// MaybeCreateExprWithCleanups - If the current full-expression + /// requires any cleanups, surround it with a ExprWithCleanups node. + /// Otherwise, just returns the passed-in expression. + Expr *MaybeCreateExprWithCleanups(Expr *SubExpr); + Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); + ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); ExprResult ActOnFinishFullExpr(Expr *Expr); + StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC); @@ -2373,9 +2659,8 @@ public: Expr *BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc); - CXXMemberCallExpr *BuildCXXMemberCallExpr(Expr *Exp, - NamedDecl *FoundDecl, - CXXMethodDecl *Method); + ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, + CXXMethodDecl *Method); ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc, SourceLocation EncodeLoc, @@ -2423,7 +2708,7 @@ public: Decl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, - Expr *BitfieldWidth, + Expr *BitfieldWidth, const VirtSpecifiers &VS, Expr *Init, bool IsDefinition, bool Deleted = false); @@ -2435,10 +2720,10 @@ public: SourceLocation IdLoc, SourceLocation LParenLoc, Expr **Args, unsigned NumArgs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc); + SourceLocation RParenLoc, + SourceLocation EllipsisLoc); - MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args, + MemInitResult BuildMemberInitializer(ValueDecl *Member, Expr **Args, unsigned NumArgs, SourceLocation IdLoc, SourceLocation LParenLoc, SourceLocation RParenLoc); @@ -2448,11 +2733,19 @@ public: Expr **Args, unsigned NumArgs, SourceLocation LParenLoc, SourceLocation RParenLoc, - CXXRecordDecl *ClassDecl); - - bool SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor, - CXXBaseOrMemberInitializer **Initializers, - unsigned NumInitializers, bool AnyErrors); + CXXRecordDecl *ClassDecl, + SourceLocation EllipsisLoc); + + MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, + Expr **Args, unsigned NumArgs, + SourceLocation RParenLoc, + SourceLocation LParenLoc, + CXXRecordDecl *ClassDecl, + SourceLocation EllipsisLoc); + + bool SetCtorInitializers(CXXConstructorDecl *Constructor, + CXXCtorInitializer **Initializers, + unsigned NumInitializers, bool AnyErrors); void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); @@ -2466,8 +2759,11 @@ public: /// \brief The list of classes whose vtables have been used within /// this translation unit, and the source locations at which the /// first use occurred. - llvm::SmallVector<std::pair<CXXRecordDecl *, SourceLocation>, 16> - VTableUses; + typedef std::pair<CXXRecordDecl*, SourceLocation> VTableUse; + + /// \brief The list of vtables that are required but have not yet been + /// materialized. + llvm::SmallVector<VTableUse, 16> VTableUses; /// \brief The set of classes whose vtables have been used within /// this translation unit, and a bit that will be true if the vtable is @@ -2546,20 +2842,15 @@ public: CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, - TypeSourceInfo *TInfo); - - /// SetClassDeclAttributesFromBase - Copies class decl traits - /// (such as whether the class has a trivial constructor, - /// trivial destructor etc) from the given base class. - void SetClassDeclAttributesFromBase(CXXRecordDecl *Class, - const CXXRecordDecl *BaseClass, - bool BaseIsVirtual); + TypeSourceInfo *TInfo, + SourceLocation EllipsisLoc); BaseResult ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, - ParsedType basetype, SourceLocation - BaseLoc); + ParsedType basetype, + SourceLocation BaseLoc, + SourceLocation EllipsisLoc); bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, unsigned NumBases); @@ -2596,13 +2887,18 @@ public: bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, const CXXMethodDecl *Old); - /// CheckOverridingFunctionAttributes - Checks whether attributes are - /// incompatible or prevent overriding. - bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New, - const CXXMethodDecl *Old); - bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); + /// CheckOverrideControl - Check C++0x override control semantics. + void CheckOverrideControl(const Decl *D); + + /// CheckForFunctionMarkedFinal - Checks whether a virtual member function + /// overrides a virtual member function marked 'final', according to + /// C++0x [class.virtual]p3. + bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, + const CXXMethodDecl *Old); + + //===--------------------------------------------------------------------===// // C++ Access Control // @@ -2661,6 +2957,10 @@ public: /// 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; + void ActOnStartSuppressingAccessChecks(); void ActOnStopSuppressingAccessChecks(); @@ -2732,12 +3032,13 @@ public: Decl *ActOnTemplateTemplateParameter(Scope *S, SourceLocation TmpLoc, TemplateParamsTy *Params, + SourceLocation EllipsisLoc, IdentifierInfo *ParamName, SourceLocation ParamNameLoc, unsigned Depth, unsigned Position, SourceLocation EqualLoc, - const ParsedTemplateArgument &DefaultArg); + ParsedTemplateArgument DefaultArg); TemplateParamsTy * ActOnTemplateParameterList(unsigned Depth, @@ -2753,7 +3054,8 @@ public: TPC_ClassTemplate, TPC_FunctionTemplate, TPC_ClassTemplateMember, - TPC_FriendFunctionTemplate + TPC_FriendFunctionTemplate, + TPC_FriendFunctionTemplateDefinition }; bool CheckTemplateParameterList(TemplateParameterList *NewParams, @@ -2788,10 +3090,11 @@ public: ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc); - TypeResult ActOnTagTemplateIdType(TypeResult Type, - TagUseKind TUK, - TypeSpecifierType TagSpec, - SourceLocation TagLoc); + TypeResult ActOnTagTemplateIdType(CXXScopeSpec &SS, + TypeResult Type, + TagUseKind TUK, + TypeSpecifierType TagSpec, + SourceLocation TagLoc); ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, LookupResult &R, @@ -2809,11 +3112,6 @@ public: bool EnteringContext, TemplateTy &Template); - bool CheckClassTemplatePartialSpecializationArgs( - TemplateParameterList *TemplateParams, - const TemplateArgumentListBuilder &TemplateArgs, - bool &MirrorsPrimaryTemplate); - DeclResult ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, @@ -2886,7 +3184,7 @@ public: SourceLocation TemplateLoc, SourceLocation RAngleLoc, Decl *Param, - TemplateArgumentListBuilder &Converted); + llvm::SmallVectorImpl<TemplateArgument> &Converted); /// \brief Specifies the context in which a particular template /// argument is being checked. @@ -2906,21 +3204,22 @@ public: bool CheckTemplateArgument(NamedDecl *Param, const TemplateArgumentLoc &Arg, - TemplateDecl *Template, + NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, - TemplateArgumentListBuilder &Converted, + unsigned ArgumentPackIndex, + llvm::SmallVectorImpl<TemplateArgument> &Converted, CheckTemplateArgumentKind CTAK = CTAK_Specified); bool CheckTemplateArgumentList(TemplateDecl *Template, SourceLocation TemplateLoc, const TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs, - TemplateArgumentListBuilder &Converted); + llvm::SmallVectorImpl<TemplateArgument> &Converted); bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, const TemplateArgumentLoc &Arg, - TemplateArgumentListBuilder &Converted); + llvm::SmallVectorImpl<TemplateArgument> &Converted); bool CheckTemplateArgument(TemplateTypeParmDecl *Param, TypeSourceInfo *Arg); @@ -3034,6 +3333,289 @@ public: const TemplateArgument *Args, unsigned NumArgs); + //===--------------------------------------------------------------------===// + // C++ Variadic Templates (C++0x [temp.variadic]) + //===--------------------------------------------------------------------===// + + /// \brief The context in which an unexpanded parameter pack is + /// being diagnosed. + /// + /// Note that the values of this enumeration line up with the first + /// argument to the \c err_unexpanded_parameter_pack diagnostic. + enum UnexpandedParameterPackContext { + /// \brief An arbitrary expression. + UPPC_Expression = 0, + + /// \brief The base type of a class type. + UPPC_BaseType, + + /// \brief The type of an arbitrary declaration. + UPPC_DeclarationType, + + /// \brief The type of a data member. + UPPC_DataMemberType, + + /// \brief The size of a bit-field. + UPPC_BitFieldWidth, + + /// \brief The expression in a static assertion. + UPPC_StaticAssertExpression, + + /// \brief The fixed underlying type of an enumeration. + UPPC_FixedUnderlyingType, + + /// \brief The enumerator value. + UPPC_EnumeratorValue, + + /// \brief A using declaration. + UPPC_UsingDeclaration, + + /// \brief A friend declaration. + UPPC_FriendDeclaration, + + /// \brief A declaration qualifier. + UPPC_DeclarationQualifier, + + /// \brief An initializer. + UPPC_Initializer, + + /// \brief A default argument. + UPPC_DefaultArgument, + + /// \brief The type of a non-type template parameter. + UPPC_NonTypeTemplateParameterType, + + /// \brief The type of an exception. + UPPC_ExceptionType, + + /// \brief Partial specialization. + UPPC_PartialSpecialization + }; + + /// \brief If the given type contains an unexpanded parameter pack, + /// diagnose the error. + /// + /// \param Loc The source location where a diagnostc should be emitted. + /// + /// \param T The type that is being checked for unexpanded parameter + /// packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, + UnexpandedParameterPackContext UPPC); + + /// \brief If the given expression contains an unexpanded parameter + /// pack, diagnose the error. + /// + /// \param E The expression that is being checked for unexpanded + /// parameter packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(Expr *E, + UnexpandedParameterPackContext UPPC = UPPC_Expression); + + /// \brief If the given nested-name-specifier contains an unexpanded + /// parameter pack, diagnose the error. + /// + /// \param SS The nested-name-specifier that is being checked for + /// unexpanded parameter packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, + UnexpandedParameterPackContext UPPC); + + /// \brief If the given name contains an unexpanded parameter pack, + /// diagnose the error. + /// + /// \param NameInfo The name (with source location information) that + /// is being checked for unexpanded parameter packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, + UnexpandedParameterPackContext UPPC); + + /// \brief If the given template name contains an unexpanded parameter pack, + /// diagnose the error. + /// + /// \param Loc The location of the template name. + /// + /// \param Template The template name that is being checked for unexpanded + /// parameter packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, + TemplateName Template, + UnexpandedParameterPackContext UPPC); + + /// \brief If the given template argument contains an unexpanded parameter + /// pack, diagnose the error. + /// + /// \param Arg The template argument that is being checked for unexpanded + /// parameter packs. + /// + /// \returns true if an error ocurred, false otherwise. + bool DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, + UnexpandedParameterPackContext UPPC); + + /// \brief Collect the set of unexpanded parameter packs within the given + /// template argument. + /// + /// \param Arg The template argument that will be traversed to find + /// unexpanded parameter packs. + void collectUnexpandedParameterPacks(TemplateArgument Arg, + llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + + /// \brief Collect the set of unexpanded parameter packs within the given + /// template argument. + /// + /// \param Arg The template argument that will be traversed to find + /// unexpanded parameter packs. + void collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, + llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + + /// \brief Collect the set of unexpanded parameter packs within the given + /// type. + /// + /// \param T The type that will be traversed to find + /// unexpanded parameter packs. + void collectUnexpandedParameterPacks(QualType T, + llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + + /// \brief Collect the set of unexpanded parameter packs within the given + /// type. + /// + /// \param TL The type that will be traversed to find + /// unexpanded parameter packs. + void collectUnexpandedParameterPacks(TypeLoc TL, + llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); + + /// \brief Invoked when parsing a template argument followed by an + /// ellipsis, which creates a pack expansion. + /// + /// \param Arg The template argument preceding the ellipsis, which + /// may already be invalid. + /// + /// \param EllipsisLoc The location of the ellipsis. + ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, + SourceLocation EllipsisLoc); + + /// \brief Invoked when parsing a type followed by an ellipsis, which + /// creates a pack expansion. + /// + /// \param Type The type preceding the ellipsis, which will become + /// the pattern of the pack expansion. + /// + /// \param EllipsisLoc The location of the ellipsis. + TypeResult ActOnPackExpansion(ParsedType Type, SourceLocation EllipsisLoc); + + /// \brief Construct a pack expansion type from the pattern of the pack + /// expansion. + TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern, + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions); + + /// \brief Construct a pack expansion type from the pattern of the pack + /// expansion. + QualType CheckPackExpansion(QualType Pattern, + SourceRange PatternRange, + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions); + + /// \brief Invoked when parsing an expression followed by an ellipsis, which + /// creates a pack expansion. + /// + /// \param Pattern The expression preceding the ellipsis, which will become + /// the pattern of the pack expansion. + /// + /// \param EllipsisLoc The location of the ellipsis. + ExprResult ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc); + + /// \brief Invoked when parsing an expression followed by an ellipsis, which + /// creates a pack expansion. + /// + /// \param Pattern The expression preceding the ellipsis, which will become + /// the pattern of the pack expansion. + /// + /// \param EllipsisLoc The location of the ellipsis. + ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions); + + /// \brief Determine whether we could expand a pack expansion with the + /// given set of parameter packs into separate arguments by repeatedly + /// transforming the pattern. + /// + /// \param EllipsisLoc The location of the ellipsis that identifies the + /// pack expansion. + /// + /// \param PatternRange The source range that covers the entire pattern of + /// the pack expansion. + /// + /// \param Unexpanded The set of unexpanded parameter packs within the + /// pattern. + /// + /// \param 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. + /// + /// \param RetainExpansion Whether the caller should add an unexpanded + /// pack expansion after all of the expanded arguments. This is used + /// when extending explicitly-specified template argument packs per + /// C++0x [temp.arg.explicit]p9. + /// + /// \param NumExpansions The number of separate arguments that will be in + /// the expanded form of the corresponding pack expansion. This is both an + /// input and an output parameter, which can be set by the caller if the + /// number of expansions is known a priori (e.g., due to a prior substitution) + /// and will be set by the callee when the number of expansions is known. + /// The callee must set this value when \c ShouldExpand is \c true; it may + /// set this value in other cases. + /// + /// \returns true if an error occurred (e.g., because the parameter packs + /// are to be instantiated with arguments of different lengths), false + /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) + /// must be set. + bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, + SourceRange PatternRange, + const UnexpandedParameterPack *Unexpanded, + unsigned NumUnexpanded, + const MultiLevelTemplateArgumentList &TemplateArgs, + bool &ShouldExpand, + bool &RetainExpansion, + llvm::Optional<unsigned> &NumExpansions); + + /// \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 + /// consistent across all of the unexpanded parameter packs in its pattern. + unsigned getNumArgumentsInExpansion(QualType T, + const MultiLevelTemplateArgumentList &TemplateArgs); + + /// \brief Determine whether the given declarator contains any unexpanded + /// parameter packs. + /// + /// This routine is used by the parser to disambiguate function declarators + /// with an ellipsis prior to the ')', e.g., + /// + /// \code + /// void f(T...); + /// \endcode + /// + /// To determine whether we have an (unnamed) function parameter pack or + /// a variadic function. + /// + /// \returns true if the declarator contains any unexpanded parameter packs, + /// false otherwise. + bool containsUnexpandedParameterPacks(Declarator &D); + + //===--------------------------------------------------------------------===// + // C++ Template Argument Deduction (C++ [temp.deduct]) + //===--------------------------------------------------------------------===// + /// \brief Describes the result of template argument deduction. /// /// The TemplateDeductionResult enumeration describes the result of @@ -3128,17 +3710,22 @@ public: FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info); + bool DeduceAutoType(QualType AutoType, Expr *Initializer, QualType &Result); + FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, - TemplatePartialOrderingContext TPOC); + TemplatePartialOrderingContext TPOC, + unsigned NumCallArguments); UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, TemplatePartialOrderingContext TPOC, + unsigned NumCallArguments, SourceLocation Loc, const PartialDiagnostic &NoneDiag, const PartialDiagnostic &AmbigDiag, - const PartialDiagnostic &CandidateDiag); + const PartialDiagnostic &CandidateDiag, + bool Complain = true); ClassTemplatePartialSpecializationDecl * getMoreSpecializedPartialSpecialization( @@ -3206,9 +3793,10 @@ public: /// \brief The point of instantiation within the source code. SourceLocation PointOfInstantiation; - /// \brief The template in which we are performing the instantiation, - /// for substitutions of prior template arguments. - TemplateDecl *Template; + /// \brief The template (or partial specialization) in which we are + /// performing the instantiation, for substitutions of prior template + /// arguments. + NamedDecl *Template; /// \brief The entity that is being instantiated. uintptr_t Entity; @@ -3220,6 +3808,10 @@ public: /// \brief The number of template arguments in TemplateArgs. unsigned NumTemplateArgs; + /// \brief The template deduction info object associated with the + /// substitution or checking of explicit or deduced template arguments. + sema::TemplateDeductionInfo *DeductionInfo; + /// \brief The source range that covers the construct that cause /// the instantiation, e.g., the template-id that causes a class /// template instantiation. @@ -3227,7 +3819,7 @@ public: ActiveTemplateInstantiation() : Kind(TemplateInstantiation), Template(0), Entity(0), TemplateArgs(0), - NumTemplateArgs(0) {} + NumTemplateArgs(0), DeductionInfo(0) {} /// \brief Determines whether this template is an actual instantiation /// that should be counted toward the maximum instantiation depth. @@ -3278,6 +3870,13 @@ public: llvm::SmallVector<ActiveTemplateInstantiation, 16> ActiveTemplateInstantiations; + /// \brief Whether we are in a SFINAE context that is not associated with + /// template instantiation. + /// + /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside + /// of a template instantiation or template argument deduction. + bool InNonInstantiationSFINAEContext; + /// \brief The number of ActiveTemplateInstantiation entries in /// \c ActiveTemplateInstantiations that are not actual instantiations and, /// therefore, should not be counted as part of the instantiation depth. @@ -3292,12 +3891,49 @@ public: /// to implement it anywhere else. ActiveTemplateInstantiation LastTemplateInstantiationErrorContext; + /// \brief The current index into pack expansion arguments that will be + /// used for substitution of parameter packs. + /// + /// The pack expansion index will be -1 to indicate that parameter packs + /// should be instantiated as themselves. Otherwise, the index specifies + /// which argument within the parameter pack will be used for substitution. + int ArgumentPackSubstitutionIndex; + + /// \brief RAII object used to change the argument pack substitution index + /// within a \c Sema object. + /// + /// See \c ArgumentPackSubstitutionIndex for more information. + class ArgumentPackSubstitutionIndexRAII { + Sema &Self; + int OldSubstitutionIndex; + + public: + ArgumentPackSubstitutionIndexRAII(Sema &Self, int NewSubstitutionIndex) + : Self(Self), OldSubstitutionIndex(Self.ArgumentPackSubstitutionIndex) { + Self.ArgumentPackSubstitutionIndex = NewSubstitutionIndex; + } + + ~ArgumentPackSubstitutionIndexRAII() { + Self.ArgumentPackSubstitutionIndex = OldSubstitutionIndex; + } + }; + + friend class ArgumentPackSubstitutionRAII; + /// \brief The stack of calls expression undergoing template instantiation. /// /// The top of this stack is used by a fixit instantiating unresolved /// function calls to fix the AST to match the textual change it prints. llvm::SmallVector<CallExpr *, 8> CallsUndergoingInstantiation; - + + /// \brief For each declaration that involved template argument deduction, the + /// set of diagnostics that were suppressed during that template argument + /// deduction. + /// + /// FIXME: Serialize this structure to the AST file. + llvm::DenseMap<Decl *, llvm::SmallVector<PartialDiagnosticAt, 1> > + SuppressedDiagnostics; + /// \brief A stack object to be created when performing template /// instantiation. /// @@ -3331,6 +3967,7 @@ public: const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, ActiveTemplateInstantiation::InstantiationKind Kind, + sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); /// \brief Note that we are instantiating as part of template @@ -3340,6 +3977,7 @@ public: ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, + sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, @@ -3351,14 +3989,14 @@ public: /// \brief Note that we are substituting prior template arguments into a /// non-type or template template parameter. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, + NamedDecl *Template, NonTypeTemplateParmDecl *Param, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, SourceRange InstantiationRange); InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, + NamedDecl *Template, TemplateTemplateParmDecl *Param, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, @@ -3386,7 +4024,7 @@ public: private: Sema &SemaRef; bool Invalid; - + bool SavedInNonInstantiationSFINAEContext; bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, SourceRange InstantiationRange); @@ -3402,21 +4040,39 @@ public: /// template argument substitution failures are not considered /// errors. /// - /// When this routine returns true, the emission of most diagnostics - /// will be suppressed and there will be no local error recovery. - bool isSFINAEContext() const; + /// \returns An empty \c llvm::Optional if we're not in a SFINAE context. + /// Otherwise, contains a pointer that, if non-NULL, contains the nearest + /// template-deduction context object, which can be used to capture + /// diagnostics that will be suppressed. + llvm::Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const; /// \brief RAII class used to determine whether SFINAE has /// trapped any errors that occur during template argument - /// deduction. + /// deduction.` class SFINAETrap { Sema &SemaRef; unsigned PrevSFINAEErrors; + bool PrevInNonInstantiationSFINAEContext; + bool PrevAccessCheckingSFINAE; + public: - explicit SFINAETrap(Sema &SemaRef) - : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors) { } + explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false) + : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors), + PrevInNonInstantiationSFINAEContext( + SemaRef.InNonInstantiationSFINAEContext), + PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE) + { + if (!SemaRef.isSFINAEContext()) + SemaRef.InNonInstantiationSFINAEContext = true; + SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE; + } - ~SFINAETrap() { SemaRef.NumSFINAEErrors = PrevSFINAEErrors; } + ~SFINAETrap() { + SemaRef.NumSFINAEErrors = PrevSFINAEErrors; + SemaRef.InNonInstantiationSFINAEContext + = PrevInNonInstantiationSFINAEContext; + SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE; + } /// \brief Determine whether any SFINAE errors have been trapped. bool hasErrorOccurred() const { @@ -3424,24 +4080,6 @@ public: } }; - /// \brief RAII class that determines when any errors have occurred - /// between the time the instance was created and the time it was - /// queried. - class ErrorTrap { - Sema &SemaRef; - unsigned PrevErrors; - - public: - explicit ErrorTrap(Sema &SemaRef) - : SemaRef(SemaRef), PrevErrors(SemaRef.getDiagnostics().getNumErrors()) {} - - /// \brief Determine whether any errors have occurred since this - /// object instance was created. - bool hasErrorOccurred() const { - return SemaRef.getDiagnostics().getNumErrors() > PrevErrors; - } - }; - /// \brief The current instantiation scope used to store local /// variables. LocalInstantiationScope *CurrentInstantiationScope; @@ -3449,6 +4087,17 @@ public: /// \brief The number of typos corrected by CorrectTypo. unsigned TyposCorrected; + typedef llvm::DenseMap<IdentifierInfo *, std::pair<llvm::StringRef, bool> > + UnqualifiedTyposCorrectedMap; + + /// \brief A cache containing the results of typo correction for unqualified + /// name lookup. + /// + /// The string is the string that we corrected to (which may be empty, if + /// there was no correction), while the boolean will be true when the + /// string represents a keyword. + UnqualifiedTyposCorrectedMap UnqualifiedTyposCorrected; + /// \brief Worker object for performing CFG-based warnings. sema::AnalysisBasedWarnings AnalysisWarnings; @@ -3485,14 +4134,43 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity); + TypeSourceInfo *SubstType(TypeLoc TL, + const MultiLevelTemplateArgumentList &TemplateArgs, + SourceLocation Loc, DeclarationName Entity); + TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity); ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, - const MultiLevelTemplateArgumentList &TemplateArgs); + const MultiLevelTemplateArgumentList &TemplateArgs, + llvm::Optional<unsigned> NumExpansions); + bool SubstParmTypes(SourceLocation Loc, + ParmVarDecl **Params, unsigned NumParams, + const MultiLevelTemplateArgumentList &TemplateArgs, + llvm::SmallVectorImpl<QualType> &ParamTypes, + llvm::SmallVectorImpl<ParmVarDecl *> *OutParams = 0); ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); + + /// \brief Substitute the given template arguments into a list of + /// expressions, expanding pack expansions if required. + /// + /// \param Exprs The list of expressions to substitute into. + /// + /// \param NumExprs The number of expressions in \p Exprs. + /// + /// \param IsCall Whether this is some form of call, in which case + /// default arguments will be dropped. + /// + /// \param TemplateArgs The set of template arguments to substitute. + /// + /// \param Outputs Will receive all of the substituted arguments. + /// + /// \returns true if an error occurred, false otherwise. + bool SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall, + const MultiLevelTemplateArgumentList &TemplateArgs, + llvm::SmallVectorImpl<Expr *> &Outputs); StmtResult SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -3541,7 +4219,8 @@ public: TemplateName SubstTemplateName(TemplateName Name, SourceLocation Loc, const MultiLevelTemplateArgumentList &TemplateArgs); - bool Subst(const TemplateArgumentLoc &Arg, TemplateArgumentLoc &Result, + bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs, + TemplateArgumentListInfo &Result, const MultiLevelTemplateArgumentList &TemplateArgs); void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, @@ -3636,7 +4315,19 @@ public: void CheckObjCPropertyAttributes(Decl *PropertyPtrTy, SourceLocation Loc, unsigned &Attributes); - void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC); + + /// 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 redeclaredProperty Declaration for property if redeclared + /// in class extension. + /// \param lexicalDC Container for redeclaredProperty. + void ProcessPropertyDecl(ObjCPropertyDecl *property, + ObjCContainerDecl *DC, + ObjCPropertyDecl *redeclaredProperty = 0, + ObjCContainerDecl *lexicalDC = 0); + void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, ObjCPropertyDecl *SuperProperty, const IdentifierInfo *Name); @@ -3664,14 +4355,16 @@ public: Selector GetterSel, Selector SetterSel, Decl *ClassCategory, bool *OverridingProperty, - tok::ObjCKeywordKind MethodImplKind); + tok::ObjCKeywordKind MethodImplKind, + DeclContext *lexicalDC = 0); Decl *ActOnPropertyImplDecl(Scope *S, SourceLocation AtLoc, SourceLocation PropertyLoc, bool ImplKind,Decl *ClassImplDecl, IdentifierInfo *PropertyId, - IdentifierInfo *PropertyIvar); + IdentifierInfo *PropertyIvar, + SourceLocation PropertyIvarLoc); struct ObjCArgInfo { IdentifierInfo *Name; @@ -3686,6 +4379,7 @@ public: }; Decl *ActOnMethodDeclaration( + Scope *S, SourceLocation BeginLoc, // location of the + or -. SourceLocation EndLoc, // location of the ; or {. tok::TokenKind MethodType, @@ -3711,7 +4405,9 @@ public: HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, DeclarationName MemberName, - SourceLocation MemberLoc); + SourceLocation MemberLoc, + SourceLocation SuperLoc, QualType SuperType, + bool Super); ExprResult ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, @@ -3719,6 +4415,8 @@ public: SourceLocation receiverNameLoc, SourceLocation propertyNameLoc); + ObjCMethodDecl *tryCaptureObjCSelf(); + /// \brief Describes the kind of message expression indicated by a message /// send that starts with an identifier. enum ObjCMessageKind { @@ -3751,6 +4449,7 @@ public: Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, + SourceLocation SelectorLoc, SourceLocation RBracLoc, MultiExprArg Args); @@ -3768,6 +4467,7 @@ public: Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, + SourceLocation SelectorLoc, SourceLocation RBracLoc, MultiExprArg Args); @@ -3810,11 +4510,9 @@ public: SourceLocation RParenLoc); /// ActOnPragmaUnused - Called on well-formed '#pragma unused'. - void ActOnPragmaUnused(const Token *Identifiers, - unsigned NumIdentifiers, Scope *curScope, - SourceLocation PragmaLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc); + void ActOnPragmaUnused(const Token &Identifier, + Scope *curScope, + SourceLocation PragmaLoc); /// ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... . void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType, @@ -3835,6 +4533,10 @@ public: SourceLocation WeakNameLoc, SourceLocation AliasNameLoc); + /// ActOnPragmaFPContract - Called on well formed + /// #pragma {STDC,OPENCL} FP_CONTRACT + void ActOnPragmaFPContract(tok::OnOffSwitch OOS); + /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to /// a the record decl, to handle '#pragma pack' and '#pragma options align'. void AddAlignmentAttributesForRecord(RecordDecl *RD); @@ -3842,9 +4544,9 @@ public: /// FreePackedContext - Deallocate and null out PackContext. void FreePackedContext(); - /// PushVisibilityAttr - Note that we've entered a context with a - /// visibility attribute. - void PushVisibilityAttr(const VisibilityAttr *Attr); + /// PushNamespaceVisibilityAttr - Note that we've entered a + /// namespace with a visibility attribute. + void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr); /// AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used, /// add an appropriate visibility attribute. @@ -3872,6 +4574,11 @@ public: ExprValueKind VK = VK_RValue, const CXXCastPath *BasePath = 0); + /// IgnoredValueConversions - Given that an expression's result is + /// syntactically ignored, perform any conversions that are + /// required. + void IgnoredValueConversions(Expr *&expr); + // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts // functions and arrays to their respective pointers (C99 6.3.2.1). Expr *UsualUnaryConversions(Expr *&expr); @@ -3885,6 +4592,12 @@ public: // lvalue-to-rvalue conversion. void DefaultFunctionArrayLvalueConversion(Expr *&expr); + // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on + // the operand. This is DefaultFunctionArrayLvalueConversion, + // except that it assumes the operand isn't of function or array + // type. + void DefaultLvalueConversion(Expr *&expr); + // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that // do not have a prototype. Integer promotions are performed on each // argument, and arguments that have type float are promoted to double. @@ -3957,6 +4670,11 @@ public: /// c/v/r qualifiers, which we accept as an extension. CompatiblePointerDiscardsQualifiers, + /// IncompatiblePointerDiscardsQualifiers - The assignment + /// discards qualifiers that we don't permit to be discarded, + /// like address spaces. + IncompatiblePointerDiscardsQualifiers, + /// IncompatibleNestedPointerQualifiers - The assignment is between two /// nested pointer types, and the qualifiers other than the first two /// levels differ e.g. char ** -> const char **, but we accept them as an @@ -3996,8 +4714,14 @@ public: /// CheckAssignmentConstraints - Perform type checking for assignment, /// argument passing, variable initialization, and function return values. - /// This routine is only used by the following two methods. C99 6.5.16. - AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs); + /// C99 6.5.16. + AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, + QualType lhs, QualType rhs); + + /// Check assignment constraints and prepare for a conversion of the + /// RHS to the LHS type. + AssignConvertType CheckAssignmentConstraints(QualType lhs, Expr *&rhs, + CastKind &Kind); // CheckSingleAssignmentConstraints - Currently used by // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, @@ -4010,18 +4734,6 @@ public: AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs, Expr *&rExpr); - // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1) - AssignConvertType CheckPointerTypesForAssignment(QualType lhsType, - QualType rhsType); - - AssignConvertType CheckObjCPointerTypesForAssignment(QualType lhsType, - QualType rhsType); - - // Helper function for CheckAssignmentConstraints involving two - // block pointer types. - AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType, - QualType rhsType); - bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType); bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType); @@ -4036,10 +4748,11 @@ public: bool PerformImplicitConversion(Expr *&From, QualType ToType, const ImplicitConversionSequence& ICS, AssignmentAction Action, - bool IgnoreBaseAccess = false); + bool CStyle = false); bool PerformImplicitConversion(Expr *&From, QualType ToType, const StandardConversionSequence& SCS, - AssignmentAction Action,bool IgnoreBaseAccess); + AssignmentAction Action, + bool CStyle); /// the following "Check" methods will return a valid/converted QualType /// or a null QualType (indicating an error diagnostic was issued). @@ -4047,7 +4760,8 @@ public: /// type checking binary operators (subroutines of CreateBuiltinBinOp). QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex); QualType CheckPointerToMemberOperands( // C++ 5.5 - Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect); + Expr *&lex, Expr *&rex, ExprValueKind &VK, + SourceLocation OpLoc, bool isIndirect); QualType CheckMultiplyDivideOperands( // C99 6.5.5 Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign, bool isDivide); @@ -4071,36 +4785,30 @@ public: // For compound assignment, pass both expressions and the converted type. QualType CheckAssignmentOperands( // C99 6.5.16.[1,2] Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType); - QualType CheckCommaOperands( // C99 6.5.17 - Expr *lex, Expr *&rex, SourceLocation OpLoc); + + void ConvertPropertyForRValue(Expr *&E); + void ConvertPropertyForLValue(Expr *&LHS, Expr *&RHS, QualType& LHSTy); + QualType CheckConditionalOperands( // C99 6.5.15 - Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc); + Expr *&cond, Expr *&lhs, Expr *&rhs, + ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); QualType CXXCheckConditionalOperands( // C++ 5.16 - Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc); + Expr *&cond, Expr *&lhs, Expr *&rhs, + ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc); QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, bool *NonStandardCompositeType = 0); QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS, SourceLocation questionLoc); + bool DiagnoseConditionalForNull(Expr *LHS, Expr *RHS, + SourceLocation QuestionLoc); + /// type checking for vector binary operators. QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex); QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx, SourceLocation l, bool isRel); - /// type checking unary operators (subroutines of ActOnUnaryOp). - /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4 - QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc, - bool isInc, bool isPrefix); - QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc); - QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc); - QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc, bool isReal); - - /// type checking primary expressions. - QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc, - const IdentifierInfo *Comp, - SourceLocation CmpLoc); - /// type checking declaration initializers (C99 6.7.8) bool CheckInitList(const InitializedEntity &Entity, InitListExpr *&InitList, QualType &DeclType); @@ -4137,7 +4845,7 @@ public: /// CheckCastTypes - Check type constraints for casting between types under /// C semantics, or forward to CXXCheckCStyleCast in C++. bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, CXXCastPath &BasePath, + CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath, bool FunctionalStyle = false); // CheckVectorCast - check type constraints for vectors. @@ -4157,9 +4865,9 @@ public: /// CXXCheckCStyleCast - Check constraints of a C-style or function-style /// cast under C++ semantics. - bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, CXXCastPath &BasePath, - bool FunctionalStyle); + bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, + Expr *&CastExpr, CastKind &Kind, + CXXCastPath &BasePath, bool FunctionalStyle); /// CheckMessageArgumentTypes - Check types in an Obj-C message send. /// \param Method - May be null. @@ -4168,7 +4876,7 @@ public: bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel, ObjCMethodDecl *Method, bool isClassMessage, SourceLocation lbrac, SourceLocation rbrac, - QualType &ReturnType); + QualType &ReturnType, ExprValueKind &VK); /// CheckBooleanCondition - Diagnose problems involving the use of /// the given expression as a boolean condition (e.g. in an if @@ -4187,6 +4895,10 @@ public: /// being used as a boolean condition, warn if it's an assignment. void DiagnoseAssignmentAsCondition(Expr *E); + /// \brief Redundant parentheses over an equality comparison can indicate + /// that the user intended an assignment used as condition. + void DiagnoseEqualityWithExtraParens(ParenExpr *parenE); + /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. bool CheckCXXBooleanCondition(Expr *&CondExpr); @@ -4202,8 +4914,6 @@ public: /// in the global scope. bool CheckObjCDeclScope(Decl *D); - void InitBuiltinVaListType(); - /// 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. @@ -4256,14 +4966,20 @@ public: /// in the grammar. PCC_RecoveryInFunction, /// \brief Code completion occurs where only a type is permitted. - PCC_Type + PCC_Type, + /// \brief Code completion occurs in a parenthesized expression, which + /// might also be a type cast. + PCC_ParenthesizedExpression, + /// \brief Code completion occurs within a sequence of declaration + /// specifiers within a function, method, or block. + PCC_LocalDeclarationSpecifiers }; void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext); - void CodeCompleteDeclarator(Scope *S, - bool AllowNonIdentifiers, - bool AllowNestedNameSpecifiers); + void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, + bool AllowNonIdentifiers, + bool AllowNestedNameSpecifiers); struct CodeCompleteExpressionData; void CodeCompleteExpression(Scope *S, @@ -4271,6 +4987,7 @@ public: void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool IsArrow); + void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); void CodeCompleteCase(Scope *S); @@ -4287,7 +5004,7 @@ public: void CodeCompleteNamespaceAliasDecl(Scope *S); void CodeCompleteOperatorName(Scope *S); void CodeCompleteConstructorInitializer(Decl *Constructor, - CXXBaseOrMemberInitializer** Initializers, + CXXCtorInitializer** Initializers, unsigned NumInitializers); void CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl, @@ -4296,31 +5013,25 @@ public: void CodeCompleteObjCAtStatement(Scope *S); void CodeCompleteObjCAtExpression(Scope *S); void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS); - void CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl, - Decl **Methods, - unsigned NumMethods); - void CodeCompleteObjCPropertySetter(Scope *S, Decl *ClassDecl, - Decl **Methods, - unsigned NumMethods); - void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS); + void CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl); + void CodeCompleteObjCPropertySetter(Scope *S, Decl *ClassDecl); + void CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, + bool IsParameter); void CodeCompleteObjCMessageReceiver(Scope *S); void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, IdentifierInfo **SelIdents, - unsigned NumSelIdents); - void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, - IdentifierInfo **SelIdents, - unsigned NumSelIdents); + unsigned NumSelIdents, + bool AtArgumentExpression); void CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, IdentifierInfo **SelIdents, unsigned NumSelIdents, - bool IsSuper); + bool AtArgumentExpression, + bool IsSuper = false); void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, IdentifierInfo **SelIdents, - unsigned NumSelIdents); - void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, - IdentifierInfo **SelIdents, - unsigned NumSelIdents, - bool IsSuper); + unsigned NumSelIdents, + bool AtArgumentExpression, + ObjCInterfaceDecl *Super = 0); void CodeCompleteObjCForCollection(Scope *S, DeclGroupPtrTy IterationVar); void CodeCompleteObjCSelector(Scope *S, @@ -4363,7 +5074,7 @@ public: MacroInfo *MacroInfo, unsigned Argument); void CodeCompleteNaturalLanguage(); - void GatherGlobalCodeCompletions( + void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, llvm::SmallVectorImpl<CodeCompletionResult> &Results); //@} @@ -4376,7 +5087,8 @@ public: SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const; -private: +private: + void CheckArrayAccess(const ArraySubscriptExpr *E); bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall); @@ -4385,7 +5097,6 @@ private: ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); @@ -4422,7 +5133,10 @@ private: void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc); void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex); - void CheckImplicitConversions(Expr *E); + void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); + + void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field, + Expr *Init); /// \brief The parser's current scope. /// @@ -4431,6 +5145,7 @@ private: protected: friend class Parser; + friend class InitializationSequence; /// \brief Retrieve the parser's current scope. Scope *getCurScope() const { return CurScope; } diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index a5a1364..ae5aa33 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" #undef DIAG diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index a7b3b84..53f4a9d 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -13,8 +13,10 @@ #define LLVM_CLANG_SEMA_TEMPLATE_H #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclVisitor.h" #include "llvm/ADT/SmallVector.h" #include <cassert> +#include <utility> namespace clang { /// \brief Data structure that captures multiple levels of template argument @@ -79,12 +81,21 @@ namespace clang { return !(*this)(Depth, Index).isNull(); } + /// \brief Clear out a specific template argument. + void setArgument(unsigned Depth, unsigned Index, + TemplateArgument Arg) { + assert(Depth < TemplateArgumentLists.size()); + assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second); + const_cast<TemplateArgument&>( + TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index]) + = Arg; + } + /// \brief Add a new outermost level to the multi-level template argument /// list. void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { - TemplateArgumentLists.push_back( - ArgList(TemplateArgs->getFlatArgumentList(), - TemplateArgs->flat_size())); + TemplateArgumentLists.push_back(ArgList(TemplateArgs->data(), + TemplateArgs->size())); } /// \brief Add a new outmost level to the multi-level template argument @@ -140,7 +151,7 @@ namespace clang { : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { } /// \brief Construct an integral non-type template argument that - /// has been deduced, possible from an array bound. + /// has been deduced, possibly from an array bound. DeducedTemplateArgument(const llvm::APSInt &Value, QualType ValueType, bool DeducedFromArrayBound) @@ -165,10 +176,19 @@ namespace clang { /// instantiate a new function declaration, which will have its own /// set of parameter declarations. class LocalInstantiationScope { + public: + /// \brief A set of declarations. + typedef llvm::SmallVector<Decl *, 4> DeclArgumentPack; + + private: /// \brief Reference to the semantic analysis that is performing /// this template instantiation. Sema &SemaRef; + typedef llvm::DenseMap<const Decl *, + llvm::PointerUnion<Decl *, DeclArgumentPack *> > + LocalDeclsMap; + /// \brief A mapping from local declarations that occur /// within a template to their instantiations. /// @@ -183,8 +203,15 @@ namespace clang { /// when we instantiate add<int>, we will introduce a mapping from /// the ParmVarDecl for 'x' that occurs in the template to the /// instantiated ParmVarDecl for 'x'. - llvm::DenseMap<const Decl *, Decl *> LocalDecls; + /// + /// For a parameter pack, the local instantiation scope may contain a + /// set of instantiated parameters. This is stored as a DeclArgumentPack + /// pointer. + LocalDeclsMap LocalDecls; + /// \brief The set of argument packs we've allocated. + llvm::SmallVector<DeclArgumentPack *, 1> ArgumentPacks; + /// \brief The outer scope, which contains local variable /// definitions from some other instantiation (that may not be /// relevant to this particular scope). @@ -197,6 +224,19 @@ namespace clang { /// lookup will search our outer scope. bool CombineWithOuterScope; + /// \brief If non-NULL, the template parameter pack that has been + /// partially substituted per C++0x [temp.arg.explicit]p9. + NamedDecl *PartiallySubstitutedPack; + + /// \brief If \c PartiallySubstitutedPack is non-null, the set of + /// explicitly-specified template arguments in that pack. + const TemplateArgument *ArgsInPartiallySubstitutedPack; + + /// \brief If \c PartiallySubstitutedPack, the number of + /// explicitly-specified template arguments in + /// ArgsInPartiallySubstitutedPack. + unsigned NumArgsInPartiallySubstitutedPack; + // This class is non-copyable LocalInstantiationScope(const LocalInstantiationScope &); LocalInstantiationScope &operator=(const LocalInstantiationScope &); @@ -204,7 +244,8 @@ namespace clang { public: LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), - Exited(false), CombineWithOuterScope(CombineWithOuterScope) + Exited(false), CombineWithOuterScope(CombineWithOuterScope), + PartiallySubstitutedPack(0) { SemaRef.CurrentInstantiationScope = this; } @@ -212,33 +253,171 @@ namespace clang { ~LocalInstantiationScope() { Exit(); } + + const Sema &getSema() const { return SemaRef; } /// \brief Exit this local instantiation scope early. void Exit() { if (Exited) return; + for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) + delete ArgumentPacks[I]; + SemaRef.CurrentInstantiationScope = Outer; Exited = true; } - Decl *getInstantiationOf(const Decl *D); + /// \brief Find the instantiation of the declaration D within the current + /// instantiation scope. + /// + /// \param D The declaration whose instantiation we are searching for. + /// + /// \returns A pointer to the declaration or argument pack of declarations + /// to which the declaration \c D is instantiataed, if found. Otherwise, + /// returns NULL. + llvm::PointerUnion<Decl *, DeclArgumentPack *> * + findInstantiationOf(const Decl *D); + + void InstantiatedLocal(const Decl *D, Decl *Inst); + void InstantiatedLocalPackArg(const Decl *D, Decl *Inst); + void MakeInstantiatedLocalArgPack(const Decl *D); + + /// \brief Note that the given parameter pack has been partially substituted + /// via explicit specification of template arguments + /// (C++0x [temp.arg.explicit]p9). + /// + /// \param Pack The parameter pack, which will always be a template + /// parameter pack. + /// + /// \param ExplicitArgs The explicitly-specified template arguments provided + /// for this parameter pack. + /// + /// \param NumExplicitArgs The number of explicitly-specified template + /// arguments provided for this parameter pack. + void SetPartiallySubstitutedPack(NamedDecl *Pack, + const TemplateArgument *ExplicitArgs, + unsigned NumExplicitArgs); + + /// \brief Retrieve the partially-substitued template parameter pack. + /// + /// If there is no partially-substituted parameter pack, returns NULL. + NamedDecl *getPartiallySubstitutedPack( + const TemplateArgument **ExplicitArgs = 0, + unsigned *NumExplicitArgs = 0) const; + }; + + class TemplateDeclInstantiator + : public DeclVisitor<TemplateDeclInstantiator, Decl *> + { + Sema &SemaRef; + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; + DeclContext *Owner; + const MultiLevelTemplateArgumentList &TemplateArgs; - VarDecl *getInstantiationOf(const VarDecl *Var) { - return cast<VarDecl>(getInstantiationOf(cast<Decl>(Var))); + /// \brief A list of out-of-line class template partial + /// specializations that will need to be instantiated after the + /// enclosing class's instantiation is complete. + llvm::SmallVector<std::pair<ClassTemplateDecl *, + ClassTemplatePartialSpecializationDecl *>, 4> + OutOfLinePartialSpecs; + + public: + TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, + const MultiLevelTemplateArgumentList &TemplateArgs) + : SemaRef(SemaRef), SubstIndex(SemaRef, -1), Owner(Owner), + TemplateArgs(TemplateArgs) { } + + // FIXME: Once we get closer to completion, replace these manually-written + // declarations with automatically-generated ones from + // clang/AST/DeclNodes.inc. + Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); + Decl *VisitLabelDecl(LabelDecl *D); + Decl *VisitNamespaceDecl(NamespaceDecl *D); + Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); + Decl *VisitTypedefDecl(TypedefDecl *D); + Decl *VisitVarDecl(VarDecl *D); + Decl *VisitAccessSpecDecl(AccessSpecDecl *D); + Decl *VisitFieldDecl(FieldDecl *D); + Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); + Decl *VisitStaticAssertDecl(StaticAssertDecl *D); + Decl *VisitEnumDecl(EnumDecl *D); + Decl *VisitEnumConstantDecl(EnumConstantDecl *D); + Decl *VisitFriendDecl(FriendDecl *D); + Decl *VisitFunctionDecl(FunctionDecl *D, + TemplateParameterList *TemplateParams = 0); + Decl *VisitCXXRecordDecl(CXXRecordDecl *D); + Decl *VisitCXXMethodDecl(CXXMethodDecl *D, + TemplateParameterList *TemplateParams = 0); + Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D); + Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); + Decl *VisitCXXConversionDecl(CXXConversionDecl *D); + ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D); + Decl *VisitClassTemplateDecl(ClassTemplateDecl *D); + Decl *VisitClassTemplatePartialSpecializationDecl( + ClassTemplatePartialSpecializationDecl *D); + Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); + Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); + Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); + Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); + Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); + Decl *VisitUsingDecl(UsingDecl *D); + Decl *VisitUsingShadowDecl(UsingShadowDecl *D); + Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); + Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); + + // Base case. FIXME: Remove once we can instantiate everything. + Decl *VisitDecl(Decl *D) { + unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID( + Diagnostic::Error, + "cannot instantiate %0 yet"); + SemaRef.Diag(D->getLocation(), DiagID) + << D->getDeclKindName(); + + return 0; } + + typedef + llvm::SmallVectorImpl<std::pair<ClassTemplateDecl *, + ClassTemplatePartialSpecializationDecl *> > + ::iterator + delayed_partial_spec_iterator; - ParmVarDecl *getInstantiationOf(const ParmVarDecl *Var) { - return cast<ParmVarDecl>(getInstantiationOf(cast<Decl>(Var))); + /// \brief Return an iterator to the beginning of the set of + /// "delayed" partial specializations, which must be passed to + /// InstantiateClassTemplatePartialSpecialization once the class + /// definition has been completed. + delayed_partial_spec_iterator delayed_partial_spec_begin() { + return OutOfLinePartialSpecs.begin(); } - NonTypeTemplateParmDecl *getInstantiationOf( - const NonTypeTemplateParmDecl *Var) { - return cast<NonTypeTemplateParmDecl>(getInstantiationOf(cast<Decl>(Var))); + /// \brief Return an iterator to the end of the set of + /// "delayed" partial specializations, which must be passed to + /// InstantiateClassTemplatePartialSpecialization once the class + /// definition has been completed. + delayed_partial_spec_iterator delayed_partial_spec_end() { + return OutOfLinePartialSpecs.end(); } - void InstantiatedLocal(const Decl *D, Decl *Inst); - }; + // Helper functions for instantiating methods. + TypeSourceInfo *SubstFunctionType(FunctionDecl *D, + llvm::SmallVectorImpl<ParmVarDecl *> &Params); + bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); + bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); + + TemplateParameterList * + SubstTemplateParams(TemplateParameterList *List); + + bool SubstQualifier(const DeclaratorDecl *OldDecl, + DeclaratorDecl *NewDecl); + bool SubstQualifier(const TagDecl *OldDecl, + TagDecl *NewDecl); + + ClassTemplatePartialSpecializationDecl * + InstantiateClassTemplatePartialSpecialization( + ClassTemplateDecl *ClassTemplate, + ClassTemplatePartialSpecializationDecl *PartialSpec); + }; } #endif // LLVM_CLANG_SEMA_TEMPLATE_H diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index ac32e9c..7cc3571 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -13,7 +13,9 @@ #ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H #define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H +#include "clang/Basic/PartialDiagnostic.h" #include "clang/AST/DeclTemplate.h" +#include "llvm/ADT/SmallVector.h" namespace clang { @@ -21,7 +23,7 @@ class ASTContext; class TemplateArgumentList; namespace sema { - + /// \brief Provides information about an attempted template argument /// deduction, whose success or failure was described by a /// TemplateDeductionResult value. @@ -37,6 +39,10 @@ class TemplateDeductionInfo { /// deduction is occurring. SourceLocation Loc; + /// \brief Warnings (and follow-on notes) that were suppressed due to + /// SFINAE while performing template argument deduction. + llvm::SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; + // do not implement these TemplateDeductionInfo(const TemplateDeductionInfo&); TemplateDeductionInfo &operator=(const TemplateDeductionInfo&); @@ -69,6 +75,23 @@ public: Deduced = NewDeduced; } + /// \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)); + } + + /// \brief Iterator over the set of suppressed diagnostics. + typedef llvm::SmallVectorImpl<PartialDiagnosticAt>::const_iterator + diag_iterator; + + /// \brief Returns an iterator at the beginning of the sequence of suppressed + /// diagnostics. + diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); } + + /// \brief Returns an iterator at the end of the sequence of suppressed + /// diagnostics. + diag_iterator diag_end() const { return SuppressedDiagnostics.end(); } + /// \brief The template parameter to which a template argument /// deduction failure refers. /// |