diff options
Diffstat (limited to 'include/clang/Sema')
| -rw-r--r-- | include/clang/Sema/AnalysisBasedWarnings.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/AttributeList.h | 15 | ||||
| -rw-r--r-- | include/clang/Sema/DeclSpec.h | 58 | ||||
| -rw-r--r-- | include/clang/Sema/DelayedDiagnostic.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/ExternalSemaSource.h | 17 | ||||
| -rw-r--r-- | include/clang/Sema/IdentifierResolver.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/Lookup.h | 27 | ||||
| -rw-r--r-- | include/clang/Sema/LoopHint.h | 13 | ||||
| -rw-r--r-- | include/clang/Sema/MultiplexExternalSemaSource.h | 15 | ||||
| -rw-r--r-- | include/clang/Sema/ObjCMethodList.h | 31 | ||||
| -rw-r--r-- | include/clang/Sema/Overload.h | 36 | ||||
| -rw-r--r-- | include/clang/Sema/PrettyDeclStackTrace.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/Scope.h | 20 | ||||
| -rw-r--r-- | include/clang/Sema/ScopeInfo.h | 41 | ||||
| -rw-r--r-- | include/clang/Sema/Sema.h | 485 | ||||
| -rw-r--r-- | include/clang/Sema/SemaDiagnostic.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/SemaFixItUtils.h | 6 | ||||
| -rw-r--r-- | include/clang/Sema/SemaInternal.h | 212 | ||||
| -rw-r--r-- | include/clang/Sema/SemaLambda.h | 6 | ||||
| -rw-r--r-- | include/clang/Sema/TemplateDeduction.h | 4 | ||||
| -rw-r--r-- | include/clang/Sema/TypoCorrection.h | 42 |
21 files changed, 824 insertions, 224 deletions
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h index 432c4e23a993..64dd2d36bef8 100644 --- a/include/clang/Sema/AnalysisBasedWarnings.h +++ b/include/clang/Sema/AnalysisBasedWarnings.h @@ -11,8 +11,8 @@ // that issues warnings based on dataflow-analysis. //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H -#define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H +#ifndef LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H +#define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H #include "llvm/ADT/DenseMap.h" diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index c21c19fd55c9..dc85f5d2084c 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_ATTRLIST_H -#define LLVM_CLANG_SEMA_ATTRLIST_H +#ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H +#define LLVM_CLANG_SEMA_ATTRIBUTELIST_H #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" @@ -94,10 +94,10 @@ private: /// The number of expression arguments this attribute has. /// The expressions themselves are stored after the object. - unsigned NumArgs : 16; + unsigned NumArgs : 15; /// Corresponds to the Syntax enum. - unsigned SyntaxUsed : 2; + unsigned SyntaxUsed : 3; /// True if already diagnosed as invalid. mutable unsigned Invalid : 1; @@ -455,6 +455,7 @@ public: bool hasCustomParsing() const; unsigned getMinArgs() const; unsigned getMaxArgs() const; + bool hasVariadicArg() const; bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; bool diagnoseLangOpts(class Sema &S) const; bool existsInTarget(const llvm::Triple &T) const; @@ -821,12 +822,13 @@ enum AttributeDeclKind { ExpectedFunctionMethodOrClass, ExpectedFunctionMethodOrParameter, ExpectedClass, + ExpectedEnum, ExpectedVariable, ExpectedMethod, ExpectedVariableFunctionOrLabel, ExpectedFieldOrGlobalVar, ExpectedStruct, - ExpectedVariableFunctionOrTag, + ExpectedVariableOrTypedef, ExpectedTLSVar, ExpectedVariableOrField, ExpectedVariableFieldOrTag, @@ -842,7 +844,8 @@ enum AttributeDeclKind { ExpectedObjectiveCProtocol, ExpectedFunctionGlobalVarMethodOrProperty, ExpectedStructOrTypedef, - ExpectedObjectiveCInterfaceOrProtocol + ExpectedObjectiveCInterfaceOrProtocol, + ExpectedKernelFunction }; } // end namespace clang diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 8364dfc4b0bb..d36882660298 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -37,6 +37,7 @@ namespace clang { class ASTContext; + class CXXRecordDecl; class TypeLoc; class LangOptions; class DiagnosticsEngine; @@ -141,6 +142,22 @@ public: /// nested-name-specifier '::'. void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); + /// \brief Turns this (empty) nested-name-specifier into '__super' + /// nested-name-specifier. + /// + /// \param Context The AST context in which this nested-name-specifier + /// resides. + /// + /// \param RD The declaration of the class in which nested-name-specifier + /// appeared. + /// + /// \param SuperLoc The location of the '__super' keyword. + /// name. + /// + /// \param ColonColonLoc The location of the trailing '::'. + void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, + SourceLocation SuperLoc, SourceLocation ColonColonLoc); + /// \brief Make a new nested-name-specifier from incomplete source-location /// information. /// @@ -1053,6 +1070,12 @@ struct DeclaratorChunk { /// EndLoc - If valid, the place where this chunck ends. SourceLocation EndLoc; + SourceRange getSourceRange() const { + if (EndLoc.isInvalid()) + return SourceRange(Loc, Loc); + return SourceRange(Loc, EndLoc); + } + struct TypeInfoCommon { AttributeList *AttrList; }; @@ -1159,7 +1182,7 @@ struct DeclaratorChunk { unsigned TypeQuals : 3; /// ExceptionSpecType - An ExceptionSpecificationType value. - unsigned ExceptionSpecType : 3; + unsigned ExceptionSpecType : 4; /// DeleteParams - If this is true, we need to delete[] Params. unsigned DeleteParams : 1; @@ -1200,6 +1223,11 @@ struct DeclaratorChunk { /// If this is an invalid location, there is no volatile-qualifier. unsigned VolatileQualifierLoc; + /// \brief The location of the restrict-qualifier, if any. + /// + /// If this is an invalid location, there is no restrict-qualifier. + unsigned RestrictQualifierLoc; + /// \brief The location of the 'mutable' qualifer in a lambda-declarator, if /// any. unsigned MutableLoc; @@ -1221,6 +1249,10 @@ struct DeclaratorChunk { /// \brief Pointer to the expression in the noexcept-specifier of this /// function, if it has one. Expr *NoexceptExpr; + + /// \brief Pointer to the cached tokens for an exception-specification + /// that has not yet been parsed. + CachedTokens *ExceptionSpecTokens; }; /// \brief If HasTrailingReturnType is true, this is the trailing return @@ -1247,6 +1279,8 @@ struct DeclaratorChunk { delete[] Params; if (getExceptionSpecType() == EST_Dynamic) delete[] Exceptions; + else if (getExceptionSpecType() == EST_Unparsed) + delete ExceptionSpecTokens; } /// isKNRPrototype - Return true if this is a K&R style identifier list, @@ -1275,16 +1309,21 @@ struct DeclaratorChunk { return SourceLocation::getFromRawEncoding(RefQualifierLoc); } - /// \brief Retrieve the location of the ref-qualifier, if any. + /// \brief Retrieve the location of the 'const' qualifier, if any. SourceLocation getConstQualifierLoc() const { return SourceLocation::getFromRawEncoding(ConstQualifierLoc); } - /// \brief Retrieve the location of the ref-qualifier, if any. + /// \brief Retrieve the location of the 'volatile' qualifier, if any. SourceLocation getVolatileQualifierLoc() const { return SourceLocation::getFromRawEncoding(VolatileQualifierLoc); } + /// \brief Retrieve the location of the 'restrict' qualifier, if any. + SourceLocation getRestrictQualifierLoc() const { + return SourceLocation::getFromRawEncoding(RestrictQualifierLoc); + } + /// \brief Retrieve the location of the 'mutable' qualifier, if any. SourceLocation getMutableLoc() const { return SourceLocation::getFromRawEncoding(MutableLoc); @@ -1429,6 +1468,7 @@ struct DeclaratorChunk { SourceLocation RefQualifierLoc, SourceLocation ConstQualifierLoc, SourceLocation VolatileQualifierLoc, + SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceLocation ESpecLoc, @@ -1436,6 +1476,7 @@ struct DeclaratorChunk { SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, + CachedTokens *ExceptionSpecTokens, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, @@ -1458,7 +1499,8 @@ struct DeclaratorChunk { SourceLocation Loc) { DeclaratorChunk I; I.Kind = MemberPointer; - I.Loc = Loc; + I.Loc = SS.getBeginLoc(); + I.EndLoc = Loc; I.Mem.TypeQuals = TypeQuals; I.Mem.AttrList = nullptr; new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS); @@ -1881,6 +1923,14 @@ public: return DeclTypeInfo[i]; } + typedef SmallVectorImpl<DeclaratorChunk>::const_iterator type_object_iterator; + typedef llvm::iterator_range<type_object_iterator> type_object_range; + + /// Returns the range of type objects, from the identifier outwards. + type_object_range type_objects() const { + return type_object_range(DeclTypeInfo.begin(), DeclTypeInfo.end()); + } + void DropFirstTypeObject() { assert(!DeclTypeInfo.empty() && "No type chunks to drop."); DeclTypeInfo.front().destroy(); diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 85551f8db036..7fd6779f344d 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -19,8 +19,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H -#define LLVM_CLANG_SEMA_DELAYED_DIAGNOSTIC_H +#ifndef LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H +#define LLVM_CLANG_SEMA_DELAYEDDIAGNOSTIC_H #include "clang/Sema/Sema.h" diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 325abdf8e517..c0ef7121a6ee 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -10,8 +10,8 @@ // This file defines the ExternalSemaSource interface. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H -#define LLVM_CLANG_SEMA_EXTERNAL_SEMA_SOURCE_H +#ifndef LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H +#define LLVM_CLANG_SEMA_EXTERNALSEMASOURCE_H #include "clang/AST/ExternalASTSource.h" #include "clang/AST/Type.h" @@ -20,6 +20,10 @@ #include "llvm/ADT/MapVector.h" #include <utility> +namespace llvm { +template <class T, unsigned n> class SmallSetVector; +} + namespace clang { class CXXConstructorDecl; @@ -132,6 +136,15 @@ public: /// introduce the same declarations repeatedly. virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {} + /// \brief Read the set of potentially unused typedefs known to the source. + /// + /// The external source should append its own potentially unused local + /// typedefs to the given vector of declarations. Note that this routine may + /// be invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadUnusedLocalTypedefNameCandidates( + llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {}; + /// \brief Read the set of locally-scoped external declarations known to the /// external Sema source. /// diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h index b2404bc14b93..a07834f95629 100644 --- a/include/clang/Sema/IdentifierResolver.h +++ b/include/clang/Sema/IdentifierResolver.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H -#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H +#ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H +#define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/SmallVector.h" diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 00cc164d964c..1c6c7bbbd997 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -132,7 +132,7 @@ public: : ResultKind(NotFound), Paths(nullptr), NamingClass(nullptr), - SemaRef(SemaRef), + SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind), IDNS(0), @@ -154,7 +154,7 @@ public: : ResultKind(NotFound), Paths(nullptr), NamingClass(nullptr), - SemaRef(SemaRef), + SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind), IDNS(0), @@ -174,7 +174,7 @@ public: : ResultKind(NotFound), Paths(nullptr), NamingClass(nullptr), - SemaRef(Other.SemaRef), + SemaPtr(Other.SemaPtr), NameInfo(Other.NameInfo), LookupKind(Other.LookupKind), IDNS(Other.IDNS), @@ -305,7 +305,7 @@ public: if (!D->isInIdentifierNamespace(IDNS)) return nullptr; - if (isHiddenDeclarationVisible() || isVisible(SemaRef, D)) + if (isHiddenDeclarationVisible() || isVisible(getSema(), D)) return D; return getAcceptableDeclSlow(D); @@ -424,13 +424,20 @@ public: Paths = nullptr; } } else { - AmbiguityKind SavedAK = Ambiguity; + AmbiguityKind SavedAK; + bool WasAmbiguous = false; + if (ResultKind == Ambiguous) { + SavedAK = Ambiguity; + WasAmbiguous = true; + } ResultKind = Found; resolveKind(); // If we didn't make the lookup unambiguous, restore the old // ambiguity kind. if (ResultKind == Ambiguous) { + (void)WasAmbiguous; + assert(WasAmbiguous); Ambiguity = SavedAK; } else if (Paths) { deletePaths(Paths); @@ -544,7 +551,7 @@ public: /// \brief Get the Sema object that this lookup result is searching /// with. - Sema &getSema() const { return SemaRef; } + Sema &getSema() const { return *SemaPtr; } /// A class for iterating through a result set and possibly /// filtering out results. The results returned are possibly @@ -623,9 +630,9 @@ public: private: void diagnose() { if (isAmbiguous()) - SemaRef.DiagnoseAmbiguousLookup(*this); - else if (isClassLookup() && SemaRef.getLangOpts().AccessControl) - SemaRef.CheckLookupAccess(*this); + getSema().DiagnoseAmbiguousLookup(*this); + else if (isClassLookup() && getSema().getLangOpts().AccessControl) + getSema().CheckLookupAccess(*this); } void setAmbiguous(AmbiguityKind AK) { @@ -657,7 +664,7 @@ private: QualType BaseObjectType; // Parameters. - Sema &SemaRef; + Sema *SemaPtr; DeclarationNameInfo NameInfo; SourceRange NameContextRange; Sema::LookupNameKind LookupKind; diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h index d4b985df544c..c8b2ee845e59 100644 --- a/include/clang/Sema/LoopHint.h +++ b/include/clang/Sema/LoopHint.h @@ -26,13 +26,18 @@ struct LoopHint { // hints. IdentifierLoc *PragmaNameLoc; // Name of the loop hint. Examples: "unroll", "vectorize". In the - // "#pragma unroll" case, this is identical to PragmaNameLoc. + // "#pragma unroll" and "#pragma nounroll" cases, this is identical to + // PragmaNameLoc. IdentifierLoc *OptionLoc; - // Identifier for the hint argument. If null, then the hint has no argument - // such as for "#pragma unroll". - IdentifierLoc *ValueLoc; + // Identifier for the hint state argument. If null, then the state is + // default value such as for "#pragma unroll". + IdentifierLoc *StateLoc; // Expression for the hint argument if it exists, null otherwise. Expr *ValueExpr; + + LoopHint() + : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr), + ValueExpr(nullptr) {} }; } // end namespace clang diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h index 7860b6da06a0..f06d19629a30 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -10,8 +10,8 @@ // This file defines ExternalSemaSource interface, dispatching to all clients // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H -#define LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H +#ifndef LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H +#define LLVM_CLANG_SEMA_MULTIPLEXEXTERNALSEMASOURCE_H #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/Weak.h" @@ -282,6 +282,15 @@ public: /// introduce the same declarations repeatedly. void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override; + /// \brief Read the set of potentially unused typedefs known to the source. + /// + /// The external source should append its own potentially unused local + /// typedefs to the given vector of declarations. Note that this routine may + /// be invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + void ReadUnusedLocalTypedefNameCandidates( + llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; + /// \brief Read the set of locally-scoped extern "C" declarations known to the /// external Sema source. /// @@ -368,4 +377,4 @@ public: } // end namespace clang -#endif // LLVM_CLANG_SEMA_MULTIPLEX_EXTERNAL_SEMA_SOURCE_H +#endif diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h index 20033567dff9..b618e38f88cd 100644 --- a/include/clang/Sema/ObjCMethodList.h +++ b/include/clang/Sema/ObjCMethodList.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H -#define LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H +#ifndef LLVM_CLANG_SEMA_OBJCMETHODLIST_H +#define LLVM_CLANG_SEMA_OBJCMETHODLIST_H #include "llvm/ADT/PointerIntPair.h" @@ -20,20 +20,37 @@ namespace clang { class ObjCMethodDecl; -/// ObjCMethodList - a linked list of methods with different signatures. +/// \brief a linked list of methods with the same selector name but different +/// signatures. struct ObjCMethodList { - ObjCMethodDecl *Method; + // NOTE: If you add any members to this struct, make sure to serialize them. + /// \brief If there is more than one decl with this signature. + llvm::PointerIntPair<ObjCMethodDecl *, 1> MethodAndHasMoreThanOneDecl; /// \brief The next list object and 2 bits for extra info. llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits; - ObjCMethodList() : Method(nullptr) { } - ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) - : Method(M), NextAndExtraBits(C, 0) { } + ObjCMethodList() { } + ObjCMethodList(ObjCMethodDecl *M) + : MethodAndHasMoreThanOneDecl(M, 0) {} ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); } unsigned getBits() const { return NextAndExtraBits.getInt(); } void setNext(ObjCMethodList *L) { NextAndExtraBits.setPointer(L); } void setBits(unsigned B) { NextAndExtraBits.setInt(B); } + + ObjCMethodDecl *getMethod() const { + return MethodAndHasMoreThanOneDecl.getPointer(); + } + void setMethod(ObjCMethodDecl *M) { + return MethodAndHasMoreThanOneDecl.setPointer(M); + } + + bool hasMoreThanOneDecl() const { + return MethodAndHasMoreThanOneDecl.getInt(); + } + void setHasMoreThanOneDecl(bool B) { + return MethodAndHasMoreThanOneDecl.setInt(B); + } }; } diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 7c221a2336ce..4447db2b3ef0 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -25,6 +25,7 @@ #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" namespace clang { @@ -85,21 +86,6 @@ namespace clang { ICK_Num_Conversion_Kinds ///< The number of conversion kinds }; - /// ImplicitConversionCategory - The category of an implicit - /// conversion kind. The enumerator values match with Table 9 of - /// (C++ 13.3.3.1.1) and are listed such that better conversion - /// categories have smaller values. - enum ImplicitConversionCategory { - ICC_Identity = 0, ///< Identity - ICC_Lvalue_Transformation, ///< Lvalue transformation - ICC_Qualification_Adjustment, ///< Qualification adjustment - ICC_Promotion, ///< Promotion - ICC_Conversion ///< Conversion - }; - - ImplicitConversionCategory - GetConversionCategory(ImplicitConversionKind Kind); - /// ImplicitConversionRank - The rank of an implicit conversion /// kind. The enumerator values match with Table 9 of (C++ /// 13.3.3.1.1) and are listed such that better conversion ranks @@ -567,6 +553,17 @@ namespace clang { /// conversion. ovl_fail_trivial_conversion, + /// This conversion candidate was not considered because it is + /// an illegal instantiation of a constructor temploid: it is + /// callable with one argument, we only have one argument, and + /// its first parameter type is exactly the type of the class. + /// + /// Defining such a constructor directly is illegal, and + /// template-argument deduction is supposed to ignore such + /// instantiations, but we can still get one with the right + /// kind of implicit instantiation. + ovl_fail_illegal_constructor, + /// This conversion candidate is not viable because its result /// type is not implicitly convertible to the desired type. ovl_fail_bad_final_conversion, @@ -718,7 +715,8 @@ namespace clang { CandidateSetKind Kind; unsigned NumInlineSequences; - char InlineSpace[16 * sizeof(ImplicitConversionSequence)]; + llvm::AlignedCharArray<llvm::AlignOf<ImplicitConversionSequence>::Alignment, + 16 * sizeof(ImplicitConversionSequence)> InlineSpace; OverloadCandidateSet(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION; void operator=(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION; @@ -735,8 +733,8 @@ namespace clang { /// \brief Determine when this overload candidate will be new to the /// overload set. - bool isNewCandidate(Decl *F) { - return Functions.insert(F->getCanonicalDecl()); + bool isNewCandidate(Decl *F) { + return Functions.insert(F->getCanonicalDecl()).second; } /// \brief Clear out all of the candidates. @@ -759,7 +757,7 @@ namespace clang { // available. if (NumConversions + NumInlineSequences <= 16) { ImplicitConversionSequence *I = - (ImplicitConversionSequence*)InlineSpace; + (ImplicitConversionSequence *)InlineSpace.buffer; C.Conversions = &I[NumInlineSequences]; NumInlineSequences += NumConversions; } else { diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h index c0c772dc5983..ca22e640deb4 100644 --- a/include/clang/Sema/PrettyDeclStackTrace.h +++ b/include/clang/Sema/PrettyDeclStackTrace.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H -#define LLVM_CLANG_SEMA_PRETTY_DECL_STACK_TRACE_H +#ifndef LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H +#define LLVM_CLANG_SEMA_PRETTYDECLSTACKTRACE_H #include "clang/Basic/SourceLocation.h" #include "llvm/Support/PrettyStackTrace.h" diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 8e4e2ef4be21..97e447d1fd67 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -135,14 +135,6 @@ private: /// scopes seen as a component. unsigned short MSLocalManglingNumber; - /// \brief SEH __try blocks get uniquely numbered within a function. This - /// variable holds the index for an SEH try block. - short SEHTryIndex; - - /// \brief SEH __try blocks get uniquely numbered within a function. This - /// variable holds the next free index at a function's scope. - short SEHTryIndexPool; - /// PrototypeDepth - This is the number of function prototype scopes /// enclosing this scope, including this scope. unsigned short PrototypeDepth; @@ -155,7 +147,6 @@ private: /// pointer is non-null and points to it. This is used for label processing. Scope *FnParent; Scope *MSLocalManglingParent; - Scope *SEHTryParent; /// BreakParent/ContinueParent - This is a direct link to the innermost /// BreakScope/ContinueScope which contains the contents of this scope @@ -294,14 +285,6 @@ public: return 1; } - int getSEHTryIndex() { - return SEHTryIndex; - } - - int getSEHTryParentIndex() const { - return SEHTryParent ? SEHTryParent->SEHTryIndex : -1; - } - /// isDeclScope - Return true if this is the scope that the specified decl is /// declared in. bool isDeclScope(Decl *D) { @@ -317,6 +300,9 @@ public: return ErrorTrap.hasUnrecoverableErrorOccurred(); } + /// isFunctionScope() - Return true if this scope is a function scope. + bool isFunctionScope() const { return (getFlags() & Scope::FnScope); } + /// isClassScope - Return true if this scope is a class/struct/union scope. bool isClassScope() const { return (getFlags() & Scope::ClassScope); diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 63427aaa4a75..d63b734a8dbf 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -12,9 +12,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H -#define LLVM_CLANG_SEMA_SCOPE_INFO_H +#ifndef LLVM_CLANG_SEMA_SCOPEINFO_H +#define LLVM_CLANG_SEMA_SCOPEINFO_H +#include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/PartialDiagnostic.h" @@ -41,8 +42,6 @@ class SwitchStmt; class TemplateTypeParmDecl; class TemplateParameterList; class VarDecl; -class DeclRefExpr; -class MemberExpr; class ObjCIvarRefExpr; class ObjCPropertyRefExpr; class ObjCMessageExpr; @@ -145,6 +144,10 @@ public: /// current function scope. These diagnostics are vetted for reachability /// prior to being emitted. SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; + + /// \brief A list of parameters which have the nonnull attribute and are + /// modified in the function. + llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams; public: /// Represents a simple identification of a weak object. @@ -187,8 +190,6 @@ public: /// Used to find the proper base profile for a given base expression. static BaseInfoTy getBaseInfo(const Expr *BaseE); - // For use in DenseMap. - friend class DenseMapInfo; inline WeakObjectProfileTy(); static inline WeakObjectProfileTy getSentinel(); @@ -381,7 +382,7 @@ public: /// capture (if this is a capture and not an init-capture). The expression /// is only required if we are capturing ByVal and the variable's type has /// a non-trivial copy constructor. - llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind; + llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind; /// \brief The source location at which the first capture occurred. SourceLocation Loc; @@ -413,10 +414,11 @@ public: return InitExprAndCaptureKind.getInt() == Cap_This; } bool isVariableCapture() const { - return InitExprAndCaptureKind.getInt() != Cap_This; + return InitExprAndCaptureKind.getInt() != Cap_This && !isVLATypeCapture(); } bool isCopyCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy; + return InitExprAndCaptureKind.getInt() == Cap_ByCopy && + !isVLATypeCapture(); } bool isReferenceCapture() const { return InitExprAndCaptureKind.getInt() == Cap_ByRef; @@ -424,7 +426,11 @@ public: bool isBlockCapture() const { return InitExprAndCaptureKind.getInt() == Cap_Block; } - bool isNested() { return VarAndNested.getInt(); } + bool isVLATypeCapture() const { + return InitExprAndCaptureKind.getInt() == Cap_ByCopy && + getVariable() == nullptr; + } + bool isNested() const { return VarAndNested.getInt(); } VarDecl *getVariable() const { return VarAndNested.getPointer(); @@ -443,7 +449,8 @@ public: QualType getCaptureType() const { return CaptureType; } Expr *getInitExpr() const { - return InitExprAndCaptureKind.getPointer(); + assert(!isVLATypeCapture() && "no init expression for type capture"); + return static_cast<Expr *>(InitExprAndCaptureKind.getPointer()); } }; @@ -478,6 +485,13 @@ public: CaptureMap[Var] = Captures.size(); } + void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) { + Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false, + /*isByref*/ false, /*isNested*/ false, Loc, + /*EllipsisLoc*/ SourceLocation(), CaptureType, + /*Cpy*/ nullptr)); + } + void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, Expr *Cpy); @@ -494,7 +508,10 @@ public: bool isCaptured(VarDecl *Var) const { return CaptureMap.count(Var); } - + + /// \brief Determine whether the given variable-array type has been captured. + bool isVLATypeCaptured(const VariableArrayType *VAT) const; + /// \brief Retrieve the capture of the given variable, if it has been /// captured already. Capture &getCapture(VarDecl *Var) { diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index e254afdbadaa..74efa60c9366 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -129,7 +129,6 @@ namespace clang { class ModuleLoader; class MultiLevelTemplateArgumentList; class NamedDecl; - class NonNullAttr; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCCompatibleAliasDecl; @@ -169,6 +168,7 @@ namespace clang { class TypedefDecl; class TypedefNameDecl; class TypeLoc; + class TypoCorrectionConsumer; class UnqualifiedId; class UnresolvedLookupExpr; class UnresolvedMemberExpr; @@ -390,6 +390,10 @@ public: /// \brief Set containing all declared private fields that are not used. NamedDeclSetType UnusedPrivateFields; + /// \brief Set containing all typedefs that are likely unused. + llvm::SmallSetVector<const TypedefNameDecl *, 4> + UnusedLocalTypedefNameCandidates; + typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy; /// PureVirtualClassDiagSet - a set of class declarations which we have @@ -454,12 +458,11 @@ public: /// cycle detection at the end of the TU. DelegatingCtorDeclsType DelegatingCtorDecls; - /// \brief All the overriding destructors seen during a class definition - /// (there could be multiple due to nested classes) that had their exception - /// spec checks delayed, plus the overridden destructor. - SmallVector<std::pair<const CXXDestructorDecl*, - const CXXDestructorDecl*>, 2> - DelayedDestructorExceptionSpecChecks; + /// \brief All the overriding functions seen during a class definition + /// that had their exception spec checks delayed, plus the overridden + /// function. + SmallVector<std::pair<const CXXMethodDecl*, const CXXMethodDecl*>, 2> + DelayedExceptionSpecChecks; /// \brief All the members seen during a class definition which were both /// explicitly defaulted and had explicitly-specified exception @@ -477,11 +480,16 @@ public: /// \brief Callback to the parser to parse templated functions when needed. typedef void LateTemplateParserCB(void *P, LateParsedTemplate &LPT); + typedef void LateTemplateParserCleanupCB(void *P); LateTemplateParserCB *LateTemplateParser; + LateTemplateParserCleanupCB *LateTemplateParserCleanup; void *OpaqueParser; - void SetLateTemplateParser(LateTemplateParserCB *LTP, void *P) { + void SetLateTemplateParser(LateTemplateParserCB *LTP, + LateTemplateParserCleanupCB *LTPCleanup, + void *P) { LateTemplateParser = LTP; + LateTemplateParserCleanup = LTPCleanup; OpaqueParser = P; } @@ -684,7 +692,10 @@ public: /// \brief will hold 'respondsToSelector:' Selector RespondsToSelectorSel; - + + /// \brief counter for internal MS Asm label names. + unsigned MSAsmLabelNameCounter; + /// A flag to remember whether the implicit forms of operator new and delete /// have been declared. bool GlobalNewDeleteDeclared; @@ -745,6 +756,10 @@ public: /// this expression evaluation context. unsigned NumCleanupObjects; + /// \brief The number of typos encountered during this expression evaluation + /// context (i.e. the number of TypoExprs created). + unsigned NumTypos; + llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs; /// \brief The lambdas that are present within this context, if it @@ -778,6 +793,7 @@ public: bool IsDecltype) : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), + NumTypos(0), ManglingContextDecl(ManglingContextDecl), MangleNumbering() { } /// \brief Retrieve the mangling numbering context, used to consistently @@ -1037,6 +1053,8 @@ public: /// \brief Retrieve the module loader associated with the preprocessor. ModuleLoader &getModuleLoader() const; + void emitAndClearUnusedLocalTypedefWarnings(); + void ActOnEndOfTranslationUnit(); void CheckDelegatingCtorCycles(); @@ -1181,7 +1199,7 @@ public: const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT); void UpdateExceptionSpec(FunctionDecl *FD, - const FunctionProtoType::ExtProtoInfo &EPI); + const FunctionProtoType::ExceptionSpecInfo &ESI); bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range); bool CheckDistantExceptionSpec(QualType T); bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New); @@ -1233,7 +1251,7 @@ public: static QualType getPrintable(QualType T) { return T; } static SourceRange getPrintable(SourceRange R) { return R; } static SourceRange getPrintable(SourceLocation L) { return L; } - static SourceRange getPrintable(Expr *E) { return E->getSourceRange(); } + static SourceRange getPrintable(const Expr *E) { return E->getSourceRange(); } static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} template<typename T1> @@ -1381,7 +1399,10 @@ public: const CXXScopeSpec &SS, QualType T); QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); - QualType BuildDecltypeType(Expr *E, SourceLocation Loc); + /// If AsUnevaluated is false, E is treated as though it were an evaluated + /// context, such as when building a type for decltype(auto). + QualType BuildDecltypeType(Expr *E, SourceLocation Loc, + bool AsUnevaluated = true); QualType BuildUnaryTransformType(QualType BaseType, UnaryTransformType::UTTKind UKind, SourceLocation Loc); @@ -1543,13 +1564,11 @@ public: /// expression. /// /// \param CCC The correction callback, if typo correction is desired. - NameClassification ClassifyName(Scope *S, - CXXScopeSpec &SS, - IdentifierInfo *&Name, - SourceLocation NameLoc, - const Token &NextToken, - bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = nullptr); + NameClassification + ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, + SourceLocation NameLoc, const Token &NextToken, + bool IsAddressOfOperand, + std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr); Decl *ActOnDeclarator(Scope *S, Declarator &D); @@ -1989,6 +2008,13 @@ public: int FirstArg, unsigned AttrSpellingListIndex); SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name, unsigned AttrSpellingListIndex); + AlwaysInlineAttr *mergeAlwaysInlineAttr(Decl *D, SourceRange Range, + IdentifierInfo *Ident, + unsigned AttrSpellingListIndex); + MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range, + unsigned AttrSpellingListIndex); + OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range, + unsigned AttrSpellingListIndex); /// \brief Describes the kind of merge to perform for availability /// attributes (including "deprecated", "unavailable", and "availability"). @@ -2132,6 +2158,8 @@ public: }; ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); + ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, + APValue &Value, CCEKind CCE); /// \brief Abstract base class used to perform a contextual implicit /// conversion from an expression to any type passing a filter. @@ -2562,9 +2590,30 @@ public: bool ConstThis, bool VolatileThis); + typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator; + typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)> + TypoRecoveryCallback; + private: bool CppLookupName(LookupResult &R, Scope *S); + struct TypoExprState { + std::unique_ptr<TypoCorrectionConsumer> Consumer; + TypoDiagnosticGenerator DiagHandler; + TypoRecoveryCallback RecoveryHandler; + TypoExprState(); + TypoExprState(TypoExprState&& other) LLVM_NOEXCEPT; + TypoExprState& operator=(TypoExprState&& other) LLVM_NOEXCEPT; + }; + + /// \brief The set of unhandled TypoExprs and their associated state. + llvm::MapVector<TypoExpr *, TypoExprState> DelayedTypos; + + /// \brief Creates a new TypoExpr AST node. + TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, + TypoDiagnosticGenerator TDG, + TypoRecoveryCallback TRC); + // \brief The set of known/encountered (unique, canonicalized) NamespaceDecls. // // The boolean value will be true to indicate that the namespace was loaded @@ -2575,7 +2624,24 @@ private: /// source. bool LoadedExternalKnownNamespaces; + /// \brief Helper for CorrectTypo and CorrectTypoDelayed used to create and + /// populate a new TypoCorrectionConsumer. Returns nullptr if typo correction + /// should be skipped entirely. + std::unique_ptr<TypoCorrectionConsumer> + makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo, + Sema::LookupNameKind LookupKind, Scope *S, + CXXScopeSpec *SS, + std::unique_ptr<CorrectionCandidateCallback> CCC, + DeclContext *MemberContext, bool EnteringContext, + const ObjCObjectPointerType *OPT, + bool ErrorRecovery); + public: + const TypoExprState &getTypoExprState(TypoExpr *TE) const; + + /// \brief Clears the state of the given TypoExpr. + void clearDelayedTypo(TypoExpr *TE); + /// \brief Look up a name, looking for a single declaration. Return /// null if the results were absent, ambiguous, or overloaded. /// @@ -2590,12 +2656,15 @@ public: bool AllowBuiltinCreation = false); bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup = false); + bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, + CXXScopeSpec &SS); bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation = false, bool EnteringContext = false); ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl = NotForRedeclaration); + bool LookupInSuper(LookupResult &R, CXXRecordDecl *Class); void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, QualType T1, QualType T2, @@ -2645,13 +2714,35 @@ public: TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, - CorrectionCandidateCallback &CCC, + std::unique_ptr<CorrectionCandidateCallback> CCC, CorrectTypoKind Mode, DeclContext *MemberContext = nullptr, bool EnteringContext = false, const ObjCObjectPointerType *OPT = nullptr, bool RecordFailure = true); + TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo, + Sema::LookupNameKind LookupKind, Scope *S, + CXXScopeSpec *SS, + std::unique_ptr<CorrectionCandidateCallback> CCC, + TypoDiagnosticGenerator TDG, + TypoRecoveryCallback TRC, CorrectTypoKind Mode, + DeclContext *MemberContext = nullptr, + bool EnteringContext = false, + const ObjCObjectPointerType *OPT = nullptr); + + ExprResult + CorrectDelayedTyposInExpr(Expr *E, + llvm::function_ref<ExprResult(Expr *)> Filter = + [](Expr *E) -> ExprResult { return E; }); + + ExprResult + CorrectDelayedTyposInExpr(ExprResult ER, + llvm::function_ref<ExprResult(Expr *)> Filter = + [](Expr *E) -> ExprResult { return E; }) { + return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter); + } + void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery = true); @@ -2694,6 +2785,12 @@ public: void checkUnusedDeclAttributes(Declarator &D); + /// Determine if type T is a valid subject for a nonnull and similar + /// attributes. By default, we look through references (the behavior used by + /// nonnull), but if the second parameter is true, then we treat a reference + /// type as valid. + bool isValidPointerAttrType(QualType T, bool RefOkay = false); + bool CheckRegparmAttr(const AttributeList &attr, unsigned &value); bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const FunctionDecl *FD = nullptr); @@ -2872,12 +2969,27 @@ private: bool receiverIdOrClass, bool warn, bool instance); +public: + /// \brief - Returns instance or factory methods in global method pool for + /// given selector. If no such method or only one method found, function returns + /// false; otherwise, it returns true + bool CollectMultipleMethodsInGlobalPool(Selector Sel, + SmallVectorImpl<ObjCMethodDecl*>& Methods, + bool instance); + + bool AreMultipleMethodsInGlobalPool(Selector Sel, + bool instance); + +private: + /// \brief - Returns a selector which best matches given argument list or + /// nullptr if none could be found + ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, + bool IsInstance); + + /// \brief Record the typo correction failure and return an empty correction. TypoCorrection FailedCorrection(IdentifierInfo *Typo, SourceLocation TypoLoc, - bool RecordFailure = true, - bool IsUnqualifiedLookup = false) { - if (IsUnqualifiedLookup) - (void)UnqualifiedTyposCorrected[Typo]; + bool RecordFailure = true) { if (RecordFailure) TypoCorrectionFailures[Typo].insert(TypoLoc); return TypoCorrection(); @@ -2937,11 +3049,6 @@ public: public: FullExprArg(Sema &actions) : E(nullptr) { } - // 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) {} - ExprResult release() { return E; } @@ -3001,6 +3108,18 @@ public: Sema &S; }; + /// An RAII helper that pops function a function scope on exit. + struct FunctionScopeRAII { + Sema &S; + bool Active; + FunctionScopeRAII(Sema &S) : S(S), Active(true) {} + ~FunctionScopeRAII() { + if (Active) + S.PopFunctionScopeInfo(); + } + void disable() { Active = false; } + }; + StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc); @@ -3128,6 +3247,9 @@ public: ArrayRef<StringRef> Clobbers, ArrayRef<Expr*> Exprs, SourceLocation EndLoc); + LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName, + SourceLocation Location, + bool AlwaysCreate); VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, @@ -3169,9 +3291,9 @@ public: StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ? SourceLocation TryLoc, Stmt *TryBlock, - Stmt *Handler, int HandlerIndex, - int HandlerParentIndex); - StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, + Stmt *Handler); + StmtResult ActOnSEHExceptBlock(SourceLocation Loc, + Expr *FilterExpr, Stmt *Block); StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block); StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); @@ -3187,6 +3309,7 @@ public: /// DiagnoseUnusedExprResult - If the statement passed in is an expression /// whose result is unused, warn. void DiagnoseUnusedExprResult(const Stmt *S); + void DiagnoseUnusedNestedTypedefs(const RecordDecl *D); void DiagnoseUnusedDecl(const NamedDecl *ND); /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null @@ -3204,6 +3327,10 @@ public: void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody); + /// Warn if a value is moved to itself. + void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, + SourceLocation OpLoc); + ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) { return DelayedDiagnostics.push(pool); } @@ -3228,8 +3355,6 @@ public: const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess); - void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); - bool makeUnavailableInSystemHeader(SourceLocation loc, StringRef message); @@ -3271,7 +3396,8 @@ public: // needs to be delayed for some constant variables when we build one of the // named expressions. void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse); - void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func); + void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, + bool OdrUse = true); void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); void MarkDeclRefReferenced(DeclRefExpr *E); void MarkMemberReferenced(MemberExpr *E); @@ -3327,6 +3453,9 @@ public: TryCaptureKind Kind = TryCapture_Implicit, SourceLocation EllipsisLoc = SourceLocation()); + /// \brief Checks if the variable must be captured. + bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc); + /// \brief Given a variable, determine the type that a reference to that /// variable will have in the given scope. QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc); @@ -3359,12 +3488,11 @@ public: // Primary Expressions. SourceRange getExprRange(Expr *E) const; - ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - UnqualifiedId &Id, - bool HasTrailingLParen, bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = nullptr, - bool IsInlineAsmIdentifier = false); + ExprResult ActOnIdExpression( + Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, + std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr, + bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); void DecomposeUnqualifiedId(const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, @@ -3373,9 +3501,9 @@ public: bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectionCandidateCallback &CCC, + std::unique_ptr<CorrectionCandidateCallback> CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, - ArrayRef<Expr *> Args = None); + ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr); ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, @@ -3430,11 +3558,13 @@ public: ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, - bool NeedsADL); + bool NeedsADL, + bool AcceptInvalidDecl = false); ExprResult BuildDeclarationNameExpr( const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, NamedDecl *FoundD = nullptr, - const TemplateArgumentListInfo *TemplateArgs = nullptr); + const TemplateArgumentListInfo *TemplateArgs = nullptr, + bool AcceptInvalidDecl = false); ExprResult BuildLiteralOperatorCall(LookupResult &R, DeclarationNameInfo &SuffixInfo, @@ -3446,6 +3576,9 @@ public: PredefinedExpr::IdentType IT); ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); + + bool CheckLoopHintExpr(Expr *E, SourceLocation Loc); + ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr); ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope = nullptr); @@ -3629,6 +3762,10 @@ public: bool GNUSyntax, ExprResult Init); +private: + static BinaryOperatorKind ConvertTokenKindToBinaryOpcode(tok::TokenKind Kind); + +public: ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr); ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, @@ -3876,6 +4013,8 @@ public: bool IsStdInitListInitialization, bool RequiresZeroInit, unsigned ConstructKind, SourceRange ParenRange); + ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field); + /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating /// the default expr if needed. ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, @@ -3934,24 +4073,20 @@ public: /// \brief Overwrite an EPI's exception specification with this /// computed exception specification. - void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const { - EPI.ExceptionSpecType = getExceptionSpecType(); - if (EPI.ExceptionSpecType == EST_Dynamic) { - EPI.NumExceptions = size(); - EPI.Exceptions = data(); - } else if (EPI.ExceptionSpecType == EST_None) { + FunctionProtoType::ExceptionSpecInfo getExceptionSpec() const { + FunctionProtoType::ExceptionSpecInfo ESI; + ESI.Type = getExceptionSpecType(); + if (ESI.Type == EST_Dynamic) { + ESI.Exceptions = Exceptions; + } else if (ESI.Type == EST_None) { /// C++11 [except.spec]p14: /// The exception-specification is noexcept(false) if the set of /// potential exceptions of the special member function contains "any" - EPI.ExceptionSpecType = EST_ComputedNoexcept; - EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(), + ESI.Type = EST_ComputedNoexcept; + ESI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(), tok::kw_false).get(); } - } - FunctionProtoType::ExtProtoInfo getEPI() const { - FunctionProtoType::ExtProtoInfo EPI; - getEPI(EPI); - return EPI; + return ESI; } }; @@ -3998,13 +4133,28 @@ public: void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD); /// \brief Check the given exception-specification and update the - /// extended prototype information with the results. - void checkExceptionSpecification(ExceptionSpecificationType EST, + /// exception specification information with the results. + void checkExceptionSpecification(bool IsTopLevel, + ExceptionSpecificationType EST, ArrayRef<ParsedType> DynamicExceptions, ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr, SmallVectorImpl<QualType> &Exceptions, - FunctionProtoType::ExtProtoInfo &EPI); + FunctionProtoType::ExceptionSpecInfo &ESI); + + /// \brief Determine if we're in a case where we need to (incorrectly) eagerly + /// parse an exception specification to work around a libstdc++ bug. + bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D); + + /// \brief Add an exception-specification to the given member function + /// (or member function template). The exception-specification was parsed + /// after the method itself was declared. + void actOnDelayedExceptionSpecification(Decl *Method, + ExceptionSpecificationType EST, + SourceRange SpecificationRange, + ArrayRef<ParsedType> DynamicExceptions, + ArrayRef<SourceRange> DynamicExceptionRanges, + Expr *NoexceptExpr); /// \brief Determine if a special member function should have a deleted /// definition when it is defaulted. @@ -4206,6 +4356,17 @@ public: void *TyOrExpr, SourceLocation RParenLoc); + /// \brief Handle a C++1z fold-expression: ( expr op ... op expr ). + ExprResult ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, + tok::TokenKind Operator, + SourceLocation EllipsisLoc, Expr *RHS, + SourceLocation RParenLoc); + ExprResult BuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, + BinaryOperatorKind Operator, + SourceLocation EllipsisLoc, Expr *RHS, + SourceLocation RParenLoc); + ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, + BinaryOperatorKind Operator); //// ActOnCXXThis - Parse 'this' pointer. ExprResult ActOnCXXThis(SourceLocation loc); @@ -4450,16 +4611,26 @@ public: /// \brief The parser has parsed a global nested-name-specifier '::'. /// - /// \param S The scope in which this nested-name-specifier occurs. - /// /// \param CCLoc The location of the '::'. /// /// \param SS The nested-name-specifier, which will be updated in-place /// to reflect the parsed nested-name-specifier. /// /// \returns true if an error occurred, false otherwise. - bool ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc, - CXXScopeSpec &SS); + bool ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc, CXXScopeSpec &SS); + + /// \brief The parser has parsed a '__super' nested-name-specifier. + /// + /// \param SuperLoc The location of the '__super' keyword. + /// + /// \param ColonColonLoc The location of the '::'. + /// + /// \param SS The nested-name-specifier, which will be updated in-place + /// to reflect the parsed nested-name-specifier. + /// + /// \returns true if an error occurred, false otherwise. + bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, + SourceLocation ColonColonLoc, CXXScopeSpec &SS); bool isAcceptableNestedNameSpecifier(const NamedDecl *SD); NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS); @@ -5038,6 +5209,10 @@ public: /// CheckOverrideControl - Check C++11 override control semantics. void CheckOverrideControl(NamedDecl *D); + + /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was + /// not used in the declaration of an overriding method. + void DiagnoseAbsenceOfOverrideControl(NamedDecl *D); /// CheckForFunctionMarkedFinal - Checks whether a virtual member function /// overrides a virtual member function marked 'final', according to @@ -5582,6 +5757,10 @@ public: // C++ Variadic Templates (C++0x [temp.variadic]) //===--------------------------------------------------------------------===// + /// Determine whether an unexpanded parameter pack might be permitted in this + /// location. Useful for error recovery. + bool isUnexpandedParameterPackPermitted(); + /// \brief The context in which an unexpanded parameter pack is /// being diagnosed. /// @@ -6053,6 +6232,8 @@ public: bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); + TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; + bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, SourceLocation ReturnLoc, Expr *&RetExpr, AutoType *AT); @@ -6512,17 +6693,6 @@ public: /// \brief The number of typos corrected by CorrectTypo. unsigned TyposCorrected; - typedef llvm::DenseMap<IdentifierInfo *, TypoCorrection> - 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; - typedef llvm::SmallSet<SourceLocation, 2> SrcLocSet; typedef llvm::DenseMap<IdentifierInfo *, SrcLocSet> IdentifierSourceLocations; @@ -6548,6 +6718,31 @@ public: /// but have not yet been performed. std::deque<PendingImplicitInstantiation> PendingInstantiations; + class SavePendingInstantiationsAndVTableUsesRAII { + public: + SavePendingInstantiationsAndVTableUsesRAII(Sema &S): S(S) { + SavedPendingInstantiations.swap(S.PendingInstantiations); + SavedVTableUses.swap(S.VTableUses); + } + + ~SavePendingInstantiationsAndVTableUsesRAII() { + // Restore the set of pending vtables. + assert(S.VTableUses.empty() && + "VTableUses should be empty before it is discarded."); + S.VTableUses.swap(SavedVTableUses); + + // Restore the set of pending implicit instantiations. + assert(S.PendingInstantiations.empty() && + "PendingInstantiations should be empty before it is discarded."); + S.PendingInstantiations.swap(SavedPendingInstantiations); + } + + private: + Sema &S; + SmallVector<VTableUse, 16> SavedVTableUses; + std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; + }; + /// \brief The queue of implicit template instantiations that are required /// and must be performed within the current local scope. /// @@ -6597,6 +6792,8 @@ public: DeclarationName Entity, CXXRecordDecl *ThisContext, unsigned ThisTypeQuals); + void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, + const MultiLevelTemplateArgumentList &Args); ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, @@ -6656,6 +6853,10 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs, TemplateSpecializationKind TSK); + bool InstantiateInClassInitializer( + SourceLocation PointOfInstantiation, FieldDecl *Instantiation, + FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs); + struct LateInstantiatedAttribute { const Attr *TmplAttr; LocalInstantiationScope *Scope; @@ -7142,33 +7343,10 @@ public: PSK_CodeSeg, }; - enum PragmaSectionFlag : unsigned { - PSF_None = 0, - PSF_Read = 0x1, - PSF_Write = 0x2, - PSF_Execute = 0x4, - PSF_Implicit = 0x8, - PSF_Invalid = 0x80000000U, - }; - - struct SectionInfo { - DeclaratorDecl *Decl; - SourceLocation PragmaSectionLocation; - int SectionFlags; - SectionInfo() {} - SectionInfo(DeclaratorDecl *Decl, - SourceLocation PragmaSectionLocation, - int SectionFlags) - : Decl(Decl), - PragmaSectionLocation(PragmaSectionLocation), - SectionFlags(SectionFlags) {} - }; - - llvm::StringMap<SectionInfo> SectionInfos; - bool UnifySection(const StringRef &SectionName, + bool UnifySection(StringRef SectionName, int SectionFlags, DeclaratorDecl *TheDecl); - bool UnifySection(const StringRef &SectionName, + bool UnifySection(StringRef SectionName, int SectionFlags, SourceLocation PragmaSectionLocation); @@ -7283,6 +7461,16 @@ public: void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T, unsigned SpellingListIndex, bool IsPackExpansion); + /// AddAssumeAlignedAttr - Adds an assume_aligned attribute to a particular + /// declaration. + void AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, Expr *OE, + unsigned SpellingListIndex); + + /// AddAlignValueAttr - Adds an align_value attribute to a particular + /// declaration. + void AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, + unsigned SpellingListIndex); + // OpenMP directives and clauses. private: void *VarDataSharingAttributesStack; @@ -7291,6 +7479,10 @@ private: void DestroyDataSharingAttributesStack(); ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind); + /// \brief Checks if the specified variable is used in one of the private + /// clauses in OpenMP constructs. + bool IsOpenMPCapturedVar(VarDecl *VD); + public: ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op); @@ -7342,6 +7534,12 @@ public: ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp for simd' after parsing + /// of the associated statement. + StmtResult ActOnOpenMPForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp sections' after parsing /// of the associated statement. StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7371,6 +7569,12 @@ public: ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp parallel for simd' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel sections' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7395,6 +7599,25 @@ public: StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp ordered' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp atomic' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp teams' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, @@ -7473,6 +7696,21 @@ public: /// \brief Called on well-formed 'mergeable' clause. OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'read' clause. + OMPClause *ActOnOpenMPReadClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'write' clause. + OMPClause *ActOnOpenMPWriteClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'update' clause. + OMPClause *ActOnOpenMPUpdateClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'capture' clause. + OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'seq_cst' clause. + OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, + SourceLocation EndLoc); OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, @@ -7615,6 +7853,7 @@ public: VAK_Valid, VAK_ValidInCXX11, VAK_Undefined, + VAK_MSVCUndefined, VAK_Invalid }; @@ -7732,6 +7971,12 @@ public: Expr *SrcExpr, AssignmentAction Action, bool *Complained = nullptr); + /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag + /// enum. If AllowMask is true, then we also allow the complement of a valid + /// value, to be used as a mask. + bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, + bool AllowMask) const; + /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant /// integer not in the range of enum values. void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, @@ -7976,6 +8221,7 @@ public: ObjCMethodDecl *Method, bool isClassMessage, bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, + SourceRange RecRange, QualType &ReturnType, ExprValueKind &VK); /// \brief Determine the result of a message send expression based on @@ -8067,18 +8313,30 @@ public: CFT_Device, CFT_Global, CFT_Host, - CFT_HostDevice + CFT_HostDevice, + CFT_InvalidTarget }; CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); - bool CheckCUDATarget(CUDAFunctionTarget CallerTarget, - CUDAFunctionTarget CalleeTarget); - - bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) { - return CheckCUDATarget(IdentifyCUDATarget(Caller), - IdentifyCUDATarget(Callee)); - } + bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee); + + /// Given a implicit special member, infer its CUDA target from the + /// calls it needs to make to underlying base/field special members. + /// \param ClassDecl the class for which the member is being created. + /// \param CSM the kind of special member. + /// \param MemberDecl the special member itself. + /// \param ConstRHS true if this is a copy operation with a const object on + /// its RHS. + /// \param Diagnose true if this call should emit diagnostics. + /// \return true if there was an error inferring. + /// The result of this call is implicit CUDA target attribute(s) attached to + /// the member declaration. + bool inferCUDATargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl, + CXXSpecialMember CSM, + CXXMethodDecl *MemberDecl, + bool ConstRHS, + bool Diagnose); /// \name Code completion //@{ @@ -8269,7 +8527,8 @@ private: bool CheckObjCString(Expr *Arg); - ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, + unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, unsigned MaxWidth); @@ -8295,6 +8554,7 @@ public: private: bool SemaBuiltinPrefetch(CallExpr *TheCall); bool SemaBuiltinAssume(CallExpr *TheCall); + bool SemaBuiltinAssumeAligned(CallExpr *TheCall); bool SemaBuiltinLongjmp(CallExpr *TheCall); ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, @@ -8322,6 +8582,10 @@ public: FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs); + + bool FormatStringHasSArg(const StringLiteral *FExpr); + + bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); private: bool CheckFormatArguments(const FormatAttr *Format, @@ -8359,6 +8623,7 @@ private: void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS); void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation()); + void CheckBoolLikeConversion(Expr *E, SourceLocation CC); void CheckForIntOverflow(Expr *E); void CheckUnsequencedOperations(Expr *E); diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index fdf959305151..7740d5e29c00 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_DIAGNOSTICSEMA_H -#define LLVM_CLANG_DIAGNOSTICSEMA_H +#ifndef LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H +#define LLVM_CLANG_SEMA_SEMADIAGNOSTIC_H #include "clang/Basic/Diagnostic.h" diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h index fffca6791454..343ccfb3d630 100644 --- a/include/clang/Sema/SemaFixItUtils.h +++ b/include/clang/Sema/SemaFixItUtils.h @@ -10,8 +10,8 @@ // This file defines helper classes for generation of Sema FixItHints. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_FIXITUTILS_H -#define LLVM_CLANG_SEMA_FIXITUTILS_H +#ifndef LLVM_CLANG_SEMA_SEMAFIXITUTILS_H +#define LLVM_CLANG_SEMA_SEMAFIXITUTILS_H #include "clang/AST/Expr.h" @@ -88,4 +88,4 @@ struct ConversionFixItGenerator { }; } // endof namespace clang -#endif // LLVM_CLANG_SEMA_FIXITUTILS_H +#endif diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index 9199b0fba2a5..045bacf21360 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -12,10 +12,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_SEMA_INTERNAL_H -#define LLVM_CLANG_SEMA_SEMA_INTERNAL_H +#ifndef LLVM_CLANG_SEMA_SEMAINTERNAL_H +#define LLVM_CLANG_SEMA_SEMAINTERNAL_H #include "clang/AST/ASTContext.h" +#include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaDiagnostic.h" @@ -86,6 +87,213 @@ inline InheritableAttr *getDLLAttr(Decl *D) { return nullptr; } +class TypoCorrectionConsumer : public VisibleDeclConsumer { + typedef SmallVector<TypoCorrection, 1> TypoResultList; + typedef llvm::StringMap<TypoResultList> TypoResultsMap; + typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap; + +public: + TypoCorrectionConsumer(Sema &SemaRef, + const DeclarationNameInfo &TypoName, + Sema::LookupNameKind LookupKind, + Scope *S, CXXScopeSpec *SS, + std::unique_ptr<CorrectionCandidateCallback> CCC, + DeclContext *MemberContext, + bool EnteringContext) + : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0), + SemaRef(SemaRef), S(S), + SS(SS ? llvm::make_unique<CXXScopeSpec>(*SS) : nullptr), + CorrectionValidator(std::move(CCC)), MemberContext(MemberContext), + Result(SemaRef, TypoName, LookupKind), + Namespaces(SemaRef.Context, SemaRef.CurContext, SS), + EnteringContext(EnteringContext), SearchNamespaces(false) { + Result.suppressDiagnostics(); + // Arrange for ValidatedCorrections[0] to always be an empty correction. + ValidatedCorrections.push_back(TypoCorrection()); + } + + bool includeHiddenDecls() const override { return true; } + + // Methods for adding potential corrections to the consumer. + void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, + bool InBaseClass) override; + void FoundName(StringRef Name); + void addKeywordResult(StringRef Keyword); + void addCorrection(TypoCorrection Correction); + + bool empty() const { + return CorrectionResults.empty() && ValidatedCorrections.size() == 1; + } + + /// \brief Return the list of TypoCorrections for the given identifier from + /// the set of corrections that have the closest edit distance, if any. + TypoResultList &operator[](StringRef Name) { + return CorrectionResults.begin()->second[Name]; + } + + /// \brief Return the edit distance of the corrections that have the + /// closest/best edit distance from the original typop. + unsigned getBestEditDistance(bool Normalized) { + if (CorrectionResults.empty()) + return (std::numeric_limits<unsigned>::max)(); + + unsigned BestED = CorrectionResults.begin()->first; + return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED; + } + + /// \brief Set-up method to add to the consumer the set of namespaces to use + /// in performing corrections to nested name specifiers. This method also + /// implicitly adds all of the known classes in the current AST context to the + /// to the consumer for correcting nested name specifiers. + void + addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces); + + /// \brief Return the next typo correction that passes all internal filters + /// and is deemed valid by the consumer's CorrectionCandidateCallback, + /// starting with the corrections that have the closest edit distance. An + /// empty TypoCorrection is returned once no more viable corrections remain + /// in the consumer. + const TypoCorrection &getNextCorrection(); + + /// \brief Get the last correction returned by getNextCorrection(). + const TypoCorrection &getCurrentCorrection() { + return CurrentTCIndex < ValidatedCorrections.size() + ? ValidatedCorrections[CurrentTCIndex] + : ValidatedCorrections[0]; // The empty correction. + } + + /// \brief Return the next typo correction like getNextCorrection, but keep + /// the internal state pointed to the current correction (i.e. the next time + /// getNextCorrection is called, it will return the same correction returned + /// by peekNextcorrection). + const TypoCorrection &peekNextCorrection() { + auto Current = CurrentTCIndex; + const TypoCorrection &TC = getNextCorrection(); + CurrentTCIndex = Current; + return TC; + } + + /// \brief Reset the consumer's position in the stream of viable corrections + /// (i.e. getNextCorrection() will return each of the previously returned + /// corrections in order before returning any new corrections). + void resetCorrectionStream() { + CurrentTCIndex = 0; + } + + /// \brief Return whether the end of the stream of corrections has been + /// reached. + bool finished() { + return CorrectionResults.empty() && + CurrentTCIndex >= ValidatedCorrections.size(); + } + + ASTContext &getContext() const { return SemaRef.Context; } + const LookupResult &getLookupResult() const { return Result; } + + bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; } + const CXXScopeSpec *getSS() const { return SS.get(); } + Scope *getScope() const { return S; } + +private: + class NamespaceSpecifierSet { + struct SpecifierInfo { + DeclContext* DeclCtx; + NestedNameSpecifier* NameSpecifier; + unsigned EditDistance; + }; + + typedef SmallVector<DeclContext*, 4> DeclContextList; + typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList; + + ASTContext &Context; + DeclContextList CurContextChain; + std::string CurNameSpecifier; + SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers; + SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers; + bool isSorted; + + SpecifierInfoList Specifiers; + llvm::SmallSetVector<unsigned, 4> Distances; + llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap; + + /// \brief Helper for building the list of DeclContexts between the current + /// context and the top of the translation unit + static DeclContextList buildContextChain(DeclContext *Start); + + void sortNamespaces(); + + unsigned buildNestedNameSpecifier(DeclContextList &DeclChain, + NestedNameSpecifier *&NNS); + + public: + NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext, + CXXScopeSpec *CurScopeSpec); + + /// \brief Add the DeclContext (a namespace or record) to the set, computing + /// the corresponding NestedNameSpecifier and its distance in the process. + void addNameSpecifier(DeclContext *Ctx); + + typedef SpecifierInfoList::iterator iterator; + iterator begin() { + if (!isSorted) sortNamespaces(); + return Specifiers.begin(); + } + iterator end() { return Specifiers.end(); } + }; + + void addName(StringRef Name, NamedDecl *ND, + NestedNameSpecifier *NNS = nullptr, bool isKeyword = false); + + /// \brief Find any visible decls for the given typo correction candidate. + /// If none are found, it to the set of candidates for which qualified lookups + /// will be performed to find possible nested name specifier changes. + bool resolveCorrection(TypoCorrection &Candidate); + + /// \brief Perform qualified lookups on the queued set of typo correction + /// candidates and add the nested name specifier changes to each candidate if + /// a lookup succeeds (at which point the candidate will be returned to the + /// main pool of potential corrections). + void performQualifiedLookups(); + + /// \brief The name written that is a typo in the source. + IdentifierInfo *Typo; + + /// \brief The results found that have the smallest edit distance + /// found (so far) with the typo name. + /// + /// The pointer value being set to the current DeclContext indicates + /// whether there is a keyword with this name. + TypoEditDistanceMap CorrectionResults; + + SmallVector<TypoCorrection, 4> ValidatedCorrections; + size_t CurrentTCIndex; + + Sema &SemaRef; + Scope *S; + std::unique_ptr<CXXScopeSpec> SS; + std::unique_ptr<CorrectionCandidateCallback> CorrectionValidator; + DeclContext *MemberContext; + LookupResult Result; + NamespaceSpecifierSet Namespaces; + SmallVector<TypoCorrection, 2> QualifiedResults; + bool EnteringContext; + bool SearchNamespaces; +}; + +inline Sema::TypoExprState::TypoExprState() {} + +inline Sema::TypoExprState::TypoExprState(TypoExprState &&other) LLVM_NOEXCEPT { + *this = std::move(other); } +inline Sema::TypoExprState &Sema::TypoExprState::operator=( + Sema::TypoExprState &&other) LLVM_NOEXCEPT { + Consumer = std::move(other.Consumer); + DiagHandler = std::move(other.DiagHandler); + RecoveryHandler = std::move(other.RecoveryHandler); + return *this; +} + +} // end namespace clang + #endif diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h index f6367505f866..d043e2c459b3 100644 --- a/include/clang/Sema/SemaLambda.h +++ b/include/clang/Sema/SemaLambda.h @@ -13,8 +13,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_SEMA_LAMBDA_H -#define LLVM_CLANG_SEMA_LAMBDA_H +#ifndef LLVM_CLANG_SEMA_SEMALAMBDA_H +#define LLVM_CLANG_SEMA_SEMALAMBDA_H #include "clang/AST/ASTLambda.h" #include "clang/Sema/ScopeInfo.h" namespace clang { @@ -33,4 +33,4 @@ Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda( } // clang -#endif // LLVM_CLANG_SEMA_LAMBDA_H +#endif diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 2c2c36d30be3..8338d975752c 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -10,8 +10,8 @@ // routines. // //===----------------------------------------------------------------------===/ -#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H -#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H +#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H +#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H #include "clang/AST/DeclTemplate.h" #include "clang/Basic/PartialDiagnostic.h" diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index 6cab59c93efc..922d0ffa1142 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Ownership.h" #include "llvm/ADT/SmallVector.h" namespace clang { @@ -198,10 +199,9 @@ public: void setCorrectionRange(CXXScopeSpec *SS, const DeclarationNameInfo &TypoName) { - CorrectionRange.setBegin(ForceSpecifierReplacement && SS && !SS->isEmpty() - ? SS->getBeginLoc() - : TypoName.getLoc()); - CorrectionRange.setEnd(TypoName.getLoc()); + CorrectionRange = TypoName.getSourceRange(); + if (ForceSpecifierReplacement && SS && !SS->isEmpty()) + CorrectionRange.setBegin(SS->getBeginLoc()); } SourceRange getCorrectionRange() const { @@ -247,11 +247,13 @@ class CorrectionCandidateCallback { public: static const unsigned InvalidDistance = TypoCorrection::InvalidDistance; - CorrectionCandidateCallback() + explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr, + NestedNameSpecifier *TypoNNS = nullptr) : WantTypeSpecifiers(true), WantExpressionKeywords(true), - WantCXXNamedCasts(true), WantRemainingKeywords(true), - WantObjCSuper(false), IsObjCIvarLookup(false), - IsAddressOfOperand(false) {} + WantCXXNamedCasts(true), WantFunctionLikeCasts(true), + WantRemainingKeywords(true), WantObjCSuper(false), + IsObjCIvarLookup(false), IsAddressOfOperand(false), Typo(Typo), + TypoNNS(TypoNNS) {} virtual ~CorrectionCandidateCallback() {} @@ -274,20 +276,39 @@ public: /// the default RankCandidate returns either 0 or InvalidDistance depending /// whether ValidateCandidate returns true or false. virtual unsigned RankCandidate(const TypoCorrection &candidate) { - return ValidateCandidate(candidate) ? 0 : InvalidDistance; + return (!MatchesTypo(candidate) && ValidateCandidate(candidate)) + ? 0 + : InvalidDistance; } - // Flags for context-dependent keywords. + void setTypoName(IdentifierInfo *II) { Typo = II; } + void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; } + + // Flags for context-dependent keywords. WantFunctionLikeCasts is only + // used/meaningful when WantCXXNamedCasts is false. // TODO: Expand these to apply to non-keywords or possibly remove them. bool WantTypeSpecifiers; bool WantExpressionKeywords; bool WantCXXNamedCasts; + bool WantFunctionLikeCasts; bool WantRemainingKeywords; bool WantObjCSuper; // Temporary hack for the one case where a CorrectTypoContext enum is used // when looking up results. bool IsObjCIvarLookup; bool IsAddressOfOperand; + +protected: + bool MatchesTypo(const TypoCorrection &candidate) { + return Typo && candidate.isResolved() && !candidate.requiresImport() && + candidate.getCorrectionAsIdentifierInfo() == Typo && + // FIXME: This probably does not return true when both + // NestedNameSpecifiers have the same textual representation. + candidate.getCorrectionSpecifier() == TypoNNS; + } + + IdentifierInfo *Typo; + NestedNameSpecifier *TypoNNS; }; /// @brief Simple template class for restricting typo correction candidates @@ -325,6 +346,7 @@ public: WantTypeSpecifiers = false; WantExpressionKeywords = false; WantCXXNamedCasts = false; + WantFunctionLikeCasts = false; WantRemainingKeywords = false; } |
