diff options
Diffstat (limited to 'lib/Sema')
37 files changed, 4997 insertions, 3145 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index ab46554485..3b6cbe9469 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -1309,11 +1309,10 @@ static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM, case Stmt::ObjCForCollectionStmtClass: return true; case Stmt::DoStmtClass: { - const Expr *Cond = cast<DoStmt>(S)->getCond(); - llvm::APSInt Val; - if (!Cond->EvaluateAsInt(Val, Ctx)) + Expr::EvalResult Result; + if (!cast<DoStmt>(S)->getCond()->EvaluateAsInt(Result, Ctx)) return true; - return Val.getBoolValue(); + return Result.Val.getInt().getBoolValue(); } default: break; diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt index 3d21d79f2b..5f20af01fb 100644 --- a/lib/Sema/CMakeLists.txt +++ b/lib/Sema/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS if (MSVC) set_source_files_properties(SemaDeclAttr.cpp PROPERTIES COMPILE_FLAGS /bigobj) set_source_files_properties(SemaExpr.cpp PROPERTIES COMPILE_FLAGS /bigobj) + set_source_files_properties(SemaExprCXX.cpp PROPERTIES COMPILE_FLAGS /bigobj) set_source_files_properties(SemaTemplate.cpp PROPERTIES COMPILE_FLAGS /bigobj) endif() diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 754169fe5f..92e65c4b81 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -49,6 +49,8 @@ bool CodeCompletionContext::wantConstructorResults() const { case CCC_Expression: case CCC_ObjCMessageReceiver: case CCC_ParenthesizedExpression: + case CCC_Symbol: + case CCC_SymbolOrNewName: return true; case CCC_TopLevel: @@ -65,8 +67,7 @@ bool CodeCompletionContext::wantConstructorResults() const { case CCC_ObjCProtocolName: case CCC_Namespace: case CCC_Type: - case CCC_Name: - case CCC_PotentiallyQualifiedName: + case CCC_NewName: case CCC_MacroName: case CCC_MacroNameUse: case CCC_PreprocessorExpression: @@ -128,10 +129,12 @@ StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) { return "Namespace"; case CCKind::CCC_Type: return "Type"; - case CCKind::CCC_Name: - return "Name"; - case CCKind::CCC_PotentiallyQualifiedName: - return "PotentiallyQualifiedName"; + case CCKind::CCC_NewName: + return "NewName"; + case CCKind::CCC_Symbol: + return "Symbol"; + case CCKind::CCC_SymbolOrNewName: + return "SymbolOrNewName"; case CCKind::CCC_MacroName: return "MacroName"; case CCKind::CCC_MacroNameUse: @@ -269,23 +272,18 @@ CodeCompletionString::Chunk::CreateResultType(const char *ResultType) { return Chunk(CK_ResultType, ResultType); } -CodeCompletionString::Chunk -CodeCompletionString::Chunk::CreateCurrentParameter( - const char *CurrentParameter) { +CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter( + const char *CurrentParameter) { return Chunk(CK_CurrentParameter, CurrentParameter); } -CodeCompletionString::CodeCompletionString(const Chunk *Chunks, - unsigned NumChunks, - unsigned Priority, - CXAvailabilityKind Availability, - const char **Annotations, - unsigned NumAnnotations, - StringRef ParentName, - const char *BriefComment) - : NumChunks(NumChunks), NumAnnotations(NumAnnotations), - Priority(Priority), Availability(Availability), - ParentName(ParentName), BriefComment(BriefComment) { +CodeCompletionString::CodeCompletionString( + const Chunk *Chunks, unsigned NumChunks, unsigned Priority, + CXAvailabilityKind Availability, const char **Annotations, + unsigned NumAnnotations, StringRef ParentName, const char *BriefComment) + : NumChunks(NumChunks), NumAnnotations(NumAnnotations), Priority(Priority), + Availability(Availability), ParentName(ParentName), + BriefComment(BriefComment) { assert(NumChunks <= 0xffff); assert(NumAnnotations <= 0xffff); @@ -293,7 +291,8 @@ CodeCompletionString::CodeCompletionString(const Chunk *Chunks, for (unsigned I = 0; I != NumChunks; ++I) StoredChunks[I] = Chunks[I]; - const char **StoredAnnotations = reinterpret_cast<const char **>(StoredChunks + NumChunks); + const char **StoredAnnotations = + reinterpret_cast<const char **>(StoredChunks + NumChunks); for (unsigned I = 0; I != NumAnnotations; ++I) StoredAnnotations[I] = Annotations[I]; } @@ -304,7 +303,7 @@ unsigned CodeCompletionString::getAnnotationCount() const { const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const { if (AnnotationNr < NumAnnotations) - return reinterpret_cast<const char * const*>(end())[AnnotationNr]; + return reinterpret_cast<const char *const *>(end())[AnnotationNr]; else return nullptr; } @@ -313,27 +312,33 @@ std::string CodeCompletionString::getAsString() const { std::string Result; llvm::raw_string_ostream OS(Result); - for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) { - switch (C->Kind) { - case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break; - case CK_Placeholder: OS << "<#" << C->Text << "#>"; break; - + for (const Chunk &C : *this) { + switch (C.Kind) { + case CK_Optional: + OS << "{#" << C.Optional->getAsString() << "#}"; + break; + case CK_Placeholder: + OS << "<#" << C.Text << "#>"; + break; case CK_Informative: case CK_ResultType: - OS << "[#" << C->Text << "#]"; + OS << "[#" << C.Text << "#]"; + break; + case CK_CurrentParameter: + OS << "<#" << C.Text << "#>"; + break; + default: + OS << C.Text; break; - - case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break; - default: OS << C->Text; break; } } return OS.str(); } const char *CodeCompletionString::getTypedText() const { - for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) - if (C->Kind == CK_TypedText) - return C->Text; + for (const Chunk &C : *this) + if (C.Kind == CK_TypedText) + return C.Text; return nullptr; } @@ -368,7 +373,7 @@ StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) { // Find the interesting names. SmallVector<const DeclContext *, 2> Contexts; while (DC && !DC->isFunctionOrMethod()) { - if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) { + if (const auto *ND = dyn_cast<NamedDecl>(DC)) { if (ND->getIdentifier()) Contexts.push_back(DC); } @@ -387,11 +392,11 @@ StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) { OS << "::"; } - const DeclContext *CurDC = Contexts[I-1]; - if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC)) + const DeclContext *CurDC = Contexts[I - 1]; + if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC)) CurDC = CatImpl->getCategoryDecl(); - if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) { + if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) { const ObjCInterfaceDecl *Interface = Cat->getClassInterface(); if (!Interface) { // Assign an empty StringRef but with non-null data to distinguish @@ -417,11 +422,9 @@ CodeCompletionString *CodeCompletionBuilder::TakeString() { sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() + sizeof(const char *) * Annotations.size(), alignof(CodeCompletionString)); - CodeCompletionString *Result - = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(), - Priority, Availability, - Annotations.data(), Annotations.size(), - ParentName, BriefComment); + CodeCompletionString *Result = new (Mem) CodeCompletionString( + Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(), + Annotations.size(), ParentName, BriefComment); Chunks.clear(); return Result; } @@ -450,8 +453,8 @@ void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) { Chunks.push_back(Chunk::CreateResultType(ResultType)); } -void -CodeCompletionBuilder::AddCurrentParameterChunk(const char *CurrentParameter) { +void CodeCompletionBuilder::AddCurrentParameterChunk( + const char *CurrentParameter) { Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter)); } @@ -481,8 +484,7 @@ void CodeCompletionBuilder::addBriefComment(StringRef Comment) { //===----------------------------------------------------------------------===// // Code completion overload candidate implementation //===----------------------------------------------------------------------===// -FunctionDecl * -CodeCompleteConsumer::OverloadCandidate::getFunction() const { +FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const { if (getKind() == CK_Function) return Function; else if (getKind() == CK_FunctionTemplate) @@ -498,8 +500,9 @@ CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { return Function->getType()->getAs<FunctionType>(); case CK_FunctionTemplate: - return FunctionTemplate->getTemplatedDecl()->getType() - ->getAs<FunctionType>(); + return FunctionTemplate->getTemplatedDecl() + ->getType() + ->getAs<FunctionType>(); case CK_FunctionType: return Type; @@ -514,12 +517,12 @@ CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { CodeCompleteConsumer::~CodeCompleteConsumer() = default; -bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter, - CodeCompletionResult Result) { +bool PrintingCodeCompleteConsumer::isResultFilteredOut( + StringRef Filter, CodeCompletionResult Result) { switch (Result.Kind) { case CodeCompletionResult::RK_Declaration: return !(Result.Declaration->getIdentifier() && - Result.Declaration->getIdentifier()->getName().startswith(Filter)); + Result.Declaration->getIdentifier()->getName().startswith(Filter)); case CodeCompletionResult::RK_Keyword: return !StringRef(Result.Keyword).startswith(Filter); case CodeCompletionResult::RK_Macro: @@ -531,30 +534,39 @@ bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter, llvm_unreachable("Unknown code completion result Kind."); } -void -PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, - CodeCompletionContext Context, - CodeCompletionResult *Results, - unsigned NumResults) { +void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults( + Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results, + unsigned NumResults) { std::stable_sort(Results, Results + NumResults); - StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); + if (!Context.getPreferredType().isNull()) + OS << "PREFERRED-TYPE: " << Context.getPreferredType().getAsString() + << "\n"; - // Print the results. + StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); + // Print the completions. for (unsigned I = 0; I != NumResults; ++I) { - if(!Filter.empty() && isResultFilteredOut(Filter, Results[I])) + if (!Filter.empty() && isResultFilteredOut(Filter, Results[I])) continue; OS << "COMPLETION: "; switch (Results[I].Kind) { case CodeCompletionResult::RK_Declaration: OS << *Results[I].Declaration; - if (Results[I].Hidden) - OS << " (Hidden)"; - if (CodeCompletionString *CCS - = Results[I].CreateCodeCompletionString(SemaRef, Context, - getAllocator(), - CCTUInfo, - includeBriefComments())) { + { + std::vector<std::string> Tags; + if (Results[I].Hidden) + Tags.push_back("Hidden"); + if (Results[I].InBaseClass) + Tags.push_back("InBase"); + if (Results[I].Availability == + CXAvailabilityKind::CXAvailability_NotAccessible) + Tags.push_back("Inaccessible"); + if (!Tags.empty()) + OS << " (" << llvm::join(Tags, ",") << ")"; + } + if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( + SemaRef, Context, getAllocator(), CCTUInfo, + includeBriefComments())) { OS << " : " << CCS->getAsString(); if (const char *BriefComment = CCS->getBriefComment()) OS << " : " << BriefComment; @@ -586,19 +598,16 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, case CodeCompletionResult::RK_Macro: OS << Results[I].Macro->getName(); - if (CodeCompletionString *CCS - = Results[I].CreateCodeCompletionString(SemaRef, Context, - getAllocator(), - CCTUInfo, - includeBriefComments())) { + if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( + SemaRef, Context, getAllocator(), CCTUInfo, + includeBriefComments())) { OS << " : " << CCS->getAsString(); } OS << '\n'; break; case CodeCompletionResult::RK_Pattern: - OS << "Pattern : " - << Results[I].Pattern->getAsString() << '\n'; + OS << "Pattern : " << Results[I].Pattern->getAsString() << '\n'; break; } } @@ -627,7 +636,9 @@ static std::string getOverloadAsString(const CodeCompletionString &CCS) { case CodeCompletionString::CK_Optional: break; - default: OS << C.Text; break; + default: + OS << C.Text; + break; } } return OS.str(); @@ -683,7 +694,7 @@ void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { break; } - if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration)) + if (const auto *Function = dyn_cast<FunctionDecl>(Declaration)) if (Function->isDeleted()) Availability = CXAvailability_NotAvailable; @@ -717,15 +728,15 @@ void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { /// saved into Saved and the returned StringRef will refer to it. StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const { switch (Kind) { - case RK_Keyword: - return Keyword; - case RK_Pattern: - return Pattern->getTypedText(); - case RK_Macro: - return Macro->getName(); - case RK_Declaration: - // Handle declarations below. - break; + case RK_Keyword: + return Keyword; + case RK_Pattern: + return Pattern->getTypedText(); + case RK_Macro: + return Macro->getName(); + case RK_Declaration: + // Handle declarations below. + break; } DeclarationName Name = Declaration->getDeclName(); @@ -735,8 +746,7 @@ StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const { if (IdentifierInfo *Id = Name.getAsIdentifierInfo()) return Id->getName(); if (Name.isObjCZeroArgSelector()) - if (IdentifierInfo *Id - = Name.getObjCSelector().getIdentifierInfoForSlot(0)) + if (IdentifierInfo *Id = Name.getObjCSelector().getIdentifierInfoForSlot(0)) return Id->getName(); Saved = Name.getAsString(); @@ -753,9 +763,5 @@ bool clang::operator<(const CodeCompletionResult &X, return cmp < 0; // If case-insensitive comparison fails, try case-sensitive comparison. - cmp = XStr.compare(YStr); - if (cmp) - return cmp < 0; - - return false; + return XStr.compare(YStr) < 0; } diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index b22eea2b36..2efa0a7fd1 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -438,7 +438,7 @@ template <class T> static bool BadSpecifier(T TNew, T TPrev, if (TNew != TPrev) DiagID = diag::err_invalid_decl_spec_combination; else - DiagID = IsExtension ? diag::ext_duplicate_declspec : + DiagID = IsExtension ? diag::ext_warn_duplicate_declspec : diag::warn_duplicate_declspec; return true; } @@ -566,14 +566,16 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, // these storage-class specifiers. // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class // specifiers are not supported." + // OpenCL C++ v1.0 s2.9 restricts register. if (S.getLangOpts().OpenCL && !S.getOpenCLOptions().isEnabled("cl_clang_storage_class_specifiers")) { switch (SC) { case SCS_extern: case SCS_private_extern: case SCS_static: - if (S.getLangOpts().OpenCLVersion < 120) { - DiagID = diag::err_opencl_unknown_type_specifier; + if (S.getLangOpts().OpenCLVersion < 120 && + !S.getLangOpts().OpenCLCPlusPlus) { + DiagID = diag::err_opencl_unknown_type_specifier; PrevSpec = getSpecifierName(SC); return true; } @@ -967,7 +969,7 @@ bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { if (isModulePrivateSpecified()) { PrevSpec = "__module_private__"; - DiagID = diag::ext_duplicate_declspec; + DiagID = diag::ext_warn_duplicate_declspec; return true; } diff --git a/lib/Sema/ParsedAttr.cpp b/lib/Sema/ParsedAttr.cpp index 3dff0ad63e..59e5aab677 100644 --- a/lib/Sema/ParsedAttr.cpp +++ b/lib/Sema/ParsedAttr.cpp @@ -103,15 +103,31 @@ void AttributePool::takePool(AttributePool &pool) { #include "clang/Sema/AttrParsedAttrKinds.inc" -static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, +static StringRef normalizeAttrScopeName(StringRef ScopeName, + ParsedAttr::Syntax SyntaxUsed) { + // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name + // to be "clang". + if (SyntaxUsed == ParsedAttr::AS_CXX11 || + SyntaxUsed == ParsedAttr::AS_C2x) { + if (ScopeName == "__gnu__") + ScopeName = "gnu"; + else if (ScopeName == "_Clang") + ScopeName = "clang"; + } + return ScopeName; +} + +static StringRef normalizeAttrName(StringRef AttrName, + StringRef NormalizedScopeName, ParsedAttr::Syntax SyntaxUsed) { // Normalize the attribute name, __foo__ becomes foo. This is only allowable - // for GNU attributes. - bool IsGNU = SyntaxUsed == ParsedAttr::AS_GNU || - ((SyntaxUsed == ParsedAttr::AS_CXX11 || - SyntaxUsed == ParsedAttr::AS_C2x) && - ScopeName == "gnu"); - if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") && + // for GNU attributes, and attributes using the double square bracket syntax. + bool ShouldNormalize = + SyntaxUsed == ParsedAttr::AS_GNU || + ((SyntaxUsed == ParsedAttr::AS_CXX11 || + SyntaxUsed == ParsedAttr::AS_C2x) && + (NormalizedScopeName == "gnu" || NormalizedScopeName == "clang")); + if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") && AttrName.endswith("__")) AttrName = AttrName.slice(2, AttrName.size() - 2); @@ -125,7 +141,7 @@ ParsedAttr::Kind ParsedAttr::getKind(const IdentifierInfo *Name, SmallString<64> FullName; if (ScopeName) - FullName += ScopeName->getName(); + FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed); AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed); @@ -141,9 +157,10 @@ ParsedAttr::Kind ParsedAttr::getKind(const IdentifierInfo *Name, unsigned ParsedAttr::getAttributeSpellingListIndex() const { // Both variables will be used in tablegen generated // attribute spell list index matching code. - StringRef Scope = ScopeName ? ScopeName->getName() : ""; - StringRef Name = normalizeAttrName(AttrName->getName(), Scope, - (ParsedAttr::Syntax)SyntaxUsed); + auto Syntax = static_cast<ParsedAttr::Syntax>(SyntaxUsed); + StringRef Scope = + ScopeName ? normalizeAttrScopeName(ScopeName->getName(), Syntax) : ""; + StringRef Name = normalizeAttrName(AttrName->getName(), Scope, Syntax); #include "clang/Sema/AttrSpellingListIndex.inc" diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp index 62a83ccb70..bd8db6f4ed 100644 --- a/lib/Sema/ScopeInfo.cpp +++ b/lib/Sema/ScopeInfo.cpp @@ -54,6 +54,8 @@ void FunctionScopeInfo::Clear() { PossiblyUnreachableDiags.clear(); WeakObjectUses.clear(); ModifiedNonNullParams.clear(); + Blocks.clear(); + ByrefBlockVars.clear(); } static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) { diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index d777afe981..a8e3b85fe0 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -152,7 +152,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I) NSNumberLiteralMethods[I] = nullptr; - if (getLangOpts().ObjC1) + if (getLangOpts().ObjC) NSAPIObj.reset(new NSAPI(Context)); if (getLangOpts().CPlusPlus) @@ -167,7 +167,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, PreallocatedFunctionScope.reset(new FunctionScopeInfo(Diags)); - // Initilization of data sharing attributes stack for OpenMP + // Initialization of data sharing attributes stack for OpenMP InitDataSharingAttributesStack(); std::unique_ptr<sema::SemaPPCallbacks> Callbacks = @@ -214,7 +214,7 @@ void Sema::Initialize() { // Initialize predefined Objective-C types: - if (getLangOpts().ObjC1) { + if (getLangOpts().ObjC) { // If 'SEL' does not yet refer to any declarations, make it refer to the // predefined 'SEL'. DeclarationName SEL = &Context.Idents.get("SEL"); @@ -320,6 +320,10 @@ void Sema::Initialize() { #define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \ setOpenCLExtensionForType(Context.Id, Ext); #include "clang/Basic/OpenCLImageTypes.def" +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + addImplicitTypedef(#ExtType, Context.Id##Ty); \ + setOpenCLExtensionForType(Context.Id##Ty, #Ext); +#include "clang/Basic/OpenCLExtensionTypes.def" }; if (Context.getTargetInfo().hasBuiltinMSVaList()) { @@ -533,6 +537,7 @@ CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) { case Type::STK_Floating: return CK_FloatingToBoolean; case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean; case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean; + case Type::STK_FixedPoint: return CK_FixedPointToBoolean; } llvm_unreachable("unknown scalar type kind"); } @@ -644,7 +649,8 @@ void Sema::getUndefinedButUsed( continue; if (FD->isExternallyVisible() && !isExternalWithNoLinkageType(FD) && - !FD->getMostRecentDecl()->isInlined()) + !FD->getMostRecentDecl()->isInlined() && + !FD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; if (FD->getBuiltinID()) continue; @@ -654,7 +660,8 @@ void Sema::getUndefinedButUsed( continue; if (VD->isExternallyVisible() && !isExternalWithNoLinkageType(VD) && - !VD->getMostRecentDecl()->isInline()) + !VD->getMostRecentDecl()->isInline() && + !VD->hasAttr<ExcludeFromExplicitInstantiationAttr>()) continue; // Skip VarDecls that lack formal definitions but which we know are in @@ -1401,9 +1408,68 @@ void Sema::RecordParsingTemplateParameterDepth(unsigned Depth) { "Remove assertion if intentionally called in a non-lambda context."); } +// Check that the type of the VarDecl has an accessible copy constructor and +// resolve its destructor's exception spefication. +static void checkEscapingByref(VarDecl *VD, Sema &S) { + QualType T = VD->getType(); + EnterExpressionEvaluationContext scope( + S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); + SourceLocation Loc = VD->getLocation(); + Expr *VarRef = new (S.Context) DeclRefExpr(VD, false, T, VK_LValue, Loc); + ExprResult Result = S.PerformMoveOrCopyInitialization( + InitializedEntity::InitializeBlock(Loc, T, false), VD, VD->getType(), + VarRef, /*AllowNRVO=*/true); + if (!Result.isInvalid()) { + Result = S.MaybeCreateExprWithCleanups(Result); + Expr *Init = Result.getAs<Expr>(); + S.Context.setBlockVarCopyInit(VD, Init, S.canThrow(Init)); + } + + // The destructor's exception spefication is needed when IRGen generates + // block copy/destroy functions. Resolve it here. + if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + if (CXXDestructorDecl *DD = RD->getDestructor()) { + auto *FPT = DD->getType()->getAs<FunctionProtoType>(); + S.ResolveExceptionSpec(Loc, FPT); + } +} + +static void markEscapingByrefs(const FunctionScopeInfo &FSI, Sema &S) { + // Set the EscapingByref flag of __block variables captured by + // escaping blocks. + for (const BlockDecl *BD : FSI.Blocks) { + if (BD->doesNotEscape()) + continue; + for (const BlockDecl::Capture &BC : BD->captures()) { + VarDecl *VD = BC.getVariable(); + if (VD->hasAttr<BlocksAttr>()) + VD->setEscapingByref(); + } + } + + for (VarDecl *VD : FSI.ByrefBlockVars) { + // __block variables might require us to capture a copy-initializer. + if (!VD->isEscapingByref()) + continue; + // It's currently invalid to ever have a __block variable with an + // array type; should we diagnose that here? + // Regardless, we don't want to ignore array nesting when + // constructing this copy. + if (VD->getType()->isStructureOrClassType()) + checkEscapingByref(VD, S); + } +} + void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP, const Decl *D, const BlockExpr *blkExpr) { assert(!FunctionScopes.empty() && "mismatched push/pop!"); + + // This function shouldn't be called after popping the current function scope. + // markEscapingByrefs calls PerformMoveOrCopyInitialization, which can call + // PushFunctionScope, which can cause clearing out PreallocatedFunctionScope + // when FunctionScopes is empty. + markEscapingByrefs(*FunctionScopes.back(), *this); + FunctionScopeInfo *Scope = FunctionScopes.pop_back_val(); if (LangOpts.OpenMP) @@ -1853,6 +1919,34 @@ void Sema::setCurrentOpenCLExtensionForDecl(Decl *D) { setOpenCLExtensionForDecl(D, CurrOpenCLExtension); } +std::string Sema::getOpenCLExtensionsFromDeclExtMap(FunctionDecl *FD) { + if (!OpenCLDeclExtMap.empty()) + return getOpenCLExtensionsFromExtMap(FD, OpenCLDeclExtMap); + + return ""; +} + +std::string Sema::getOpenCLExtensionsFromTypeExtMap(FunctionType *FT) { + if (!OpenCLTypeExtMap.empty()) + return getOpenCLExtensionsFromExtMap(FT, OpenCLTypeExtMap); + + return ""; +} + +template <typename T, typename MapT> +std::string Sema::getOpenCLExtensionsFromExtMap(T *FDT, MapT &Map) { + std::string ExtensionNames = ""; + auto Loc = Map.find(FDT); + + for (auto const& I : Loc->second) { + ExtensionNames += I; + ExtensionNames += " "; + } + ExtensionNames.pop_back(); + + return ExtensionNames; +} + bool Sema::isOpenCLDisabledDecl(Decl *FD) { auto Loc = OpenCLDeclExtMap.find(FD); if (Loc == OpenCLDeclExtMap.end()) diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index cf33231037..69084589ef 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1877,22 +1877,31 @@ void Sema::CheckLookupAccess(const LookupResult &R) { /// specifiers into account, but no member access expressions and such. /// /// \param Target the declaration to check if it can be accessed -/// \param Ctx the class/context from which to start the search +/// \param NamingClass the class in which the lookup was started. +/// \param BaseType type of the left side of member access expression. +/// \p BaseType and \p NamingClass are used for C++ access control. +/// Depending on the lookup case, they should be set to the following: +/// - lhs.target (member access without a qualifier): +/// \p BaseType and \p NamingClass are both the type of 'lhs'. +/// - lhs.X::target (member access with a qualifier): +/// BaseType is the type of 'lhs', NamingClass is 'X' +/// - X::target (qualified lookup without member access): +/// BaseType is null, NamingClass is 'X'. +/// - target (unqualified lookup). +/// BaseType is null, NamingClass is the parent class of 'target'. /// \return true if the Target is accessible from the Class, false otherwise. -bool Sema::IsSimplyAccessible(NamedDecl *Target, DeclContext *Ctx) { - if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) { - if (!Target->isCXXClassMember()) - return true; - - if (Target->getAccess() == AS_public) - return true; - QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal(); +bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass, + QualType BaseType) { + // Perform the C++ accessibility checks first. + if (Target->isCXXClassMember() && NamingClass) { + if (!getLangOpts().CPlusPlus) + return false; // The unprivileged access is AS_none as we don't know how the member was // accessed, which is described by the access in DeclAccessPair. // `IsAccessible` will examine the actual access of Target (i.e. // Decl->getAccess()) when calculating the access. - AccessTarget Entity(Context, AccessedEntity::Member, Class, - DeclAccessPair::make(Target, AS_none), qType); + AccessTarget Entity(Context, AccessedEntity::Member, NamingClass, + DeclAccessPair::make(Target, AS_none), BaseType); EffectiveContext EC(CurContext); return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible; } diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index 8024e1a051..f6ac9b44a8 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -520,9 +520,9 @@ attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) { } // end anonymous namespace -void Sema::ActOnPragmaAttributePush(ParsedAttr &Attribute, - SourceLocation PragmaLoc, - attr::ParsedSubjectMatchRuleSet Rules) { +void Sema::ActOnPragmaAttributeAttribute( + ParsedAttr &Attribute, SourceLocation PragmaLoc, + attr::ParsedSubjectMatchRuleSet Rules) { SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules; // Gather the subject match rules that are supported by the attribute. SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> @@ -622,48 +622,64 @@ void Sema::ActOnPragmaAttributePush(ParsedAttr &Attribute, Diagnostic << attrMatcherRuleListToString(ExtraRules); } - PragmaAttributeStack.push_back( + if (PragmaAttributeStack.empty()) { + Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push); + return; + } + + PragmaAttributeStack.back().Entries.push_back( {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false}); } +void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc) { + PragmaAttributeStack.emplace_back(); + PragmaAttributeStack.back().Loc = PragmaLoc; +} + void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) { if (PragmaAttributeStack.empty()) { Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch); return; } - const PragmaAttributeEntry &Entry = PragmaAttributeStack.back(); - if (!Entry.IsUsed) { - assert(Entry.Attribute && "Expected an attribute"); - Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused) - << Entry.Attribute->getName(); - Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here); + + for (const PragmaAttributeEntry &Entry : + PragmaAttributeStack.back().Entries) { + if (!Entry.IsUsed) { + assert(Entry.Attribute && "Expected an attribute"); + Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused) + << Entry.Attribute->getName(); + Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here); + } } + PragmaAttributeStack.pop_back(); } void Sema::AddPragmaAttributes(Scope *S, Decl *D) { if (PragmaAttributeStack.empty()) return; - for (auto &Entry : PragmaAttributeStack) { - ParsedAttr *Attribute = Entry.Attribute; - assert(Attribute && "Expected an attribute"); - - // Ensure that the attribute can be applied to the given declaration. - bool Applies = false; - for (const auto &Rule : Entry.MatchRules) { - if (Attribute->appliesToDecl(D, Rule)) { - Applies = true; - break; + for (auto &Group : PragmaAttributeStack) { + for (auto &Entry : Group.Entries) { + ParsedAttr *Attribute = Entry.Attribute; + assert(Attribute && "Expected an attribute"); + + // Ensure that the attribute can be applied to the given declaration. + bool Applies = false; + for (const auto &Rule : Entry.MatchRules) { + if (Attribute->appliesToDecl(D, Rule)) { + Applies = true; + break; + } } + if (!Applies) + continue; + Entry.IsUsed = true; + PragmaAttributeCurrentTargetDecl = D; + ParsedAttributesView Attrs; + Attrs.addAtEnd(Attribute); + ProcessDeclAttributeList(S, D, Attrs); + PragmaAttributeCurrentTargetDecl = nullptr; } - if (!Applies) - continue; - Entry.IsUsed = true; - PragmaAttributeCurrentTargetDecl = D; - ParsedAttributesView Attrs; - Attrs.addAtEnd(Attribute); - ProcessDeclAttributeList(S, D, Attrs); - PragmaAttributeCurrentTargetDecl = nullptr; } } diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index c2e314c245..0b4645e11c 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -131,6 +131,9 @@ namespace { return PlaceholderKind == K; } + // Language specific cast restrictions for address spaces. + void checkAddressSpaceCast(QualType SrcType, QualType DestType); + void checkCastAlign() { Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange); } @@ -561,7 +564,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, Qualifiers *CastAwayQualifiers = nullptr) { // If the only checking we care about is for Objective-C lifetime qualifiers, // and we're not in ObjC mode, there's nothing to check. - if (!CheckCVR && CheckObjCLifetime && !Self.Context.getLangOpts().ObjC1) + if (!CheckCVR && CheckObjCLifetime && !Self.Context.getLangOpts().ObjC) return CastAwayConstnessKind::CACK_None; if (!DestType->isReferenceType()) { @@ -2276,6 +2279,27 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, return SuccessResult; } +void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) { + // In OpenCL only conversions between pointers to objects in overlapping + // addr spaces are allowed. v2.0 s6.5.5 - Generic addr space overlaps + // with any named one, except for constant. + if (Self.getLangOpts().OpenCL) { + auto SrcPtrType = SrcType->getAs<PointerType>(); + if (!SrcPtrType) + return; + auto DestPtrType = DestType->getAs<PointerType>(); + if (!DestPtrType) + return; + if (!DestPtrType->isAddressSpaceOverlapping(*SrcPtrType)) { + Self.Diag(OpRange.getBegin(), + diag::err_typecheck_incompatible_address_space) + << SrcType << DestType << Sema::AA_Casting + << SrcExpr.get()->getSourceRange(); + SrcExpr = ExprError(); + } + } +} + void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, bool ListInitialization) { assert(Self.getLangOpts().CPlusPlus); @@ -2403,6 +2427,8 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, } } + checkAddressSpaceCast(SrcExpr.get()->getType(), DestType); + if (isValidCast(tcr)) { if (Kind == CK_BitCast) checkCastAlign(); @@ -2489,20 +2515,9 @@ void CastOperation::CheckCStyleCast() { assert(!SrcType->isPlaceholderType()); - // OpenCL v1 s6.5: Casting a pointer to address space A to a pointer to - // address space B is illegal. - if (Self.getLangOpts().OpenCL && DestType->isPointerType() && - SrcType->isPointerType()) { - const PointerType *DestPtr = DestType->getAs<PointerType>(); - if (!DestPtr->isAddressSpaceOverlapping(*SrcType->getAs<PointerType>())) { - Self.Diag(OpRange.getBegin(), - diag::err_typecheck_incompatible_address_space) - << SrcType << DestType << Sema::AA_Casting - << SrcExpr.get()->getSourceRange(); - SrcExpr = ExprError(); - return; - } - } + checkAddressSpaceCast(SrcType, DestType); + if (SrcExpr.isInvalid()) + return; if (Self.RequireCompleteType(OpRange.getBegin(), DestType, diag::err_typecheck_cast_to_incomplete)) { @@ -2539,10 +2554,11 @@ void CastOperation::CheckCStyleCast() { // OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type. if (Self.getLangOpts().OpenCL && DestType->isEventT()) { - llvm::APSInt CastInt; - if (SrcExpr.get()->EvaluateAsInt(CastInt, Self.Context)) { + Expr::EvalResult Result; + if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) { + llvm::APSInt CastInt = Result.Val.getInt(); if (0 == CastInt) { - Kind = CK_ZeroToOCLEvent; + Kind = CK_ZeroToOCLOpaqueType; return; } Self.Diag(OpRange.getBegin(), diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index a258d349c6..46cac25eed 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -27,6 +27,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" +#include "clang/AST/FormatString.h" #include "clang/AST/NSAPI.h" #include "clang/AST/NonTrivialTypeVisitor.h" #include "clang/AST/OperationKinds.h" @@ -35,7 +36,6 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" -#include "clang/Analysis/Analyses/FormatString.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" @@ -247,13 +247,16 @@ static void SemaBuiltinMemChkCall(Sema &S, FunctionDecl *FDecl, const Expr *SizeArg = TheCall->getArg(SizeIdx); const Expr *DstSizeArg = TheCall->getArg(DstSizeIdx); - llvm::APSInt Size, DstSize; + Expr::EvalResult SizeResult, DstSizeResult; // find out if both sizes are known at compile time - if (!SizeArg->EvaluateAsInt(Size, S.Context) || - !DstSizeArg->EvaluateAsInt(DstSize, S.Context)) + if (!SizeArg->EvaluateAsInt(SizeResult, S.Context) || + !DstSizeArg->EvaluateAsInt(DstSizeResult, S.Context)) return; + llvm::APSInt Size = SizeResult.Val.getInt(); + llvm::APSInt DstSize = DstSizeResult.Val.getInt(); + if (Size.ule(DstSize)) return; @@ -877,6 +880,66 @@ static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID, return false; } +static ExprResult SemaBuiltinLaunder(Sema &S, CallExpr *TheCall) { + if (checkArgCount(S, TheCall, 1)) + return ExprError(); + + // Compute __builtin_launder's parameter type from the argument. + // The parameter type is: + // * The type of the argument if it's not an array or function type, + // Otherwise, + // * The decayed argument type. + QualType ParamTy = [&]() { + QualType ArgTy = TheCall->getArg(0)->getType(); + if (const ArrayType *Ty = ArgTy->getAsArrayTypeUnsafe()) + return S.Context.getPointerType(Ty->getElementType()); + if (ArgTy->isFunctionType()) { + return S.Context.getPointerType(ArgTy); + } + return ArgTy; + }(); + + TheCall->setType(ParamTy); + + auto DiagSelect = [&]() -> llvm::Optional<unsigned> { + if (!ParamTy->isPointerType()) + return 0; + if (ParamTy->isFunctionPointerType()) + return 1; + if (ParamTy->isVoidPointerType()) + return 2; + return llvm::Optional<unsigned>{}; + }(); + if (DiagSelect.hasValue()) { + S.Diag(TheCall->getBeginLoc(), diag::err_builtin_launder_invalid_arg) + << DiagSelect.getValue() << TheCall->getSourceRange(); + return ExprError(); + } + + // We either have an incomplete class type, or we have a class template + // whose instantiation has not been forced. Example: + // + // template <class T> struct Foo { T value; }; + // Foo<int> *p = nullptr; + // auto *d = __builtin_launder(p); + if (S.RequireCompleteType(TheCall->getBeginLoc(), ParamTy->getPointeeType(), + diag::err_incomplete_type)) + return ExprError(); + + assert(ParamTy->getPointeeType()->isObjectType() && + "Unhandled non-object pointer case"); + + InitializedEntity Entity = + InitializedEntity::InitializeParameter(S.Context, ParamTy, false); + ExprResult Arg = + S.PerformCopyInitialization(Entity, SourceLocation(), TheCall->getArg(0)); + if (Arg.isInvalid()) + return ExprError(); + TheCall->setArg(0, Arg.get()); + + return TheCall; +} + // Emit an error and return true if the current architecture is not in the list // of supported architectures. static bool @@ -1039,6 +1102,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, if (checkArgCount(*this, TheCall, 1)) return true; TheCall->setType(Context.IntTy); break; + case Builtin::BI__builtin_launder: + return SemaBuiltinLaunder(*this, TheCall); case Builtin::BI__sync_fetch_and_add: case Builtin::BI__sync_fetch_and_add_1: case Builtin::BI__sync_fetch_and_add_2: @@ -1308,7 +1373,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, // check for the argument. if (SemaBuiltinRWPipe(*this, TheCall)) return ExprError(); - TheCall->setType(Context.IntTy); break; case Builtin::BIreserve_read_pipe: case Builtin::BIreserve_write_pipe: @@ -1340,7 +1404,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, case Builtin::BIget_pipe_max_packets: if (SemaBuiltinPipePackets(*this, TheCall)) return ExprError(); - TheCall->setType(Context.UnsignedIntTy); break; case Builtin::BIto_global: case Builtin::BIto_local: @@ -1749,6 +1812,16 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, BuiltinID == AArch64::BI__builtin_arm_wsrp) return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true); + // Only check the valid encoding range. Any constant in this range would be + // converted to a register of the form S1_2_C3_C4_5. Let the hardware throw + // an exception for incorrect registers. This matches MSVC behavior. + if (BuiltinID == AArch64::BI_ReadStatusReg || + BuiltinID == AArch64::BI_WriteStatusReg) + return SemaBuiltinConstantArgRange(TheCall, 0, 0, 0x7fff); + + if (BuiltinID == AArch64::BI__getReg) + return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31); + if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) return true; @@ -1766,777 +1839,814 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, } bool Sema::CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall) { - static const std::map<unsigned, std::vector<StringRef>> ValidCPU = { - { Hexagon::BI__builtin_HEXAGON_A6_vcmpbeq_notany, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_A6_vminub_RdP, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_M6_vabsdiffb, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_M6_vabsdiffub, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_vsplatrbp, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_vtrunehb_ppp, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_S6_vtrunohb_ppp, {"v62", "v65"} }, + struct BuiltinAndString { + unsigned BuiltinID; + const char *Str; }; - static const std::map<unsigned, std::vector<StringRef>> ValidHVX = { - { Hexagon::BI__builtin_HEXAGON_V6_extractw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_extractw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_hi, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_hi_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lo, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lo_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lvsplatb, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lvsplatb_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lvsplath, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lvsplath_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lvsplatw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_lvsplatw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_and_n, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_and_n_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_not, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_not_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_or_n, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_or_n_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2v2, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2v2_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_pred_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_shuffeqh, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_shuffeqh_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_shuffeqw, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_shuffeqw_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsb, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsb_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsb_sat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsb_sat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsh_sat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsh_sat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsw_sat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vabsw_sat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddb_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddb_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_dv, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_dv_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddcarry, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddcarry_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddclbh, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddclbh_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddclbw, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddclbw_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddh_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddh_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddububb_sat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddububb_sat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_dv, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_dv_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddw_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddw_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_valignb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_valignb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_valignbi, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vand, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vand_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandqrt, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvnqv, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvnqv_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvqv, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvqv_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvrt, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslh_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslh_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslhv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslhv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslw_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslw_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslwv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vaslwv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrh_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrh_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhbrndsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhbrndsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhbsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhbsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhubrndsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhubrndsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhubsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhubsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrhv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruhubrndsat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruhubrndsat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruhubsat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruhubsat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhrndsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhrndsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhsat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhsat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrw_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrw_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwhrndsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwhrndsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhrndsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhrndsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vasrwv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vassign, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vassign_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vassignp, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vassignp_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgb, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgb_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgbrnd, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgbrnd_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavghrnd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavghrnd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgubrnd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgubrnd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguhrnd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguhrnd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguw, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguw_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguwrnd, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavguwrnd_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgwrnd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vavgwrnd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vcl0h, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vcl0h_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vcl0w, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vcl0w_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vcombine, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vcombine_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vd0, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vd0_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdd0, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdd0_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealb4w, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealb4w_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealvdd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdealvdd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdelta, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdelta_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqb_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqh_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_veqw_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtb_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgth_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtub_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_and, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_and_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_or, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_or_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_xor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vgtw_xor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vinsertwr, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vinsertwr_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlalignb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlalignb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrb, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrb_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrhv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrhv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrwv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlsrwv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlut4, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlut4_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_nm, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_nm_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_nm, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_nm_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxb, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxb_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmaxw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminb, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminb_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vminw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabus, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabusv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabusv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabuuv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpabuuv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpahb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpahhsat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpahhsat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpauhuhsat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpauhuhsat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpsuhuhsat, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpsuhuhsat_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybus, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_64, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_64_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsat_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsat_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsrs, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsrs_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhss, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhss_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhvsrs, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyhvsrs_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyieoh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyieoh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewh_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewh_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyih, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiowh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiowh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_64_acc, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_64_acc_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_sacc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_sacc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_sacc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmux, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vmux_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgb, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgb_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnavgw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnormamth, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnormamth_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnormamtw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnormamtw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnot, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vnot_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackeb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackeb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackeh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackeh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackhb_sat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackhb_sat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackhub_sat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackhub_sat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackob, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackob_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackoh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackoh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackwh_sat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackwh_sat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackwuh_sat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpackwuh_sat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpopcounth, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vpopcounth_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vprefixqb, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vprefixqb_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vprefixqh, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vprefixqh_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vprefixqw, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vprefixqw_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrdelta, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrdelta_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_acc, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B, {"v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vror, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vror_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundhb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundhb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundhub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundhub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrounduhub, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrounduhub_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrounduwuh, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrounduwuh_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundwh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundwh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundwuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vroundwuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsathub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsathub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsatuwuh, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsatuwuh_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsatwh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsatwh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufeh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufeh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffeb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffeb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffob, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffob_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffvdd, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshuffvdd_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufoeb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufoeb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufoeh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufoeh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufoh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vshufoh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubb_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubb_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_dv, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_dv_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubcarry, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubcarry_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubh_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubh_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubhw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubhw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsububh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsububh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsububsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubububb_sat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubububb_sat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuhw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuhw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_dv, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_dv_128B, {"v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubw, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubw_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubw_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubw_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_dv, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_dv_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vswap, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vswap_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_acc, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_acc_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackob, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackob_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackoh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackoh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackub, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackub_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackuh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vunpackuh_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vxor, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vxor_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vzb, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vzb_128B, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vzh, {"v60", "v62", "v65"} }, - { Hexagon::BI__builtin_HEXAGON_V6_vzh_128B, {"v60", "v62", "v65"} }, + static BuiltinAndString ValidCPU[] = { + { Hexagon::BI__builtin_HEXAGON_A6_vcmpbeq_notany, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_A6_vminub_RdP, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_F2_dfadd, "v66" }, + { Hexagon::BI__builtin_HEXAGON_F2_dfsub, "v66" }, + { Hexagon::BI__builtin_HEXAGON_M2_mnaci, "v66" }, + { Hexagon::BI__builtin_HEXAGON_M6_vabsdiffb, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_M6_vabsdiffub, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S2_mask, "v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_nac, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_p_xacc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_nac, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_rol_i_r_xacc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_vsplatrbp, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_vtrunehb_ppp, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_S6_vtrunohb_ppp, "v62,v65,v66" }, + }; + + static BuiltinAndString ValidHVX[] = { + { Hexagon::BI__builtin_HEXAGON_V6_hi, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_hi_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lo, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lo_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_extractw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_extractw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lvsplatb, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lvsplatb_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lvsplath, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lvsplath_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lvsplatw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_lvsplatw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_and_n, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_and_n_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_not, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_not_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_or_n, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_or_n_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2v2, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_scalar2v2_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_pred_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_shuffeqh, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_shuffeqh_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_shuffeqw, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_shuffeqw_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsb, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsb_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsb_sat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsb_sat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsdiffw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsh_sat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsh_sat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsw_sat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vabsw_sat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddb_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddb_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_dv, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddbsat_dv_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddcarry, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddcarry_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddcarrysat, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddcarrysat_128B, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddclbh, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddclbh_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddclbw, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddclbw_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddh_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddh_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddhw_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubh_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddubsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddububb_sat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddububb_sat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduhw_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_dv, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vadduwsat_dv_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddw_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddw_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaddwsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_valignb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_valignb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_valignbi, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_valignbi_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vand, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vand_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandnqrt_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandqrt, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandqrt_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvnqv, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvnqv_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvqv, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvqv_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvrt, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vandvrt_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslh_acc, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslh_acc_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslhv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslhv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslw_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslw_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslwv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vaslwv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrh_acc, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrh_acc_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhbrndsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhbrndsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhbsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhbsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhubrndsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhubrndsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhubsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhubsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrhv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasr_into, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasr_into_128B, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruhubrndsat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruhubrndsat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruhubsat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruhubsat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhrndsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhrndsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhsat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasruwuhsat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrw_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrw_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwhrndsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwhrndsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhrndsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhrndsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwuhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vasrwv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vassign, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vassign_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vassignp, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vassignp_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgb, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgb_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgbrnd, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgbrnd_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavghrnd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavghrnd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgubrnd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgubrnd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguhrnd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguhrnd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguw, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguw_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguwrnd, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavguwrnd_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgwrnd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vavgwrnd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vcl0h, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vcl0h_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vcl0w, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vcl0w_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vcombine, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vcombine_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vd0, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vd0_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdd0, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdd0_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealb4w, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealb4w_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealvdd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdealvdd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdelta, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdelta_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhisat_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsat_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vdsaduh_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqb_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqh_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_veqw_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtb_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgth_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtub_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuh_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtuw_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_and, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_and_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_or, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_or_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_xor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vgtw_xor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vinsertwr, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vinsertwr_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlalignb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlalignb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlalignbi_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrb, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrb_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrhv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrhv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrwv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlsrwv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlut4, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlut4_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvbi_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_nm, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_nm_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvvb_oracci_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwhi_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_nm, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_nm_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vlutvwh_oracci_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxb, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxb_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmaxw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminb, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminb_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vminw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabus, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabus_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabusv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabusv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_acc, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabuu_acc_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabuuv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpabuuv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpahb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpahb_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpahhsat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpahhsat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpauhb_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpauhuhsat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpauhuhsat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpsuhuhsat, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpsuhuhsat_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybus, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybus_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybusv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpybv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_64, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyewuh_64_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_acc, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyh_acc_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsat_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsat_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsrs, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhsrs_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhss, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhss_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhus_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhvsrs, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyhvsrs_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyieoh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyieoh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewh_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewh_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiewuh_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyih, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyih_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyihb_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiowh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiowh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwb_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwh_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyiwub_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_64_acc, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_64_acc_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_sacc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_sacc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyowh_sacc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyub_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyubv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuh_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_acc, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhe_acc_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmpyuhv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmux, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vmux_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgb, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgb_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnavgw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnormamth, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnormamth_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnormamtw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnormamtw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnot, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vnot_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackeb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackeb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackeh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackeh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackhb_sat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackhb_sat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackhub_sat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackhub_sat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackob, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackob_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackoh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackoh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackwh_sat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackwh_sat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackwuh_sat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpackwuh_sat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpopcounth, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vpopcounth_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vprefixqb, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vprefixqb_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vprefixqh, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vprefixqh_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vprefixqw, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vprefixqw_128B, "v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrdelta, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrdelta_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_128B, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_acc, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybus_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusi_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybusv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpybv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubi_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_128B, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_acc, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B, "v65" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrmpyubv_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vror, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vror_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrotr, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrotr_128B, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundhb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundhb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundhub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundhub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrounduhub, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrounduhub_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrounduwuh, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrounduwuh_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundwh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundwh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundwuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vroundwuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vrsadubi_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsatdw, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsatdw_128B, "v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsathub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsathub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsatuwuh, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsatuwuh_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsatwh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsatwh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufeh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufeh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffeb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffeb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffob, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffob_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffvdd, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshuffvdd_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufoeb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufoeb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufoeh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufoeh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufoh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vshufoh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubb_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubb_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_dv, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubbsat_dv_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubcarry, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubcarry_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubh_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubh_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubhsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubhw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubhw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsububh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsububh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsububsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsububsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubububb_sat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubububb_sat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuhsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuhw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuhw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_dv, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubuwsat_dv_128B, "v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubw, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubw_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubw_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubw_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_dv, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vsubwsat_dv_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vswap, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vswap_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyb_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpybus_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_acc, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vtmpyhb_acc_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackob, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackob_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackoh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackoh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackub, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackub_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackuh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vunpackuh_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vxor, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vxor_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vzb, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vzb_128B, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vzh, "v60,v62,v65,v66" }, + { Hexagon::BI__builtin_HEXAGON_V6_vzh_128B, "v60,v62,v65,v66" }, + }; + + // Sort the tables on first execution so we can binary search them. + auto SortCmp = [](const BuiltinAndString &LHS, const BuiltinAndString &RHS) { + return LHS.BuiltinID < RHS.BuiltinID; + }; + static const bool SortOnce = + (std::sort(std::begin(ValidCPU), std::end(ValidCPU), SortCmp), + std::sort(std::begin(ValidHVX), std::end(ValidHVX), SortCmp), true); + (void)SortOnce; + auto LowerBoundCmp = [](const BuiltinAndString &BI, unsigned BuiltinID) { + return BI.BuiltinID < BuiltinID; }; const TargetInfo &TI = Context.getTargetInfo(); - auto FC = ValidCPU.find(BuiltinID); - if (FC != ValidCPU.end()) { + const BuiltinAndString *FC = + std::lower_bound(std::begin(ValidCPU), std::end(ValidCPU), BuiltinID, + LowerBoundCmp); + if (FC != std::end(ValidCPU) && FC->BuiltinID == BuiltinID) { const TargetOptions &Opts = TI.getTargetOpts(); StringRef CPU = Opts.CPU; if (!CPU.empty()) { assert(CPU.startswith("hexagon") && "Unexpected CPU name"); CPU.consume_front("hexagon"); - if (llvm::none_of(FC->second, [CPU](StringRef S) { return S == CPU; })) + SmallVector<StringRef, 3> CPUs; + StringRef(FC->Str).split(CPUs, ','); + if (llvm::none_of(CPUs, [CPU](StringRef S) { return S == CPU; })) return Diag(TheCall->getBeginLoc(), diag::err_hexagon_builtin_unsupported_cpu); } } - auto FH = ValidHVX.find(BuiltinID); - if (FH != ValidHVX.end()) { + const BuiltinAndString *FH = + std::lower_bound(std::begin(ValidHVX), std::end(ValidHVX), BuiltinID, + LowerBoundCmp); + if (FH != std::end(ValidHVX) && FH->BuiltinID == BuiltinID) { if (!TI.hasFeature("hvx")) return Diag(TheCall->getBeginLoc(), diag::err_hexagon_builtin_requires_hvx); - bool IsValid = llvm::any_of(FH->second, + SmallVector<StringRef, 3> HVXs; + StringRef(FH->Str).split(HVXs, ','); + bool IsValid = llvm::any_of(HVXs, [&TI] (StringRef V) { std::string F = "hvx" + V.str(); return TI.hasFeature(F); @@ -2551,15 +2661,17 @@ bool Sema::CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall) { bool Sema::CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { struct ArgInfo { - ArgInfo(unsigned O, bool S, unsigned W, unsigned A) - : OpNum(O), IsSigned(S), BitWidth(W), Align(A) {} - unsigned OpNum = 0; - bool IsSigned = false; - unsigned BitWidth = 0; - unsigned Align = 0; + uint8_t OpNum; + bool IsSigned; + uint8_t BitWidth; + uint8_t Align; + }; + struct BuiltinInfo { + unsigned BuiltinID; + ArgInfo Infos[2]; }; - static const std::map<unsigned, std::vector<ArgInfo>> Infos = { + static BuiltinInfo Infos[] = { { Hexagon::BI__builtin_circ_ldd, {{ 3, true, 4, 3 }} }, { Hexagon::BI__builtin_circ_ldw, {{ 3, true, 4, 2 }} }, { Hexagon::BI__builtin_circ_ldh, {{ 3, true, 4, 1 }} }, @@ -2745,15 +2857,33 @@ bool Sema::CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall) { {{ 3, false, 1, 0 }} }, }; - auto F = Infos.find(BuiltinID); - if (F == Infos.end()) + // Use a dynamically initialized static to sort the table exactly once on + // first run. + static const bool SortOnce = + (std::sort(std::begin(Infos), std::end(Infos), + [](const BuiltinInfo &LHS, const BuiltinInfo &RHS) { + return LHS.BuiltinID < RHS.BuiltinID; + }), + true); + (void)SortOnce; + + const BuiltinInfo *F = + std::lower_bound(std::begin(Infos), std::end(Infos), BuiltinID, + [](const BuiltinInfo &BI, unsigned BuiltinID) { + return BI.BuiltinID < BuiltinID; + }); + if (F == std::end(Infos) || F->BuiltinID != BuiltinID) return false; bool Error = false; - for (const ArgInfo &A : F->second) { - int32_t Min = A.IsSigned ? -(1 << (A.BitWidth-1)) : 0; - int32_t Max = (1 << (A.IsSigned ? A.BitWidth-1 : A.BitWidth)) - 1; + for (const ArgInfo &A : F->Infos) { + // Ignore empty ArgInfo elements. + if (A.BitWidth == 0) + continue; + + int32_t Min = A.IsSigned ? -(1 << (A.BitWidth - 1)) : 0; + int32_t Max = (1 << (A.IsSigned ? A.BitWidth - 1 : A.BitWidth)) - 1; if (!A.Align) { Error |= SemaBuiltinConstantArgRange(TheCall, A.OpNum, Min, Max); } else { @@ -2794,7 +2924,7 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break; case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break; case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break; - // MSA instrinsics. Instructions (which the intrinsics maps to) which use the + // MSA intrinsics. Instructions (which the intrinsics maps to) which use the // df/m field. // These intrinsics take an unsigned 3 bit immediate. case Mips::BI__builtin_msa_bclri_b: @@ -2937,14 +3067,14 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Mips::BI__builtin_msa_ldi_h: case Mips::BI__builtin_msa_ldi_w: case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; - case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 16; break; - case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 16; break; - case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 16; break; - case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 16; break; - case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 16; break; - case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 16; break; - case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 16; break; - case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 16; break; + case Mips::BI__builtin_msa_ld_b: i = 1; l = -512; u = 511; m = 1; break; + case Mips::BI__builtin_msa_ld_h: i = 1; l = -1024; u = 1022; m = 2; break; + case Mips::BI__builtin_msa_ld_w: i = 1; l = -2048; u = 2044; m = 4; break; + case Mips::BI__builtin_msa_ld_d: i = 1; l = -4096; u = 4088; m = 8; break; + case Mips::BI__builtin_msa_st_b: i = 2; l = -512; u = 511; m = 1; break; + case Mips::BI__builtin_msa_st_h: i = 2; l = -1024; u = 1022; m = 2; break; + case Mips::BI__builtin_msa_st_w: i = 2; l = -2048; u = 2044; m = 4; break; + case Mips::BI__builtin_msa_st_d: i = 2; l = -4096; u = 4088; m = 8; break; } if (!m) @@ -4110,7 +4240,7 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, CheckAbsoluteValueFunction(TheCall, FDecl); CheckMaxUnsignedZero(TheCall, FDecl); - if (getLangOpts().ObjC1) + if (getLangOpts().ObjC) DiagnoseCStringFormatDirectiveInCFAPI(*this, FDecl, Args, NumArgs); unsigned CMId = FDecl->getMemoryFunctionKind(); @@ -5692,7 +5822,8 @@ bool Sema::SemaBuiltinAllocaWithAlign(CallExpr *TheCall) { if (!Arg->isTypeDependent() && !Arg->isValueDependent()) { if (const auto *UE = dyn_cast<UnaryExprOrTypeTraitExpr>(Arg->IgnoreParenImpCasts())) - if (UE->getKind() == UETT_AlignOf) + if (UE->getKind() == UETT_AlignOf || + UE->getKind() == UETT_PreferredAlignOf) Diag(TheCall->getBeginLoc(), diag::warn_alloca_align_alignof) << Arg->getSourceRange(); @@ -6427,13 +6558,12 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, return SLCT_NotALiteral; } case Stmt::BinaryOperatorClass: { - llvm::APSInt LResult; - llvm::APSInt RResult; - const BinaryOperator *BinOp = cast<BinaryOperator>(E); // A string literal + an int offset is still a string literal. if (BinOp->isAdditiveOp()) { + Expr::EvalResult LResult, RResult; + bool LIsInt = BinOp->getLHS()->EvaluateAsInt(LResult, S.Context); bool RIsInt = BinOp->getRHS()->EvaluateAsInt(RResult, S.Context); @@ -6442,12 +6572,12 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, if (LIsInt) { if (BinOpKind == BO_Add) { - sumOffsets(Offset, LResult, BinOpKind, RIsInt); + sumOffsets(Offset, LResult.Val.getInt(), BinOpKind, RIsInt); E = BinOp->getRHS(); goto tryAgain; } } else { - sumOffsets(Offset, RResult, BinOpKind, RIsInt); + sumOffsets(Offset, RResult.Val.getInt(), BinOpKind, RIsInt); E = BinOp->getLHS(); goto tryAgain; } @@ -6460,9 +6590,10 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, const UnaryOperator *UnaOp = cast<UnaryOperator>(E); auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->getSubExpr()); if (UnaOp->getOpcode() == UO_AddrOf && ASE) { - llvm::APSInt IndexResult; + Expr::EvalResult IndexResult; if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.Context)) { - sumOffsets(Offset, IndexResult, BO_Add, /*RHS is int*/ true); + sumOffsets(Offset, IndexResult.Val.getInt(), BO_Add, + /*RHS is int*/ true); E = ASE->getBase(); goto tryAgain; } @@ -7079,6 +7210,8 @@ public: const char *startSpecifier, unsigned specifierLen) override; + void handleInvalidMaskType(StringRef MaskType) override; + bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen) override; @@ -7130,6 +7263,10 @@ bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier( CS.getStart(), CS.getLength()); } +void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) { + S.Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size); +} + bool CheckPrintfHandler::HandleAmount( const analyze_format_string::OptionalAmount &Amt, unsigned k, const char *startSpecifier, @@ -10201,8 +10338,8 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, Expr *OriginalInit = Init->IgnoreParenImpCasts(); unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); - llvm::APSInt Value; - if (!OriginalInit->EvaluateAsInt(Value, S.Context, + Expr::EvalResult Result; + if (!OriginalInit->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) { // The RHS is not constant. If the RHS has an enum type, make sure the // bitfield is wide enough to hold all the values of the enum without @@ -10258,6 +10395,8 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, return false; } + llvm::APSInt Value = Result.Val.getInt(); + unsigned OriginalWidth = Value.getBitWidth(); if (!Value.isSigned() || Value.isNegative()) @@ -10310,7 +10449,7 @@ static void AnalyzeAssignment(Sema &S, BinaryOperator *E) { } AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); - + // Diagnose implicitly sequentially-consistent atomic assignment. if (E->getLHS()->getType()->isAtomicType()) S.Diag(E->getRHS()->getBeginLoc(), diag::warn_atomic_implicit_seq_cst); @@ -10870,8 +11009,11 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, if (SourceRange.Width > TargetRange.Width) { // If the source is a constant, use a default-on diagnostic. // TODO: this should happen for bitfield stores, too. - llvm::APSInt Value(32); - if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects)) { + Expr::EvalResult Result; + if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) { + llvm::APSInt Value(32); + Value = Result.Val.getInt(); + if (S.SourceMgr.isInSystemMacro(CC)) return; @@ -10896,15 +11038,29 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision); } + if (TargetRange.Width > SourceRange.Width) { + if (auto *UO = dyn_cast<UnaryOperator>(E)) + if (UO->getOpcode() == UO_Minus) + if (Source->isUnsignedIntegerType()) { + if (Target->isUnsignedIntegerType()) + return DiagnoseImpCast(S, E, T, CC, + diag::warn_impcast_high_order_zero_bits); + if (Target->isSignedIntegerType()) + return DiagnoseImpCast(S, E, T, CC, + diag::warn_impcast_nonnegative_result); + } + } + if (TargetRange.Width == SourceRange.Width && !TargetRange.NonNegative && SourceRange.NonNegative && Source->isSignedIntegerType()) { // Warn when doing a signed to signed conversion, warn if the positive // source value is exactly the width of the target type, which will // cause a negative value to be stored. - llvm::APSInt Value; - if (E->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects) && + Expr::EvalResult Result; + if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects) && !S.SourceMgr.isInSystemMacro(CC)) { + llvm::APSInt Value = Result.Val.getInt(); if (isSameWidthConstantConversion(S, E, T, CC)) { std::string PrettySourceValue = Value.toString(10); std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange); @@ -12059,6 +12215,18 @@ bool Sema::CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters, if (!Param->getType().isConstQualified()) Diag(Param->getLocation(), diag::err_attribute_pointers_only) << Attr->getSpelling() << 1; + + // Check for parameter names shadowing fields from the class. + if (LangOpts.CPlusPlus && !Param->isInvalidDecl()) { + // The owning context for the parameter should be the function, but we + // want to see if this function's declaration context is a record. + DeclContext *DC = Param->getDeclContext(); + if (DC && DC->isFunctionOrMethod()) { + if (auto *RD = dyn_cast<CXXRecordDecl>(DC->getParent())) + CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(), + RD, /*DeclIsField*/ false); + } + } } return HasInvalidParm; @@ -12191,9 +12359,11 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, if (!ArrayTy) return; - llvm::APSInt index; - if (!IndexExpr->EvaluateAsInt(index, Context, Expr::SE_AllowSideEffects)) + Expr::EvalResult Result; + if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects)) return; + + llvm::APSInt index = Result.Val.getInt(); if (IndexNegated) index = -index; diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index acf43650bb..773dd46ac4 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -10,6 +10,8 @@ // This file defines the code-completion semantic actions. // //===----------------------------------------------------------------------===// +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" @@ -42,315 +44,309 @@ using namespace clang; using namespace sema; namespace { - /// A container of code-completion results. - class ResultBuilder { - public: - /// The type of a name-lookup filter, which can be provided to the - /// name-lookup routines to specify which declarations should be included in - /// the result set (when it returns true) and which declarations should be - /// filtered out (returns false). - typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const; - - typedef CodeCompletionResult Result; +/// A container of code-completion results. +class ResultBuilder { +public: + /// The type of a name-lookup filter, which can be provided to the + /// name-lookup routines to specify which declarations should be included in + /// the result set (when it returns true) and which declarations should be + /// filtered out (returns false). + typedef bool (ResultBuilder::*LookupFilter)(const NamedDecl *) const; - private: - /// The actual results we have found. - std::vector<Result> Results; + typedef CodeCompletionResult Result; - /// A record of all of the declarations we have found and placed - /// into the result set, used to ensure that no declaration ever gets into - /// the result set twice. - llvm::SmallPtrSet<const Decl*, 16> AllDeclsFound; +private: + /// The actual results we have found. + std::vector<Result> Results; - typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair; + /// A record of all of the declarations we have found and placed + /// into the result set, used to ensure that no declaration ever gets into + /// the result set twice. + llvm::SmallPtrSet<const Decl *, 16> AllDeclsFound; - /// An entry in the shadow map, which is optimized to store - /// a single (declaration, index) mapping (the common case) but - /// can also store a list of (declaration, index) mappings. - class ShadowMapEntry { - typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector; + typedef std::pair<const NamedDecl *, unsigned> DeclIndexPair; - /// Contains either the solitary NamedDecl * or a vector - /// of (declaration, index) pairs. - llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector*> DeclOrVector; + /// An entry in the shadow map, which is optimized to store + /// a single (declaration, index) mapping (the common case) but + /// can also store a list of (declaration, index) mappings. + class ShadowMapEntry { + typedef SmallVector<DeclIndexPair, 4> DeclIndexPairVector; - /// When the entry contains a single declaration, this is - /// the index associated with that entry. - unsigned SingleDeclIndex; + /// Contains either the solitary NamedDecl * or a vector + /// of (declaration, index) pairs. + llvm::PointerUnion<const NamedDecl *, DeclIndexPairVector *> DeclOrVector; - public: - ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { } + /// When the entry contains a single declaration, this is + /// the index associated with that entry. + unsigned SingleDeclIndex; - void Add(const NamedDecl *ND, unsigned Index) { - if (DeclOrVector.isNull()) { - // 0 - > 1 elements: just set the single element information. - DeclOrVector = ND; - SingleDeclIndex = Index; - return; - } + public: + ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) {} - if (const NamedDecl *PrevND = - DeclOrVector.dyn_cast<const NamedDecl *>()) { - // 1 -> 2 elements: create the vector of results and push in the - // existing declaration. - DeclIndexPairVector *Vec = new DeclIndexPairVector; - Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex)); - DeclOrVector = Vec; - } + void Add(const NamedDecl *ND, unsigned Index) { + if (DeclOrVector.isNull()) { + // 0 - > 1 elements: just set the single element information. + DeclOrVector = ND; + SingleDeclIndex = Index; + return; + } - // Add the new element to the end of the vector. - DeclOrVector.get<DeclIndexPairVector*>()->push_back( - DeclIndexPair(ND, Index)); + if (const NamedDecl *PrevND = + DeclOrVector.dyn_cast<const NamedDecl *>()) { + // 1 -> 2 elements: create the vector of results and push in the + // existing declaration. + DeclIndexPairVector *Vec = new DeclIndexPairVector; + Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex)); + DeclOrVector = Vec; } - void Destroy() { - if (DeclIndexPairVector *Vec - = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) { - delete Vec; - DeclOrVector = ((NamedDecl *)nullptr); - } + // Add the new element to the end of the vector. + DeclOrVector.get<DeclIndexPairVector *>()->push_back( + DeclIndexPair(ND, Index)); + } + + void Destroy() { + if (DeclIndexPairVector *Vec = + DeclOrVector.dyn_cast<DeclIndexPairVector *>()) { + delete Vec; + DeclOrVector = ((NamedDecl *)nullptr); } + } - // Iteration. - class iterator; - iterator begin() const; - iterator end() const; - }; + // Iteration. + class iterator; + iterator begin() const; + iterator end() const; + }; - /// A mapping from declaration names to the declarations that have - /// this name within a particular scope and their index within the list of - /// results. - typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap; + /// A mapping from declaration names to the declarations that have + /// this name within a particular scope and their index within the list of + /// results. + typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap; - /// The semantic analysis object for which results are being - /// produced. - Sema &SemaRef; + /// The semantic analysis object for which results are being + /// produced. + Sema &SemaRef; - /// The allocator used to allocate new code-completion strings. - CodeCompletionAllocator &Allocator; + /// The allocator used to allocate new code-completion strings. + CodeCompletionAllocator &Allocator; - CodeCompletionTUInfo &CCTUInfo; + CodeCompletionTUInfo &CCTUInfo; - /// If non-NULL, a filter function used to remove any code-completion - /// results that are not desirable. - LookupFilter Filter; + /// If non-NULL, a filter function used to remove any code-completion + /// results that are not desirable. + LookupFilter Filter; - /// Whether we should allow declarations as - /// nested-name-specifiers that would otherwise be filtered out. - bool AllowNestedNameSpecifiers; + /// Whether we should allow declarations as + /// nested-name-specifiers that would otherwise be filtered out. + bool AllowNestedNameSpecifiers; - /// If set, the type that we would prefer our resulting value - /// declarations to have. - /// - /// Closely matching the preferred type gives a boost to a result's - /// priority. - CanQualType PreferredType; + /// If set, the type that we would prefer our resulting value + /// declarations to have. + /// + /// Closely matching the preferred type gives a boost to a result's + /// priority. + CanQualType PreferredType; - /// A list of shadow maps, which is used to model name hiding at - /// different levels of, e.g., the inheritance hierarchy. - std::list<ShadowMap> ShadowMaps; + /// A list of shadow maps, which is used to model name hiding at + /// different levels of, e.g., the inheritance hierarchy. + std::list<ShadowMap> ShadowMaps; - /// If we're potentially referring to a C++ member function, the set - /// of qualifiers applied to the object type. - Qualifiers ObjectTypeQualifiers; + /// If we're potentially referring to a C++ member function, the set + /// of qualifiers applied to the object type. + Qualifiers ObjectTypeQualifiers; - /// Whether the \p ObjectTypeQualifiers field is active. - bool HasObjectTypeQualifiers; + /// Whether the \p ObjectTypeQualifiers field is active. + bool HasObjectTypeQualifiers; - /// The selector that we prefer. - Selector PreferredSelector; + /// The selector that we prefer. + Selector PreferredSelector; - /// The completion context in which we are gathering results. - CodeCompletionContext CompletionContext; + /// The completion context in which we are gathering results. + CodeCompletionContext CompletionContext; - /// If we are in an instance method definition, the \@implementation - /// object. - ObjCImplementationDecl *ObjCImplementation; + /// If we are in an instance method definition, the \@implementation + /// object. + ObjCImplementationDecl *ObjCImplementation; - void AdjustResultPriorityForDecl(Result &R); + void AdjustResultPriorityForDecl(Result &R); - void MaybeAddConstructorResults(Result R); + void MaybeAddConstructorResults(Result R); - public: - explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - const CodeCompletionContext &CompletionContext, - LookupFilter Filter = nullptr) +public: + explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, + const CodeCompletionContext &CompletionContext, + LookupFilter Filter = nullptr) : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo), - Filter(Filter), - AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), - CompletionContext(CompletionContext), - ObjCImplementation(nullptr) - { - // If this is an Objective-C instance method definition, dig out the - // corresponding implementation. - switch (CompletionContext.getKind()) { - case CodeCompletionContext::CCC_Expression: - case CodeCompletionContext::CCC_ObjCMessageReceiver: - case CodeCompletionContext::CCC_ParenthesizedExpression: - case CodeCompletionContext::CCC_Statement: - case CodeCompletionContext::CCC_Recovery: - if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) - if (Method->isInstanceMethod()) - if (ObjCInterfaceDecl *Interface = Method->getClassInterface()) - ObjCImplementation = Interface->getImplementation(); - break; + Filter(Filter), AllowNestedNameSpecifiers(false), + HasObjectTypeQualifiers(false), CompletionContext(CompletionContext), + ObjCImplementation(nullptr) { + // If this is an Objective-C instance method definition, dig out the + // corresponding implementation. + switch (CompletionContext.getKind()) { + case CodeCompletionContext::CCC_Expression: + case CodeCompletionContext::CCC_ObjCMessageReceiver: + case CodeCompletionContext::CCC_ParenthesizedExpression: + case CodeCompletionContext::CCC_Statement: + case CodeCompletionContext::CCC_Recovery: + if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) + if (Method->isInstanceMethod()) + if (ObjCInterfaceDecl *Interface = Method->getClassInterface()) + ObjCImplementation = Interface->getImplementation(); + break; - default: - break; - } - } - - /// Determine the priority for a reference to the given declaration. - unsigned getBasePriority(const NamedDecl *D); - - /// Whether we should include code patterns in the completion - /// results. - bool includeCodePatterns() const { - return SemaRef.CodeCompleter && - SemaRef.CodeCompleter->includeCodePatterns(); - } - - /// Set the filter used for code-completion results. - void setFilter(LookupFilter Filter) { - this->Filter = Filter; - } - - Result *data() { return Results.empty()? nullptr : &Results.front(); } - unsigned size() const { return Results.size(); } - bool empty() const { return Results.empty(); } - - /// Specify the preferred type. - void setPreferredType(QualType T) { - PreferredType = SemaRef.Context.getCanonicalType(T); + default: + break; } + } - /// Set the cv-qualifiers on the object type, for us in filtering - /// calls to member functions. - /// - /// When there are qualifiers in this set, they will be used to filter - /// out member functions that aren't available (because there will be a - /// cv-qualifier mismatch) or prefer functions with an exact qualifier - /// match. - void setObjectTypeQualifiers(Qualifiers Quals) { - ObjectTypeQualifiers = Quals; - HasObjectTypeQualifiers = true; - } - - /// Set the preferred selector. - /// - /// When an Objective-C method declaration result is added, and that - /// method's selector matches this preferred selector, we give that method - /// a slight priority boost. - void setPreferredSelector(Selector Sel) { - PreferredSelector = Sel; - } - - /// Retrieve the code-completion context for which results are - /// being collected. - const CodeCompletionContext &getCompletionContext() const { - return CompletionContext; - } - - /// Specify whether nested-name-specifiers are allowed. - void allowNestedNameSpecifiers(bool Allow = true) { - AllowNestedNameSpecifiers = Allow; - } - - /// Return the semantic analysis object for which we are collecting - /// code completion results. - Sema &getSema() const { return SemaRef; } - - /// Retrieve the allocator used to allocate code completion strings. - CodeCompletionAllocator &getAllocator() const { return Allocator; } - - CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; } - - /// Determine whether the given declaration is at all interesting - /// as a code-completion result. - /// - /// \param ND the declaration that we are inspecting. - /// - /// \param AsNestedNameSpecifier will be set true if this declaration is - /// only interesting when it is a nested-name-specifier. - bool isInterestingDecl(const NamedDecl *ND, - bool &AsNestedNameSpecifier) const; - - /// Check whether the result is hidden by the Hiding declaration. - /// - /// \returns true if the result is hidden and cannot be found, false if - /// the hidden result could still be found. When false, \p R may be - /// modified to describe how the result can be found (e.g., via extra - /// qualification). - bool CheckHiddenResult(Result &R, DeclContext *CurContext, - const NamedDecl *Hiding); - - /// Add a new result to this result set (if it isn't already in one - /// of the shadow maps), or replace an existing result (for, e.g., a - /// redeclaration). - /// - /// \param R the result to add (if it is unique). - /// - /// \param CurContext the context in which this result will be named. - void MaybeAddResult(Result R, DeclContext *CurContext = nullptr); - - /// Add a new result to this result set, where we already know - /// the hiding declaration (if any). - /// - /// \param R the result to add (if it is unique). - /// - /// \param CurContext the context in which this result will be named. - /// - /// \param Hiding the declaration that hides the result. - /// - /// \param InBaseClass whether the result was found in a base - /// class of the searched context. - void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, - bool InBaseClass); - - /// Add a new non-declaration result to this result set. - void AddResult(Result R); - - /// Enter into a new scope. - void EnterNewScope(); - - /// Exit from the current scope. - void ExitScope(); - - /// Ignore this declaration, if it is seen again. - void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); } - - /// Add a visited context. - void addVisitedContext(DeclContext *Ctx) { - CompletionContext.addVisitedContext(Ctx); - } - - /// \name Name lookup predicates - /// - /// These predicates can be passed to the name lookup functions to filter the - /// results of name lookup. All of the predicates have the same type, so that - /// - //@{ - bool IsOrdinaryName(const NamedDecl *ND) const; - bool IsOrdinaryNonTypeName(const NamedDecl *ND) const; - bool IsIntegralConstantValue(const NamedDecl *ND) const; - bool IsOrdinaryNonValueName(const NamedDecl *ND) const; - bool IsNestedNameSpecifier(const NamedDecl *ND) const; - bool IsEnum(const NamedDecl *ND) const; - bool IsClassOrStruct(const NamedDecl *ND) const; - bool IsUnion(const NamedDecl *ND) const; - bool IsNamespace(const NamedDecl *ND) const; - bool IsNamespaceOrAlias(const NamedDecl *ND) const; - bool IsType(const NamedDecl *ND) const; - bool IsMember(const NamedDecl *ND) const; - bool IsObjCIvar(const NamedDecl *ND) const; - bool IsObjCMessageReceiver(const NamedDecl *ND) const; - bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const; - bool IsObjCCollection(const NamedDecl *ND) const; - bool IsImpossibleToSatisfy(const NamedDecl *ND) const; - //@} - }; -} + /// Determine the priority for a reference to the given declaration. + unsigned getBasePriority(const NamedDecl *D); + + /// Whether we should include code patterns in the completion + /// results. + bool includeCodePatterns() const { + return SemaRef.CodeCompleter && + SemaRef.CodeCompleter->includeCodePatterns(); + } + + /// Set the filter used for code-completion results. + void setFilter(LookupFilter Filter) { this->Filter = Filter; } + + Result *data() { return Results.empty() ? nullptr : &Results.front(); } + unsigned size() const { return Results.size(); } + bool empty() const { return Results.empty(); } + + /// Specify the preferred type. + void setPreferredType(QualType T) { + PreferredType = SemaRef.Context.getCanonicalType(T); + } + + /// Set the cv-qualifiers on the object type, for us in filtering + /// calls to member functions. + /// + /// When there are qualifiers in this set, they will be used to filter + /// out member functions that aren't available (because there will be a + /// cv-qualifier mismatch) or prefer functions with an exact qualifier + /// match. + void setObjectTypeQualifiers(Qualifiers Quals) { + ObjectTypeQualifiers = Quals; + HasObjectTypeQualifiers = true; + } + + /// Set the preferred selector. + /// + /// When an Objective-C method declaration result is added, and that + /// method's selector matches this preferred selector, we give that method + /// a slight priority boost. + void setPreferredSelector(Selector Sel) { PreferredSelector = Sel; } + + /// Retrieve the code-completion context for which results are + /// being collected. + const CodeCompletionContext &getCompletionContext() const { + return CompletionContext; + } + + /// Specify whether nested-name-specifiers are allowed. + void allowNestedNameSpecifiers(bool Allow = true) { + AllowNestedNameSpecifiers = Allow; + } + + /// Return the semantic analysis object for which we are collecting + /// code completion results. + Sema &getSema() const { return SemaRef; } + + /// Retrieve the allocator used to allocate code completion strings. + CodeCompletionAllocator &getAllocator() const { return Allocator; } + + CodeCompletionTUInfo &getCodeCompletionTUInfo() const { return CCTUInfo; } + + /// Determine whether the given declaration is at all interesting + /// as a code-completion result. + /// + /// \param ND the declaration that we are inspecting. + /// + /// \param AsNestedNameSpecifier will be set true if this declaration is + /// only interesting when it is a nested-name-specifier. + bool isInterestingDecl(const NamedDecl *ND, + bool &AsNestedNameSpecifier) const; + + /// Check whether the result is hidden by the Hiding declaration. + /// + /// \returns true if the result is hidden and cannot be found, false if + /// the hidden result could still be found. When false, \p R may be + /// modified to describe how the result can be found (e.g., via extra + /// qualification). + bool CheckHiddenResult(Result &R, DeclContext *CurContext, + const NamedDecl *Hiding); + + /// Add a new result to this result set (if it isn't already in one + /// of the shadow maps), or replace an existing result (for, e.g., a + /// redeclaration). + /// + /// \param R the result to add (if it is unique). + /// + /// \param CurContext the context in which this result will be named. + void MaybeAddResult(Result R, DeclContext *CurContext = nullptr); + + /// Add a new result to this result set, where we already know + /// the hiding declaration (if any). + /// + /// \param R the result to add (if it is unique). + /// + /// \param CurContext the context in which this result will be named. + /// + /// \param Hiding the declaration that hides the result. + /// + /// \param InBaseClass whether the result was found in a base + /// class of the searched context. + void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, + bool InBaseClass); + + /// Add a new non-declaration result to this result set. + void AddResult(Result R); + + /// Enter into a new scope. + void EnterNewScope(); + + /// Exit from the current scope. + void ExitScope(); + + /// Ignore this declaration, if it is seen again. + void Ignore(const Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); } + + /// Add a visited context. + void addVisitedContext(DeclContext *Ctx) { + CompletionContext.addVisitedContext(Ctx); + } + + /// \name Name lookup predicates + /// + /// These predicates can be passed to the name lookup functions to filter the + /// results of name lookup. All of the predicates have the same type, so that + /// + //@{ + bool IsOrdinaryName(const NamedDecl *ND) const; + bool IsOrdinaryNonTypeName(const NamedDecl *ND) const; + bool IsIntegralConstantValue(const NamedDecl *ND) const; + bool IsOrdinaryNonValueName(const NamedDecl *ND) const; + bool IsNestedNameSpecifier(const NamedDecl *ND) const; + bool IsEnum(const NamedDecl *ND) const; + bool IsClassOrStruct(const NamedDecl *ND) const; + bool IsUnion(const NamedDecl *ND) const; + bool IsNamespace(const NamedDecl *ND) const; + bool IsNamespaceOrAlias(const NamedDecl *ND) const; + bool IsType(const NamedDecl *ND) const; + bool IsMember(const NamedDecl *ND) const; + bool IsObjCIvar(const NamedDecl *ND) const; + bool IsObjCMessageReceiver(const NamedDecl *ND) const; + bool IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const; + bool IsObjCCollection(const NamedDecl *ND) const; + bool IsImpossibleToSatisfy(const NamedDecl *ND) const; + //@} +}; +} // namespace class ResultBuilder::ShadowMapEntry::iterator { llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator; @@ -366,20 +362,18 @@ public: DeclIndexPair Value; public: - pointer(const DeclIndexPair &Value) : Value(Value) { } + pointer(const DeclIndexPair &Value) : Value(Value) {} - const DeclIndexPair *operator->() const { - return &Value; - } + const DeclIndexPair *operator->() const { return &Value; } }; iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {} iterator(const NamedDecl *SingleDecl, unsigned Index) - : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { } + : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) {} iterator(const DeclIndexPair *Iterator) - : DeclOrIterator(Iterator), SingleDeclIndex(0) { } + : DeclOrIterator(Iterator), SingleDeclIndex(0) {} iterator &operator++() { if (DeclOrIterator.is<const NamedDecl *>()) { @@ -388,7 +382,7 @@ public: return *this; } - const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>(); + const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair *>(); ++I; DeclOrIterator = I; return *this; @@ -404,17 +398,15 @@ public: if (const NamedDecl *ND = DeclOrIterator.dyn_cast<const NamedDecl *>()) return reference(ND, SingleDeclIndex); - return *DeclOrIterator.get<const DeclIndexPair*>(); + return *DeclOrIterator.get<const DeclIndexPair *>(); } - pointer operator->() const { - return pointer(**this); - } + pointer operator->() const { return pointer(**this); } friend bool operator==(const iterator &X, const iterator &Y) { - return X.DeclOrIterator.getOpaqueValue() - == Y.DeclOrIterator.getOpaqueValue() && - X.SingleDeclIndex == Y.SingleDeclIndex; + return X.DeclOrIterator.getOpaqueValue() == + Y.DeclOrIterator.getOpaqueValue() && + X.SingleDeclIndex == Y.SingleDeclIndex; } friend bool operator!=(const iterator &X, const iterator &Y) { @@ -455,8 +447,7 @@ ResultBuilder::ShadowMapEntry::end() const { /// \returns a nested name specifier that refers into the target context, or /// NULL if no qualification is needed. static NestedNameSpecifier * -getRequiredQualification(ASTContext &Context, - const DeclContext *CurContext, +getRequiredQualification(ASTContext &Context, const DeclContext *CurContext, const DeclContext *TargetContext) { SmallVector<const DeclContext *, 4> TargetParents; @@ -474,16 +465,14 @@ getRequiredQualification(ASTContext &Context, while (!TargetParents.empty()) { const DeclContext *Parent = TargetParents.pop_back_val(); - if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) { + if (const auto *Namespace = dyn_cast<NamespaceDecl>(Parent)) { if (!Namespace->getIdentifier()) continue; Result = NestedNameSpecifier::Create(Context, Result, Namespace); - } - else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent)) - Result = NestedNameSpecifier::Create(Context, Result, - false, - Context.getTypeDeclType(TD).getTypePtr()); + } else if (const auto *TD = dyn_cast<TagDecl>(Parent)) + Result = NestedNameSpecifier::Create( + Context, Result, false, Context.getTypeDeclType(TD).getTypePtr()); } return Result; } @@ -496,8 +485,8 @@ static bool isReservedName(const IdentifierInfo *Id, return false; const char *Name = Id->getNameStart(); return Name[0] == '_' && - (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z' && - !doubleUnderscoreOnly)); + (Name[1] == '_' || + (Name[1] >= 'A' && Name[1] <= 'Z' && !doubleUnderscoreOnly)); } // Some declarations have reserved names that we don't want to ever show. @@ -516,9 +505,9 @@ static bool shouldIgnoreDueToReservedName(const NamedDecl *ND, Sema &SemaRef) { // This allows for system headers providing private symbols with a single // underscore. if (isReservedName(Id, /*doubleUnderscoreOnly=*/true) && - SemaRef.SourceMgr.isInSystemHeader( - SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))) - return true; + SemaRef.SourceMgr.isInSystemHeader( + SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))) + return true; return false; } @@ -552,10 +541,8 @@ bool ResultBuilder::isInterestingDecl(const NamedDecl *ND, return false; if (Filter == &ResultBuilder::IsNestedNameSpecifier || - (isa<NamespaceDecl>(ND) && - Filter != &ResultBuilder::IsNamespace && - Filter != &ResultBuilder::IsNamespaceOrAlias && - Filter != nullptr)) + (isa<NamespaceDecl>(ND) && Filter != &ResultBuilder::IsNamespace && + Filter != &ResultBuilder::IsNamespaceOrAlias && Filter != nullptr)) AsNestedNameSpecifier = true; // Filter out any unwanted results. @@ -599,8 +586,7 @@ bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext, R.QualifierIsInformative = false; if (!R.Qualifier) - R.Qualifier = getRequiredQualification(SemaRef.Context, - CurContext, + R.Qualifier = getRequiredQualification(SemaRef.Context, CurContext, R.Declaration->getDeclContext()); return false; } @@ -611,23 +597,23 @@ SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) { switch (T->getTypeClass()) { case Type::Builtin: switch (cast<BuiltinType>(T)->getKind()) { - case BuiltinType::Void: - return STC_Void; + case BuiltinType::Void: + return STC_Void; - case BuiltinType::NullPtr: - return STC_Pointer; + case BuiltinType::NullPtr: + return STC_Pointer; - case BuiltinType::Overload: - case BuiltinType::Dependent: - return STC_Other; + case BuiltinType::Overload: + case BuiltinType::Dependent: + return STC_Other; - case BuiltinType::ObjCId: - case BuiltinType::ObjCClass: - case BuiltinType::ObjCSel: - return STC_ObjectiveC; + case BuiltinType::ObjCId: + case BuiltinType::ObjCClass: + case BuiltinType::ObjCSel: + return STC_ObjectiveC; - default: - return STC_Arithmetic; + default: + return STC_Arithmetic; } case Type::Complex: @@ -679,21 +665,21 @@ SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) { QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { ND = ND->getUnderlyingDecl(); - if (const TypeDecl *Type = dyn_cast<TypeDecl>(ND)) + if (const auto *Type = dyn_cast<TypeDecl>(ND)) return C.getTypeDeclType(Type); - if (const ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND)) + if (const auto *Iface = dyn_cast<ObjCInterfaceDecl>(ND)) return C.getObjCInterfaceType(Iface); QualType T; if (const FunctionDecl *Function = ND->getAsFunction()) T = Function->getCallResultType(); - else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) + else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) T = Method->getSendResultType(); - else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) + else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext())); - else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) + else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) T = Property->getType(); - else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) + else if (const auto *Value = dyn_cast<ValueDecl>(ND)) T = Value->getType(); else return QualType(); @@ -702,12 +688,12 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { // get down to the likely type of an expression when the entity is // used. do { - if (const ReferenceType *Ref = T->getAs<ReferenceType>()) { + if (const auto *Ref = T->getAs<ReferenceType>()) { T = Ref->getPointeeType(); continue; } - if (const PointerType *Pointer = T->getAs<PointerType>()) { + if (const auto *Pointer = T->getAs<PointerType>()) { if (Pointer->getPointeeType()->isFunctionType()) { T = Pointer->getPointeeType(); continue; @@ -716,12 +702,12 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) { break; } - if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) { + if (const auto *Block = T->getAs<BlockPointerType>()) { T = Block->getPointeeType(); continue; } - if (const FunctionType *Function = T->getAs<FunctionType>()) { + if (const auto *Function = T->getAs<FunctionType>()) { T = Function->getReturnType(); continue; } @@ -740,8 +726,7 @@ unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) { const DeclContext *LexicalDC = ND->getLexicalDeclContext(); if (LexicalDC->isFunctionOrMethod()) { // _cmd is relatively rare - if (const ImplicitParamDecl *ImplicitParam = - dyn_cast<ImplicitParamDecl>(ND)) + if (const auto *ImplicitParam = dyn_cast<ImplicitParamDecl>(ND)) if (ImplicitParam->getIdentifier() && ImplicitParam->getIdentifier()->isStr("_cmd")) return CCP_ObjC_cmd; @@ -772,10 +757,10 @@ unsigned ResultBuilder::getBasePriority(const NamedDecl *ND) { // likely that the user will want to write a type as other declarations. if ((isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) && !(CompletionContext.getKind() == CodeCompletionContext::CCC_Statement || - CompletionContext.getKind() - == CodeCompletionContext::CCC_ObjCMessageReceiver || - CompletionContext.getKind() - == CodeCompletionContext::CCC_ParenthesizedExpression)) + CompletionContext.getKind() == + CodeCompletionContext::CCC_ObjCMessageReceiver || + CompletionContext.getKind() == + CodeCompletionContext::CCC_ParenthesizedExpression)) return CCP_Type; return CCP_Declaration; @@ -785,7 +770,7 @@ void ResultBuilder::AdjustResultPriorityForDecl(Result &R) { // If this is an Objective-C method declaration whose selector matches our // preferred selector, give it a priority boost. if (!PreferredSelector.isNull()) - if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration)) + if (const auto *Method = dyn_cast<ObjCMethodDecl>(R.Declaration)) if (PreferredSelector == Method->getSelector()) R.Priority += CCD_SelectorMatch; @@ -799,20 +784,28 @@ void ResultBuilder::AdjustResultPriorityForDecl(Result &R) { if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) R.Priority /= CCF_ExactTypeMatch; // Check for nearly-matching types, based on classification of each. - else if ((getSimplifiedTypeClass(PreferredType) - == getSimplifiedTypeClass(TC)) && + else if ((getSimplifiedTypeClass(PreferredType) == + getSimplifiedTypeClass(TC)) && !(PreferredType->isEnumeralType() && TC->isEnumeralType())) R.Priority /= CCF_SimilarTypeMatch; } } } +DeclContext::lookup_result getConstructors(ASTContext &Context, + const CXXRecordDecl *Record) { + QualType RecordTy = Context.getTypeDeclType(Record); + DeclarationName ConstructorName = + Context.DeclarationNames.getCXXConstructorName( + Context.getCanonicalType(RecordTy)); + return Record->lookup(ConstructorName); +} + void ResultBuilder::MaybeAddConstructorResults(Result R) { if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration || !CompletionContext.wantConstructorResults()) return; - ASTContext &Context = SemaRef.Context; const NamedDecl *D = R.Declaration; const CXXRecordDecl *Record = nullptr; if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) @@ -830,16 +823,8 @@ void ResultBuilder::MaybeAddConstructorResults(Result R) { if (!Record) return; - - QualType RecordTy = Context.getTypeDeclType(Record); - DeclarationName ConstructorName - = Context.DeclarationNames.getCXXConstructorName( - Context.getCanonicalType(RecordTy)); - DeclContext::lookup_result Ctors = Record->lookup(ConstructorName); - for (DeclContext::lookup_iterator I = Ctors.begin(), - E = Ctors.end(); - I != E; ++I) { - R.Declaration = *I; + for (NamedDecl *Ctor : getConstructors(SemaRef.Context, Record)) { + R.Declaration = Ctor; R.CursorKind = getCursorKindForDecl(R.Declaration); Results.push_back(R); } @@ -921,8 +906,8 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { continue; // Protocols are in distinct namespaces from everything else. - if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) - || (IDNS & Decl::IDNS_ObjCProtocol)) && + if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol) || + (IDNS & Decl::IDNS_ObjCProtocol)) && I->first->getIdentifierNamespace() != IDNS) continue; @@ -944,18 +929,19 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { R.StartsNestedNameSpecifier = true; R.Priority = CCP_NestedNameSpecifier; } else - AdjustResultPriorityForDecl(R); + AdjustResultPriorityForDecl(R); // If this result is supposed to have an informative qualifier, add one. if (R.QualifierIsInformative && !R.Qualifier && !R.StartsNestedNameSpecifier) { const DeclContext *Ctx = R.Declaration->getDeclContext(); if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) - R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, - Namespace); + R.Qualifier = + NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace); else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) - R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, - false, SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); + R.Qualifier = NestedNameSpecifier::Create( + SemaRef.Context, nullptr, false, + SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); else R.QualifierIsInformative = false; } @@ -969,6 +955,11 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) { MaybeAddConstructorResults(R); } +static void setInBaseClass(ResultBuilder::Result &R) { + R.Priority += CCD_InBaseClass; + R.InBaseClass = true; +} + void ResultBuilder::AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding, bool InBaseClass = false) { if (R.Kind != Result::RK_Declaration) { @@ -978,7 +969,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext, } // Look through using declarations. - if (const UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { + if (const auto *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) { CodeCompletionResult Result(Using->getTargetDecl(), getBasePriority(Using->getTargetDecl()), R.Qualifier); @@ -1017,27 +1008,27 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext, if (R.QualifierIsInformative && !R.Qualifier && !R.StartsNestedNameSpecifier) { const DeclContext *Ctx = R.Declaration->getDeclContext(); - if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx)) - R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, - Namespace); - else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx)) - R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, false, - SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); + if (const auto *Namespace = dyn_cast<NamespaceDecl>(Ctx)) + R.Qualifier = + NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace); + else if (const auto *Tag = dyn_cast<TagDecl>(Ctx)) + R.Qualifier = NestedNameSpecifier::Create( + SemaRef.Context, nullptr, false, + SemaRef.Context.getTypeDeclType(Tag).getTypePtr()); else R.QualifierIsInformative = false; } // Adjust the priority if this result comes from a base class. if (InBaseClass) - R.Priority += CCD_InBaseClass; + setInBaseClass(R); AdjustResultPriorityForDecl(R); if (HasObjectTypeQualifiers) - if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration)) + if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration)) if (Method->isInstance()) { - Qualifiers MethodQuals - = Qualifiers::fromCVRMask(Method->getTypeQualifiers()); + Qualifiers MethodQuals = Method->getTypeQualifiers(); if (ObjectTypeQualifiers == MethodQuals) R.Priority += CCD_ObjectQualifierMatch; else if (ObjectTypeQualifiers - MethodQuals) { @@ -1056,7 +1047,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext, void ResultBuilder::AddResult(Result R) { assert(R.Kind != Result::RK_Declaration && - "Declaration results need more context"); + "Declaration results need more context"); Results.push_back(R); } @@ -1066,9 +1057,8 @@ void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); } /// Exit from the current scope. void ResultBuilder::ExitScope() { for (ShadowMap::iterator E = ShadowMaps.back().begin(), - EEnd = ShadowMaps.back().end(); - E != EEnd; - ++E) + EEnd = ShadowMaps.back().end(); + E != EEnd; ++E) E->second.Destroy(); ShadowMaps.pop_back(); @@ -1084,7 +1074,7 @@ bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const { unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; if (SemaRef.getLangOpts().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; - else if (SemaRef.getLangOpts().ObjC1) { + else if (SemaRef.getLangOpts().ObjC) { if (isa<ObjCIvarDecl>(ND)) return true; } @@ -1109,7 +1099,7 @@ bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const { unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern; if (SemaRef.getLangOpts().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member; - else if (SemaRef.getLangOpts().ObjC1) { + else if (SemaRef.getLangOpts().ObjC) { if (isa<ObjCIvarDecl>(ND)) return true; } @@ -1121,7 +1111,7 @@ bool ResultBuilder::IsIntegralConstantValue(const NamedDecl *ND) const { if (!IsOrdinaryNonTypeName(ND)) return 0; - if (const ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl())) + if (const auto *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl())) if (VD->getType()->isIntegralOrEnumerationType()) return true; @@ -1137,16 +1127,15 @@ bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const { if (SemaRef.getLangOpts().CPlusPlus) IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace; - return (ND->getIdentifierNamespace() & IDNS) && - !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND) && - !isa<ObjCPropertyDecl>(ND); + return (ND->getIdentifierNamespace() & IDNS) && !isa<ValueDecl>(ND) && + !isa<FunctionTemplateDecl>(ND) && !isa<ObjCPropertyDecl>(ND); } /// Determines whether the given declaration is suitable as the /// start of a C++ nested-name-specifier, e.g., a class or namespace. bool ResultBuilder::IsNestedNameSpecifier(const NamedDecl *ND) const { // Allow us to find class templates, too. - if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) + if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) ND = ClassTemplate->getTemplatedDecl(); return SemaRef.isAcceptableNestedNameSpecifier(ND); @@ -1160,14 +1149,13 @@ bool ResultBuilder::IsEnum(const NamedDecl *ND) const { /// Determines whether the given declaration is a class or struct. bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const { // Allow us to find class templates, too. - if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) + if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) ND = ClassTemplate->getTemplatedDecl(); // For purposes of this check, interfaces match too. - if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND)) - return RD->getTagKind() == TTK_Class || - RD->getTagKind() == TTK_Struct || - RD->getTagKind() == TTK_Interface; + if (const auto *RD = dyn_cast<RecordDecl>(ND)) + return RD->getTagKind() == TTK_Class || RD->getTagKind() == TTK_Struct || + RD->getTagKind() == TTK_Interface; return false; } @@ -1175,10 +1163,10 @@ bool ResultBuilder::IsClassOrStruct(const NamedDecl *ND) const { /// Determines whether the given declaration is a union. bool ResultBuilder::IsUnion(const NamedDecl *ND) const { // Allow us to find class templates, too. - if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) + if (const auto *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND)) ND = ClassTemplate->getTemplatedDecl(); - if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND)) + if (const auto *RD = dyn_cast<RecordDecl>(ND)) return RD->getTagKind() == TTK_Union; return false; @@ -1252,11 +1240,12 @@ bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const { return isObjCReceiverType(SemaRef.Context, T); } -bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture(const NamedDecl *ND) const { +bool ResultBuilder::IsObjCMessageReceiverOrLambdaCapture( + const NamedDecl *ND) const { if (IsObjCMessageReceiver(ND)) return true; - const VarDecl *Var = dyn_cast<VarDecl>(ND); + const auto *Var = dyn_cast<VarDecl>(ND); if (!Var) return false; @@ -1289,34 +1278,80 @@ bool ResultBuilder::IsObjCIvar(const NamedDecl *ND) const { } namespace { - /// Visible declaration consumer that adds a code-completion result - /// for each visible declaration. - class CodeCompletionDeclConsumer : public VisibleDeclConsumer { - ResultBuilder &Results; - DeclContext *CurContext; - std::vector<FixItHint> FixIts; - public: - CodeCompletionDeclConsumer( - ResultBuilder &Results, DeclContext *CurContext, - std::vector<FixItHint> FixIts = std::vector<FixItHint>()) - : Results(Results), CurContext(CurContext), FixIts(std::move(FixIts)) {} +/// Visible declaration consumer that adds a code-completion result +/// for each visible declaration. +class CodeCompletionDeclConsumer : public VisibleDeclConsumer { + ResultBuilder &Results; + DeclContext *InitialLookupCtx; + // NamingClass and BaseType are used for access-checking. See + // Sema::IsSimplyAccessible for details. + CXXRecordDecl *NamingClass; + QualType BaseType; + std::vector<FixItHint> FixIts; - void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, - bool InBaseClass) override { - bool Accessible = true; - if (Ctx) - Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx); - ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr, - false, Accessible, FixIts); - Results.AddResult(Result, CurContext, Hiding, InBaseClass); +public: + CodeCompletionDeclConsumer( + ResultBuilder &Results, DeclContext *InitialLookupCtx, + QualType BaseType = QualType(), + std::vector<FixItHint> FixIts = std::vector<FixItHint>()) + : Results(Results), InitialLookupCtx(InitialLookupCtx), + FixIts(std::move(FixIts)) { + NamingClass = llvm::dyn_cast<CXXRecordDecl>(InitialLookupCtx); + // If BaseType was not provided explicitly, emulate implicit 'this->'. + if (BaseType.isNull()) { + auto ThisType = Results.getSema().getCurrentThisType(); + if (!ThisType.isNull()) { + assert(ThisType->isPointerType()); + BaseType = ThisType->getPointeeType(); + if (!NamingClass) + NamingClass = BaseType->getAsCXXRecordDecl(); + } } - - void EnteredContext(DeclContext* Ctx) override { - Results.addVisitedContext(Ctx); + this->BaseType = BaseType; + } + + void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, + bool InBaseClass) override { + ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr, + false, IsAccessible(ND, Ctx), FixIts); + Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass); + } + + void EnteredContext(DeclContext *Ctx) override { + Results.addVisitedContext(Ctx); + } + +private: + bool IsAccessible(NamedDecl *ND, DeclContext *Ctx) { + // Naming class to use for access check. In most cases it was provided + // explicitly (e.g. member access (lhs.foo) or qualified lookup (X::)), + // for unqualified lookup we fallback to the \p Ctx in which we found the + // member. + auto *NamingClass = this->NamingClass; + QualType BaseType = this->BaseType; + if (auto *Cls = llvm::dyn_cast_or_null<CXXRecordDecl>(Ctx)) { + if (!NamingClass) + NamingClass = Cls; + // When we emulate implicit 'this->' in an unqualified lookup, we might + // end up with an invalid naming class. In that case, we avoid emulating + // 'this->' qualifier to satisfy preconditions of the access checking. + if (NamingClass->getCanonicalDecl() != Cls->getCanonicalDecl() && + !NamingClass->isDerivedFrom(Cls)) { + NamingClass = Cls; + BaseType = QualType(); + } + } else { + // The decl was found outside the C++ class, so only ObjC access checks + // apply. Those do not rely on NamingClass and BaseType, so we clear them + // out. + NamingClass = nullptr; + BaseType = QualType(); } - }; -} + return Results.getSema().IsSimplyAccessible(ND, NamingClass, BaseType); + } +}; +} // namespace /// Add type specifiers for the current language as keyword results. static void AddTypeSpecifierResults(const LangOptions &LangOpts, @@ -1349,8 +1384,8 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.getCodeCompletionTUInfo()); if (LangOpts.CPlusPlus) { // C++-specific - Results.AddResult(Result("bool", CCP_Type + - (LangOpts.ObjC1? CCD_bool_in_ObjC : 0))); + Results.AddResult( + Result("bool", CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0))); Results.AddResult(Result("class", CCP_Type)); Results.AddResult(Result("wchar_t", CCP_Type)); @@ -1466,14 +1501,11 @@ static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC, static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt); static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt); static void AddObjCVisibilityResults(const LangOptions &LangOpts, - ResultBuilder &Results, - bool NeedAt); + ResultBuilder &Results, bool NeedAt); static void AddObjCImplementationResults(const LangOptions &LangOpts, - ResultBuilder &Results, - bool NeedAt); + ResultBuilder &Results, bool NeedAt); static void AddObjCInterfaceResults(const LangOptions &LangOpts, - ResultBuilder &Results, - bool NeedAt); + ResultBuilder &Results, bool NeedAt); static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt); static void AddTypedefResult(ResultBuilder &Results) { @@ -1511,7 +1543,7 @@ static bool WantTypesInContext(Sema::ParserCompletionContext CCC, return false; case Sema::PCC_ForInit: - return LangOpts.CPlusPlus || LangOpts.ObjC1 || LangOpts.C99; + return LangOpts.CPlusPlus || LangOpts.ObjC || LangOpts.C99; } llvm_unreachable("Invalid ParserCompletionContext!"); @@ -1537,8 +1569,7 @@ static PrintingPolicy getCompletionPrintingPolicy(Sema &S) { /// /// This routine provides a fast path where we provide constant strings for /// common type names. -static const char *GetCompletionTypeString(QualType T, - ASTContext &Context, +static const char *GetCompletionTypeString(QualType T, ASTContext &Context, const PrintingPolicy &Policy, CodeCompletionAllocator &Allocator) { if (!T.getLocalQualifiers()) { @@ -1551,11 +1582,16 @@ static const char *GetCompletionTypeString(QualType T, if (TagDecl *Tag = TagT->getDecl()) if (!Tag->hasNameForLinkage()) { switch (Tag->getTagKind()) { - case TTK_Struct: return "struct <anonymous>"; - case TTK_Interface: return "__interface <anonymous>"; - case TTK_Class: return "class <anonymous>"; - case TTK_Union: return "union <anonymous>"; - case TTK_Enum: return "enum <anonymous>"; + case TTK_Struct: + return "struct <anonymous>"; + case TTK_Interface: + return "__interface <anonymous>"; + case TTK_Class: + return "class <anonymous>"; + case TTK_Union: + return "union <anonymous>"; + case TTK_Enum: + return "enum <anonymous>"; } } } @@ -1575,10 +1611,8 @@ static void addThisCompletion(Sema &S, ResultBuilder &Results) { CodeCompletionAllocator &Allocator = Results.getAllocator(); CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); PrintingPolicy Policy = getCompletionPrintingPolicy(S); - Builder.AddResultTypeChunk(GetCompletionTypeString(ThisTy, - S.Context, - Policy, - Allocator)); + Builder.AddResultTypeChunk( + GetCompletionTypeString(ThisTy, S.Context, Policy, Allocator)); Builder.AddTypedTextChunk("this"); Results.AddResult(CodeCompletionResult(Builder.TakeString())); } @@ -1598,11 +1632,76 @@ static void AddStaticAssertResult(CodeCompletionBuilder &Builder, Results.AddResult(CodeCompletionResult(Builder.TakeString())); } +static void printOverrideString(llvm::raw_ostream &OS, + CodeCompletionString *CCS) { + for (const auto &C : *CCS) { + if (C.Kind == CodeCompletionString::CK_Optional) + printOverrideString(OS, C.Optional); + else + OS << C.Text; + // Add a space after return type. + if (C.Kind == CodeCompletionString::CK_ResultType) + OS << ' '; + } +} + +static void AddOverrideResults(ResultBuilder &Results, + const CodeCompletionContext &CCContext, + CodeCompletionBuilder &Builder) { + Sema &S = Results.getSema(); + const auto *CR = llvm::dyn_cast<CXXRecordDecl>(S.CurContext); + // If not inside a class/struct/union return empty. + if (!CR) + return; + // First store overrides within current class. + // These are stored by name to make querying fast in the later step. + llvm::StringMap<std::vector<FunctionDecl *>> Overrides; + for (auto *Method : CR->methods()) { + if (!Method->isVirtual() || !Method->getIdentifier()) + continue; + Overrides[Method->getName()].push_back(Method); + } + + for (const auto &Base : CR->bases()) { + const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl(); + if (!BR) + continue; + for (auto *Method : BR->methods()) { + if (!Method->isVirtual() || !Method->getIdentifier()) + continue; + const auto it = Overrides.find(Method->getName()); + bool IsOverriden = false; + if (it != Overrides.end()) { + for (auto *MD : it->second) { + // If the method in current body is not an overload of this virtual + // function, then it overrides this one. + if (!S.IsOverload(MD, Method, false)) { + IsOverriden = true; + break; + } + } + } + if (!IsOverriden) { + // Generates a new CodeCompletionResult by taking this function and + // converting it into an override declaration with only one chunk in the + // final CodeCompletionString as a TypedTextChunk. + std::string OverrideSignature; + llvm::raw_string_ostream OS(OverrideSignature); + CodeCompletionResult CCR(Method, 0); + PrintingPolicy Policy = + getCompletionPrintingPolicy(S.getASTContext(), S.getPreprocessor()); + auto *CCS = CCR.createCodeCompletionStringForOverride( + S.getPreprocessor(), S.getASTContext(), Builder, + /*IncludeBriefComments=*/false, CCContext, Policy); + Results.AddResult(CodeCompletionResult(CCS, Method, CCP_CodePattern)); + } + } + } +} + /// Add language constructs that show up for "ordinary" names. -static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, - Scope *S, - Sema &SemaRef, - ResultBuilder &Results) { +static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S, + Sema &SemaRef, ResultBuilder &Results) { CodeCompletionAllocator &Allocator = Results.getAllocator(); CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo()); @@ -1651,10 +1750,12 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("declaration"); Results.AddResult(Result(Builder.TakeString())); + } else { + Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); } } - if (SemaRef.getLangOpts().ObjC1) + if (SemaRef.getLangOpts().ObjC) AddObjCTopLevelResults(Results, true); AddTypedefResult(Results); @@ -1706,6 +1807,12 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, if (IsNotInheritanceScope && Results.includeCodePatterns()) Builder.AddChunk(CodeCompletionString::CK_Colon); Results.AddResult(Result(Builder.TakeString())); + + // FIXME: This adds override results only if we are at the first word of + // the declaration/definition. Also call this from other sides to have + // more use-cases. + AddOverrideResults(Results, CodeCompletionContext::CCC_ClassStructUnion, + Builder); } } LLVM_FALLTHROUGH; @@ -1719,6 +1826,8 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Builder.AddPlaceholderChunk("parameters"); Builder.AddChunk(CodeCompletionString::CK_RightAngle); Results.AddResult(Result(Builder.TakeString())); + } else { + Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); } AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); @@ -1762,7 +1871,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Builder.AddChunk(CodeCompletionString::CK_RightBrace); Results.AddResult(Result(Builder.TakeString())); } - if (SemaRef.getLangOpts().ObjC1) + if (SemaRef.getLangOpts().ObjC) AddObjCStatementResults(Results, true); if (Results.includeCodePatterns()) { @@ -1795,7 +1904,8 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, } // Switch-specific statements. - if (!SemaRef.getCurFunction()->SwitchStack.empty()) { + if (SemaRef.getCurFunction() && + !SemaRef.getCurFunction()->SwitchStack.empty()) { // case expression: Builder.AddTypedTextChunk("case"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); @@ -1871,10 +1981,9 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, // "return expression ;" or "return ;", depending on whether we // know the function is void or not. bool isVoid = false; - if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) + if (const auto *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext)) isVoid = Function->getReturnType()->isVoidType(); - else if (ObjCMethodDecl *Method - = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext)) + else if (const auto *Method = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext)) isVoid = Method->getReturnType()->isVoidType(); else if (SemaRef.getCurBlock() && !SemaRef.getCurBlock()->ReturnType.isNull()) @@ -1902,7 +2011,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts()); } - LLVM_FALLTHROUGH; + LLVM_FALLTHROUGH; // Fall through (for statement expressions). case Sema::PCC_ForInit: @@ -2089,7 +2198,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, } } - if (SemaRef.getLangOpts().ObjC1) { + if (SemaRef.getLangOpts().ObjC) { // Add "super", if we're in an Objective-C class with a superclass. if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) { // The interface can be NULL. @@ -2148,8 +2257,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, /// type chunk. static void AddResultTypeChunk(ASTContext &Context, const PrintingPolicy &Policy, - const NamedDecl *ND, - QualType BaseType, + const NamedDecl *ND, QualType BaseType, CodeCompletionBuilder &Result) { if (!ND) return; @@ -2163,24 +2271,24 @@ static void AddResultTypeChunk(ASTContext &Context, QualType T; if (const FunctionDecl *Function = ND->getAsFunction()) T = Function->getReturnType(); - else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) { + else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) { if (!BaseType.isNull()) T = Method->getSendResultType(BaseType); else T = Method->getReturnType(); - } else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) { + } else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) { T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); T = clang::TypeName::getFullyQualifiedType(T, Context); } else if (isa<UnresolvedUsingValueDecl>(ND)) { /* Do nothing: ignore unresolved using declarations*/ - } else if (const ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(ND)) { + } else if (const auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) { if (!BaseType.isNull()) T = Ivar->getUsageType(BaseType); else T = Ivar->getType(); - } else if (const ValueDecl *Value = dyn_cast<ValueDecl>(ND)) { + } else if (const auto *Value = dyn_cast<ValueDecl>(ND)) { T = Value->getType(); - } else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) { + } else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND)) { if (!BaseType.isNull()) T = Property->getUsageType(BaseType); else @@ -2190,8 +2298,8 @@ static void AddResultTypeChunk(ASTContext &Context, if (T.isNull() || Context.hasSameType(T, Context.DependentTy)) return; - Result.AddResultTypeChunk(GetCompletionTypeString(T, Context, Policy, - Result.getAllocator())); + Result.AddResultTypeChunk( + GetCompletionTypeString(T, Context, Policy, Result.getAllocator())); } static void MaybeAddSentinel(Preprocessor &PP, @@ -2199,7 +2307,7 @@ static void MaybeAddSentinel(Preprocessor &PP, CodeCompletionBuilder &Result) { if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>()) if (Sentinel->getSentinel() == 0) { - if (PP.getLangOpts().ObjC1 && PP.isMacroDefined("nil")) + if (PP.getLangOpts().ObjC && PP.isMacroDefined("nil")) Result.AddTextChunk(", nil"); else if (PP.isMacroDefined("NULL")) Result.AddTextChunk(", NULL"); @@ -2297,11 +2405,10 @@ formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl, bool SuppressBlock = false, Optional<ArrayRef<QualType>> ObjCSubsts = None); -static std::string FormatFunctionParameter(const PrintingPolicy &Policy, - const ParmVarDecl *Param, - bool SuppressName = false, - bool SuppressBlock = false, - Optional<ArrayRef<QualType>> ObjCSubsts = None) { +static std::string +FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param, + bool SuppressName = false, bool SuppressBlock = false, + Optional<ArrayRef<QualType>> ObjCSubsts = None) { bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext()); if (Param->getType()->isDependentType() || !Param->getType()->isBlockPointerType()) { @@ -2317,8 +2424,8 @@ static std::string FormatFunctionParameter(const PrintingPolicy &Policy, Type = Type.substObjCTypeArgs(Param->getASTContext(), *ObjCSubsts, ObjCSubstitutionContext::Parameter); if (ObjCMethodParam) { - Result = "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(), - Type); + Result = + "(" + formatObjCParamQualifiers(Param->getObjCDeclQualifier(), Type); Result += Type.getAsString(Policy) + ")"; if (Param->getIdentifier() && !SuppressName) Result += Param->getIdentifier()->getName(); @@ -2449,13 +2556,15 @@ static std::string GetDefaultValueString(const ParmVarDecl *Param, bool Invalid = CharSrcRange.isInvalid(); if (Invalid) return ""; - StringRef srcText = Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid); + StringRef srcText = + Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid); if (Invalid) return ""; if (srcText.empty() || srcText == "=") { // Lexer can't determine the value. - // This happens if the code is incorrect (for example class is forward declared). + // This happens if the code is incorrect (for example class is forward + // declared). return ""; } std::string DefValue(srcText.str()); @@ -2463,7 +2572,8 @@ static std::string GetDefaultValueString(const ParmVarDecl *Param, // this value always has (or always does not have) '=' in front of it if (DefValue.at(0) != '=') { // If we don't have '=' in front of value. - // Lexer returns built-in types values without '=' and user-defined types values with it. + // Lexer returns built-in types values without '=' and user-defined types + // values with it. return " = " + DefValue; } return " " + DefValue; @@ -2503,18 +2613,18 @@ static void AddFunctionParameterChunks(Preprocessor &PP, // Format the placeholder string. std::string PlaceholderStr = FormatFunctionParameter(Policy, Param); if (Param->hasDefaultArg()) - PlaceholderStr += GetDefaultValueString(Param, PP.getSourceManager(), PP.getLangOpts()); + PlaceholderStr += + GetDefaultValueString(Param, PP.getSourceManager(), PP.getLangOpts()); if (Function->isVariadic() && P == N - 1) PlaceholderStr += ", ..."; // Add the placeholder string. Result.AddPlaceholderChunk( - Result.getAllocator().CopyString(PlaceholderStr)); + Result.getAllocator().CopyString(PlaceholderStr)); } - if (const FunctionProtoType *Proto - = Function->getType()->getAs<FunctionProtoType>()) + if (const auto *Proto = Function->getType()->getAs<FunctionProtoType>()) if (Proto->isVariadic()) { if (Proto->getNumParams() == 0) Result.AddPlaceholderChunk("..."); @@ -2524,13 +2634,10 @@ static void AddFunctionParameterChunks(Preprocessor &PP, } /// Add template parameter chunks to the given code completion string. -static void AddTemplateParameterChunks(ASTContext &Context, - const PrintingPolicy &Policy, - const TemplateDecl *Template, - CodeCompletionBuilder &Result, - unsigned MaxParameters = 0, - unsigned Start = 0, - bool InDefaultArg = false) { +static void AddTemplateParameterChunks( + ASTContext &Context, const PrintingPolicy &Policy, + const TemplateDecl *Template, CodeCompletionBuilder &Result, + unsigned MaxParameters = 0, unsigned Start = 0, bool InDefaultArg = false) { bool FirstParameter = true; // Prefer to take the template parameter names from the first declaration of @@ -2541,8 +2648,8 @@ static void AddTemplateParameterChunks(ASTContext &Context, TemplateParameterList::iterator PEnd = Params->end(); if (MaxParameters) PEnd = Params->begin() + MaxParameters; - for (TemplateParameterList::iterator P = Params->begin() + Start; - P != PEnd; ++P) { + for (TemplateParameterList::iterator P = Params->begin() + Start; P != PEnd; + ++P) { bool HasDefaultArg = false; std::string PlaceholderStr; if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { @@ -2557,8 +2664,8 @@ static void AddTemplateParameterChunks(ASTContext &Context, } HasDefaultArg = TTP->hasDefaultArgument(); - } else if (NonTypeTemplateParmDecl *NTTP - = dyn_cast<NonTypeTemplateParmDecl>(*P)) { + } else if (NonTypeTemplateParmDecl *NTTP = + dyn_cast<NonTypeTemplateParmDecl>(*P)) { if (NTTP->getIdentifier()) PlaceholderStr = NTTP->getIdentifier()->getName(); NTTP->getType().getAsStringInternal(PlaceholderStr, Policy); @@ -2600,18 +2707,17 @@ static void AddTemplateParameterChunks(ASTContext &Context, // Add the placeholder string. Result.AddPlaceholderChunk( - Result.getAllocator().CopyString(PlaceholderStr)); + Result.getAllocator().CopyString(PlaceholderStr)); } } /// Add a qualifier to the given code-completion string, if the /// provided nested-name-specifier is non-NULL. -static void -AddQualifierToCompletionString(CodeCompletionBuilder &Result, - NestedNameSpecifier *Qualifier, - bool QualifierIsInformative, - ASTContext &Context, - const PrintingPolicy &Policy) { +static void AddQualifierToCompletionString(CodeCompletionBuilder &Result, + NestedNameSpecifier *Qualifier, + bool QualifierIsInformative, + ASTContext &Context, + const PrintingPolicy &Policy) { if (!Qualifier) return; @@ -2629,25 +2735,24 @@ AddQualifierToCompletionString(CodeCompletionBuilder &Result, static void AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result, const FunctionDecl *Function) { - const FunctionProtoType *Proto - = Function->getType()->getAs<FunctionProtoType>(); + const auto *Proto = Function->getType()->getAs<FunctionProtoType>(); if (!Proto || !Proto->getTypeQuals()) return; // FIXME: Add ref-qualifier! // Handle single qualifiers without copying - if (Proto->getTypeQuals() == Qualifiers::Const) { + if (Proto->getTypeQuals().hasOnlyConst()) { Result.AddInformativeChunk(" const"); return; } - if (Proto->getTypeQuals() == Qualifiers::Volatile) { + if (Proto->getTypeQuals().hasOnlyVolatile()) { Result.AddInformativeChunk(" volatile"); return; } - if (Proto->getTypeQuals() == Qualifiers::Restrict) { + if (Proto->getTypeQuals().hasOnlyRestrict()) { Result.AddInformativeChunk(" restrict"); return; } @@ -2672,37 +2777,51 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, return; switch (Name.getNameKind()) { - case DeclarationName::CXXOperatorName: { - const char *OperatorName = nullptr; - switch (Name.getCXXOverloadedOperator()) { - case OO_None: - case OO_Conditional: - case NUM_OVERLOADED_OPERATORS: - OperatorName = "operator"; - break; + case DeclarationName::CXXOperatorName: { + const char *OperatorName = nullptr; + switch (Name.getCXXOverloadedOperator()) { + case OO_None: + case OO_Conditional: + case NUM_OVERLOADED_OPERATORS: + OperatorName = "operator"; + break; -#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ - case OO_##Name: OperatorName = "operator" Spelling; break; -#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) +#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ + case OO_##Name: \ + OperatorName = "operator" Spelling; \ + break; +#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemberOnly) #include "clang/Basic/OperatorKinds.def" - case OO_New: OperatorName = "operator new"; break; - case OO_Delete: OperatorName = "operator delete"; break; - case OO_Array_New: OperatorName = "operator new[]"; break; - case OO_Array_Delete: OperatorName = "operator delete[]"; break; - case OO_Call: OperatorName = "operator()"; break; - case OO_Subscript: OperatorName = "operator[]"; break; - } - Result.AddTypedTextChunk(OperatorName); + case OO_New: + OperatorName = "operator new"; + break; + case OO_Delete: + OperatorName = "operator delete"; + break; + case OO_Array_New: + OperatorName = "operator new[]"; + break; + case OO_Array_Delete: + OperatorName = "operator delete[]"; + break; + case OO_Call: + OperatorName = "operator()"; + break; + case OO_Subscript: + OperatorName = "operator[]"; break; } + Result.AddTypedTextChunk(OperatorName); + break; + } case DeclarationName::Identifier: case DeclarationName::CXXConversionFunctionName: case DeclarationName::CXXDestructorName: case DeclarationName::CXXLiteralOperatorName: Result.AddTypedTextChunk( - Result.getAllocator().CopyString(ND->getNameAsString())); + Result.getAllocator().CopyString(ND->getNameAsString())); break; case DeclarationName::CXXDeductionGuideName: @@ -2715,19 +2834,18 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, case DeclarationName::CXXConstructorName: { CXXRecordDecl *Record = nullptr; QualType Ty = Name.getCXXNameType(); - if (const RecordType *RecordTy = Ty->getAs<RecordType>()) + if (const auto *RecordTy = Ty->getAs<RecordType>()) Record = cast<CXXRecordDecl>(RecordTy->getDecl()); - else if (const InjectedClassNameType *InjectedTy - = Ty->getAs<InjectedClassNameType>()) + else if (const auto *InjectedTy = Ty->getAs<InjectedClassNameType>()) Record = InjectedTy->getDecl(); else { Result.AddTypedTextChunk( - Result.getAllocator().CopyString(ND->getNameAsString())); + Result.getAllocator().CopyString(ND->getNameAsString())); break; } Result.AddTypedTextChunk( - Result.getAllocator().CopyString(Record->getNameAsString())); + Result.getAllocator().CopyString(Record->getNameAsString())); if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) { Result.AddChunk(CodeCompletionString::CK_LeftAngle); AddTemplateParameterChunks(Context, Policy, Template, Result); @@ -2738,11 +2856,10 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, } } -CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S, - const CodeCompletionContext &CCContext, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments) { +CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString( + Sema &S, const CodeCompletionContext &CCContext, + CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments) { return CreateCodeCompletionString(S.Context, S.PP, CCContext, Allocator, CCTUInfo, IncludeBriefComments); } @@ -2799,13 +2916,10 @@ CodeCompletionString *CodeCompletionResult::CreateCodeCompletionStringForMacro( /// \returns Either a new, heap-allocated code completion string describing /// how to use this result, or NULL to indicate that the string or name of the /// result is all that is needed. -CodeCompletionString * -CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, - Preprocessor &PP, - const CodeCompletionContext &CCContext, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments) { +CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString( + ASTContext &Ctx, Preprocessor &PP, const CodeCompletionContext &CCContext, + CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments) { if (Kind == RK_Macro) return CreateCodeCompletionStringForMacro(PP, Allocator, CCTUInfo); @@ -2834,6 +2948,30 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, return Result.TakeString(); } assert(Kind == RK_Declaration && "Missed a result kind?"); + return createCodeCompletionStringForDecl( + PP, Ctx, Result, IncludeBriefComments, CCContext, Policy); +} + +CodeCompletionString * +CodeCompletionResult::createCodeCompletionStringForOverride( + Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, + bool IncludeBriefComments, const CodeCompletionContext &CCContext, + PrintingPolicy &Policy) { + std::string OverrideSignature; + llvm::raw_string_ostream OS(OverrideSignature); + auto *CCS = createCodeCompletionStringForDecl(PP, Ctx, Result, + /*IncludeBriefComments=*/false, + CCContext, Policy); + printOverrideString(OS, CCS); + OS << " override"; + Result.AddTypedTextChunk(Result.getAllocator().CopyString(OS.str())); + return Result.TakeString(); +} + +CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl( + Preprocessor &PP, ASTContext &Ctx, CodeCompletionBuilder &Result, + bool IncludeBriefComments, const CodeCompletionContext &CCContext, + PrintingPolicy &Policy) { const NamedDecl *ND = Declaration; Result.addParentContext(ND->getDeclContext()); @@ -2846,7 +2984,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, if (StartsNestedNameSpecifier) { Result.AddTypedTextChunk( - Result.getAllocator().CopyString(ND->getNameAsString())); + Result.getAllocator().CopyString(ND->getNameAsString())); Result.AddTextChunk("::"); return Result.TakeString(); } @@ -2856,7 +2994,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, AddResultTypeChunk(Ctx, Policy, ND, CCContext.getBaseType(), Result); - if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { + if (const auto *Function = dyn_cast<FunctionDecl>(ND)) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, Ctx, Policy); AddTypedNameChunk(Ctx, Policy, ND, Result); @@ -2867,7 +3005,8 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, return Result.TakeString(); } - if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) { + if (const FunctionTemplateDecl *FunTmpl = + dyn_cast<FunctionTemplateDecl>(ND)) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, Ctx, Policy); FunctionDecl *Function = FunTmpl->getTemplatedDecl(); @@ -2886,16 +3025,16 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, // FIXME: We need to abstract template parameters better! bool HasDefaultArg = false; NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam( - LastDeducibleArgument - 1); + LastDeducibleArgument - 1); if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) HasDefaultArg = TTP->hasDefaultArgument(); - else if (NonTypeTemplateParmDecl *NTTP - = dyn_cast<NonTypeTemplateParmDecl>(Param)) + else if (NonTypeTemplateParmDecl *NTTP = + dyn_cast<NonTypeTemplateParmDecl>(Param)) HasDefaultArg = NTTP->hasDefaultArgument(); else { assert(isa<TemplateTemplateParmDecl>(Param)); - HasDefaultArg - = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); + HasDefaultArg = + cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); } if (!HasDefaultArg) @@ -2921,22 +3060,21 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, return Result.TakeString(); } - if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) { + if (const auto *Template = dyn_cast<TemplateDecl>(ND)) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, Ctx, Policy); Result.AddTypedTextChunk( - Result.getAllocator().CopyString(Template->getNameAsString())); + Result.getAllocator().CopyString(Template->getNameAsString())); Result.AddChunk(CodeCompletionString::CK_LeftAngle); AddTemplateParameterChunks(Ctx, Policy, Template, Result); Result.AddChunk(CodeCompletionString::CK_RightAngle); return Result.TakeString(); } - - if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) { + if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND)) { Selector Sel = Method->getSelector(); if (Sel.isUnarySelector()) { - Result.AddTypedTextChunk(Result.getAllocator().CopyString( - Sel.getNameForSlot(0))); + Result.AddTypedTextChunk( + Result.getAllocator().CopyString(Sel.getNameForSlot(0))); return Result.TakeString(); } @@ -2954,7 +3092,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, } unsigned Idx = 0; for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(), - PEnd = Method->param_end(); + PEnd = Method->param_end(); P != PEnd; (void)++P, ++Idx) { if (Idx > 0) { std::string Keyword; @@ -2981,12 +3119,11 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, if (ParamType->isBlockPointerType() && !DeclaringEntity) Arg = FormatFunctionParameter(Policy, *P, true, - /*SuppressBlock=*/false, - ObjCSubsts); + /*SuppressBlock=*/false, ObjCSubsts); else { if (ObjCSubsts) - ParamType = ParamType.substObjCTypeArgs(Ctx, *ObjCSubsts, - ObjCSubstitutionContext::Parameter); + ParamType = ParamType.substObjCTypeArgs( + Ctx, *ObjCSubsts, ObjCSubstitutionContext::Parameter); Arg = "(" + formatObjCParamQualifiers((*P)->getObjCDeclQualifier(), ParamType); Arg += ParamType.getAsString(Policy) + ")"; @@ -3027,7 +3164,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, Ctx, Policy); Result.AddTypedTextChunk( - Result.getAllocator().CopyString(ND->getNameAsString())); + Result.getAllocator().CopyString(ND->getNameAsString())); return Result.TakeString(); } @@ -3039,7 +3176,7 @@ const RawComment *clang::getCompletionComment(const ASTContext &Ctx, return RC; // Try to find comment from a property for ObjC methods. - const ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(ND); + const auto *M = dyn_cast<ObjCMethodDecl>(ND); if (!M) return nullptr; const ObjCPropertyDecl *PDecl = M->findPropertyDecl(); @@ -3051,7 +3188,7 @@ const RawComment *clang::getCompletionComment(const ASTContext &Ctx, const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx, const NamedDecl *ND) { - const ObjCMethodDecl *M = dyn_cast_or_null<ObjCMethodDecl>(ND); + const auto *M = dyn_cast_or_null<ObjCMethodDecl>(ND); if (!M || !M->isPropertyAccessor()) return nullptr; @@ -3074,8 +3211,7 @@ const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx, const RawComment *clang::getParameterComment( const ASTContext &Ctx, - const CodeCompleteConsumer::OverloadCandidate &Result, - unsigned ArgIndex) { + const CodeCompleteConsumer::OverloadCandidate &Result, unsigned ArgIndex) { auto FDecl = Result.getFunction(); if (!FDecl) return nullptr; @@ -3091,12 +3227,11 @@ static void AddOverloadParameterChunks(ASTContext &Context, const FunctionDecl *Function, const FunctionProtoType *Prototype, CodeCompletionBuilder &Result, - unsigned CurrentArg, - unsigned Start = 0, + unsigned CurrentArg, unsigned Start = 0, bool InOptional = false) { bool FirstParameter = true; - unsigned NumParams = Function ? Function->getNumParams() - : Prototype->getNumParams(); + unsigned NumParams = + Function ? Function->getNumParams() : Prototype->getNumParams(); for (unsigned P = Start; P != NumParams; ++P) { if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) { @@ -3126,14 +3261,15 @@ static void AddOverloadParameterChunks(ASTContext &Context, const ParmVarDecl *Param = Function->getParamDecl(P); Placeholder = FormatFunctionParameter(Policy, Param); if (Param->hasDefaultArg()) - Placeholder += GetDefaultValueString(Param, Context.getSourceManager(), Context.getLangOpts()); + Placeholder += GetDefaultValueString(Param, Context.getSourceManager(), + Context.getLangOpts()); } else { Placeholder = Prototype->getParamType(P).getAsString(Policy); } if (P == CurrentArg) Result.AddCurrentParameterChunk( - Result.getAllocator().CopyString(Placeholder)); + Result.getAllocator().CopyString(Placeholder)); else Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Placeholder)); } @@ -3155,23 +3291,22 @@ static void AddOverloadParameterChunks(ASTContext &Context, CodeCompletionString * CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( - unsigned CurrentArg, Sema &S, - CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - bool IncludeBriefComments) const { + unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) const { PrintingPolicy Policy = getCompletionPrintingPolicy(S); // FIXME: Set priority, availability appropriately. - CodeCompletionBuilder Result(Allocator,CCTUInfo, 1, CXAvailability_Available); + CodeCompletionBuilder Result(Allocator, CCTUInfo, 1, + CXAvailability_Available); FunctionDecl *FDecl = getFunction(); - const FunctionProtoType *Proto - = dyn_cast<FunctionProtoType>(getFunctionType()); + const FunctionProtoType *Proto = + dyn_cast<FunctionProtoType>(getFunctionType()); if (!FDecl && !Proto) { // Function without a prototype. Just give the return type and a // highlighted ellipsis. const FunctionType *FT = getFunctionType(); Result.AddResultTypeChunk(Result.getAllocator().CopyString( - FT->getReturnType().getAsString(Policy))); + FT->getReturnType().getAsString(Policy))); Result.AddChunk(CodeCompletionString::CK_LeftParen); Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "..."); Result.AddChunk(CodeCompletionString::CK_RightParen); @@ -3185,10 +3320,9 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( } AddResultTypeChunk(S.Context, Policy, FDecl, QualType(), Result); Result.AddTextChunk( - Result.getAllocator().CopyString(FDecl->getNameAsString())); + Result.getAllocator().CopyString(FDecl->getNameAsString())); } else { - Result.AddResultTypeChunk( - Result.getAllocator().CopyString( + Result.AddResultTypeChunk(Result.getAllocator().CopyString( Proto->getReturnType().getAsString(Policy))); } @@ -3218,8 +3352,7 @@ unsigned clang::getMacroUsagePriority(StringRef MacroName, Priority = CCP_Constant; // Treat "bool" as a type. else if (MacroName.equals("bool")) - Priority = CCP_Type + (LangOpts.ObjC1? CCD_bool_in_ObjC : 0); - + Priority = CCP_Type + (LangOpts.ObjC ? CCD_bool_in_ObjC : 0); return Priority; } @@ -3229,75 +3362,112 @@ CXCursorKind clang::getCursorKindForDecl(const Decl *D) { return CXCursor_UnexposedDecl; switch (D->getKind()) { - case Decl::Enum: return CXCursor_EnumDecl; - case Decl::EnumConstant: return CXCursor_EnumConstantDecl; - case Decl::Field: return CXCursor_FieldDecl; - case Decl::Function: - return CXCursor_FunctionDecl; - case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl; - case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl; - case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl; - - case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl; - case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl; - case Decl::ObjCMethod: - return cast<ObjCMethodDecl>(D)->isInstanceMethod() - ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl; - case Decl::CXXMethod: return CXCursor_CXXMethod; - case Decl::CXXConstructor: return CXCursor_Constructor; - case Decl::CXXDestructor: return CXCursor_Destructor; - case Decl::CXXConversion: return CXCursor_ConversionFunction; - case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl; - case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; - case Decl::ParmVar: return CXCursor_ParmDecl; - case Decl::Typedef: return CXCursor_TypedefDecl; - case Decl::TypeAlias: return CXCursor_TypeAliasDecl; - case Decl::TypeAliasTemplate: return CXCursor_TypeAliasTemplateDecl; - case Decl::Var: return CXCursor_VarDecl; - case Decl::Namespace: return CXCursor_Namespace; - case Decl::NamespaceAlias: return CXCursor_NamespaceAlias; - case Decl::TemplateTypeParm: return CXCursor_TemplateTypeParameter; - case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter; - case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter; - case Decl::FunctionTemplate: return CXCursor_FunctionTemplate; - case Decl::ClassTemplate: return CXCursor_ClassTemplate; - case Decl::AccessSpec: return CXCursor_CXXAccessSpecifier; - case Decl::ClassTemplatePartialSpecialization: - return CXCursor_ClassTemplatePartialSpecialization; - case Decl::UsingDirective: return CXCursor_UsingDirective; - case Decl::StaticAssert: return CXCursor_StaticAssert; - case Decl::Friend: return CXCursor_FriendDecl; - case Decl::TranslationUnit: return CXCursor_TranslationUnit; - - case Decl::Using: - case Decl::UnresolvedUsingValue: - case Decl::UnresolvedUsingTypename: - return CXCursor_UsingDeclaration; - - case Decl::ObjCPropertyImpl: - switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) { - case ObjCPropertyImplDecl::Dynamic: - return CXCursor_ObjCDynamicDecl; - - case ObjCPropertyImplDecl::Synthesize: - return CXCursor_ObjCSynthesizeDecl; - } - - case Decl::Import: - return CXCursor_ModuleImportDecl; - - case Decl::ObjCTypeParam: return CXCursor_TemplateTypeParameter; + case Decl::Enum: + return CXCursor_EnumDecl; + case Decl::EnumConstant: + return CXCursor_EnumConstantDecl; + case Decl::Field: + return CXCursor_FieldDecl; + case Decl::Function: + return CXCursor_FunctionDecl; + case Decl::ObjCCategory: + return CXCursor_ObjCCategoryDecl; + case Decl::ObjCCategoryImpl: + return CXCursor_ObjCCategoryImplDecl; + case Decl::ObjCImplementation: + return CXCursor_ObjCImplementationDecl; + + case Decl::ObjCInterface: + return CXCursor_ObjCInterfaceDecl; + case Decl::ObjCIvar: + return CXCursor_ObjCIvarDecl; + case Decl::ObjCMethod: + return cast<ObjCMethodDecl>(D)->isInstanceMethod() + ? CXCursor_ObjCInstanceMethodDecl + : CXCursor_ObjCClassMethodDecl; + case Decl::CXXMethod: + return CXCursor_CXXMethod; + case Decl::CXXConstructor: + return CXCursor_Constructor; + case Decl::CXXDestructor: + return CXCursor_Destructor; + case Decl::CXXConversion: + return CXCursor_ConversionFunction; + case Decl::ObjCProperty: + return CXCursor_ObjCPropertyDecl; + case Decl::ObjCProtocol: + return CXCursor_ObjCProtocolDecl; + case Decl::ParmVar: + return CXCursor_ParmDecl; + case Decl::Typedef: + return CXCursor_TypedefDecl; + case Decl::TypeAlias: + return CXCursor_TypeAliasDecl; + case Decl::TypeAliasTemplate: + return CXCursor_TypeAliasTemplateDecl; + case Decl::Var: + return CXCursor_VarDecl; + case Decl::Namespace: + return CXCursor_Namespace; + case Decl::NamespaceAlias: + return CXCursor_NamespaceAlias; + case Decl::TemplateTypeParm: + return CXCursor_TemplateTypeParameter; + case Decl::NonTypeTemplateParm: + return CXCursor_NonTypeTemplateParameter; + case Decl::TemplateTemplateParm: + return CXCursor_TemplateTemplateParameter; + case Decl::FunctionTemplate: + return CXCursor_FunctionTemplate; + case Decl::ClassTemplate: + return CXCursor_ClassTemplate; + case Decl::AccessSpec: + return CXCursor_CXXAccessSpecifier; + case Decl::ClassTemplatePartialSpecialization: + return CXCursor_ClassTemplatePartialSpecialization; + case Decl::UsingDirective: + return CXCursor_UsingDirective; + case Decl::StaticAssert: + return CXCursor_StaticAssert; + case Decl::Friend: + return CXCursor_FriendDecl; + case Decl::TranslationUnit: + return CXCursor_TranslationUnit; + + case Decl::Using: + case Decl::UnresolvedUsingValue: + case Decl::UnresolvedUsingTypename: + return CXCursor_UsingDeclaration; + + case Decl::ObjCPropertyImpl: + switch (cast<ObjCPropertyImplDecl>(D)->getPropertyImplementation()) { + case ObjCPropertyImplDecl::Dynamic: + return CXCursor_ObjCDynamicDecl; + + case ObjCPropertyImplDecl::Synthesize: + return CXCursor_ObjCSynthesizeDecl; + } + + case Decl::Import: + return CXCursor_ModuleImportDecl; + + case Decl::ObjCTypeParam: + return CXCursor_TemplateTypeParameter; - default: - if (const TagDecl *TD = dyn_cast<TagDecl>(D)) { - switch (TD->getTagKind()) { - case TTK_Interface: // fall through - case TTK_Struct: return CXCursor_StructDecl; - case TTK_Class: return CXCursor_ClassDecl; - case TTK_Union: return CXCursor_UnionDecl; - case TTK_Enum: return CXCursor_EnumDecl; - } + default: + if (const auto *TD = dyn_cast<TagDecl>(D)) { + switch (TD->getTagKind()) { + case TTK_Interface: // fall through + case TTK_Struct: + return CXCursor_StructDecl; + case TTK_Class: + return CXCursor_ClassDecl; + case TTK_Union: + return CXCursor_UnionDecl; + case TTK_Enum: + return CXCursor_EnumDecl; } + } } return CXCursor_UnexposedDecl; @@ -3351,8 +3521,8 @@ static void HandleCodeCompleteResults(Sema *S, CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults); } -static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, - Sema::ParserCompletionContext PCC) { +static CodeCompletionContext +mapCodeCompletionContext(Sema &S, Sema::ParserCompletionContext PCC) { switch (PCC) { case Sema::PCC_Namespace: return CodeCompletionContext::CCC_TopLevel; @@ -3382,14 +3552,16 @@ static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, case Sema::PCC_ForInit: if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 || - S.getLangOpts().ObjC1) + S.getLangOpts().ObjC) return CodeCompletionContext::CCC_ParenthesizedExpression; else return CodeCompletionContext::CCC_Expression; case Sema::PCC_Expression: - case Sema::PCC_Condition: return CodeCompletionContext::CCC_Expression; + case Sema::PCC_Condition: + return CodeCompletionContext(CodeCompletionContext::CCC_Expression, + S.getASTContext().BoolTy); case Sema::PCC_Statement: return CodeCompletionContext::CCC_Statement; @@ -3422,7 +3594,6 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, while (isa<BlockDecl>(CurContext)) CurContext = CurContext->getParent(); - CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext); if (!Method || !Method->isVirtual()) return; @@ -3442,9 +3613,8 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, // If we need a nested-name-specifier, add one now. if (!InContext) { - NestedNameSpecifier *NNS - = getRequiredQualification(S.Context, CurContext, - Overridden->getDeclContext()); + NestedNameSpecifier *NNS = getRequiredQualification( + S.Context, CurContext, Overridden->getDeclContext()); if (NNS) { std::string Str; llvm::raw_string_ostream OS(Str); @@ -3454,8 +3624,8 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, } else if (!InContext->Equals(Overridden->getDeclContext())) continue; - Builder.AddTypedTextChunk(Results.getAllocator().CopyString( - Overridden->getNameAsString())); + Builder.AddTypedTextChunk( + Results.getAllocator().CopyString(Overridden->getNameAsString())); Builder.AddChunk(CodeCompletionString::CK_LeftParen); bool FirstParam = true; for (auto P : Method->parameters()) { @@ -3468,11 +3638,9 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext, Results.getAllocator().CopyString(P->getIdentifier()->getName())); } Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - CCP_SuperCompletion, - CXCursor_CXXMethod, - CXAvailability_Available, - Overridden)); + Results.AddResult(CodeCompletionResult( + Builder.TakeString(), CCP_SuperCompletion, CXCursor_CXXMethod, + CXAvailability_Available, Overridden)); Results.Ignore(Overridden); } } @@ -3494,39 +3662,35 @@ void Sema::CodeCompleteModuleImport(SourceLocation ImportLoc, PP.getHeaderSearchInfo().collectAllModules(Modules); for (unsigned I = 0, N = Modules.size(); I != N; ++I) { Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString(Modules[I]->Name)); - Results.AddResult(Result(Builder.TakeString(), - CCP_Declaration, - CXCursor_ModuleImportDecl, - Modules[I]->isAvailable() - ? CXAvailability_Available - : CXAvailability_NotAvailable)); + Builder.getAllocator().CopyString(Modules[I]->Name)); + Results.AddResult(Result( + Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl, + Modules[I]->isAvailable() ? CXAvailability_Available + : CXAvailability_NotAvailable)); } } else if (getLangOpts().Modules) { // Load the named module. - Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path, - Module::AllVisible, - /*IsInclusionDirective=*/false); + Module *Mod = + PP.getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible, + /*IsInclusionDirective=*/false); // Enumerate submodules. if (Mod) { for (Module::submodule_iterator Sub = Mod->submodule_begin(), - SubEnd = Mod->submodule_end(); + SubEnd = Mod->submodule_end(); Sub != SubEnd; ++Sub) { Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString((*Sub)->Name)); - Results.AddResult(Result(Builder.TakeString(), - CCP_Declaration, - CXCursor_ModuleImportDecl, - (*Sub)->isAvailable() - ? CXAvailability_Available - : CXAvailability_NotAvailable)); + Builder.getAllocator().CopyString((*Sub)->Name)); + Results.AddResult(Result( + Builder.TakeString(), CCP_Declaration, CXCursor_ModuleImportDecl, + (*Sub)->isAvailable() ? CXAvailability_Available + : CXAvailability_NotAvailable)); } } } Results.ExitScope(); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), - Results.data(),Results.size()); + Results.data(), Results.size()); } void Sema::CodeCompleteOrdinaryName(Scope *S, @@ -3573,10 +3737,11 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, // If we are in a C++ non-static member function, check the qualifiers on // the member function to filter/prioritize the results list. - if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext)) - if (CurMethod->isInstance()) - Results.setObjectTypeQualifiers( - Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers())); + if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext)) { + if (CurMethod->isInstance()) { + Results.setObjectTypeQualifiers(CurMethod->getTypeQualifiers()); + } + } CodeCompletionDeclConsumer Consumer(Results, CurContext); LookupVisibleDecls(S, LookupOrdinaryName, Consumer, @@ -3613,25 +3778,27 @@ void Sema::CodeCompleteOrdinaryName(Scope *S, AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), - Results.data(),Results.size()); + Results.data(), Results.size()); } static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver, ArrayRef<IdentifierInfo *> SelIdents, - bool AtArgumentExpression, - bool IsSuper, + bool AtArgumentExpression, bool IsSuper, ResultBuilder &Results); void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers) { typedef CodeCompletionResult Result; - ResultBuilder Results(*this, CodeCompleter->getAllocator(), - CodeCompleter->getCodeCompletionTUInfo(), - AllowNestedNameSpecifiers - ? CodeCompletionContext::CCC_PotentiallyQualifiedName - : CodeCompletionContext::CCC_Name); + ResultBuilder Results( + *this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), + AllowNestedNameSpecifiers + // FIXME: Try to separate codepath leading here to deduce whether we + // need an existing symbol or a new one. + ? CodeCompletionContext::CCC_SymbolOrNewName + : CodeCompletionContext::CCC_NewName); Results.EnterNewScope(); // Type qualifiers can come after names. @@ -3672,12 +3839,11 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, DS.getTypeSpecType() == DeclSpec::TST_typename && DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified && DS.getTypeSpecSign() == DeclSpec::TSS_unspecified && - !DS.isTypeAltiVecVector() && - S && + !DS.isTypeAltiVecVector() && S && (S->getFlags() & Scope::DeclScope) != 0 && (S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope | - Scope::FunctionPrototypeScope | - Scope::AtCatchScope)) == 0) { + Scope::FunctionPrototypeScope | Scope::AtCatchScope)) == + 0) { ParsedType T = DS.getRepAsType(); if (!T.get().isNull() && T.get()->isObjCObjectOrInterfaceType()) AddClassMessageCompletions(*this, S, T, None, false, false, Results); @@ -3686,15 +3852,14 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, // Note that we intentionally suppress macro results here, since we do not // encourage using macros to produce the names of entities. - HandleCodeCompleteResults(this, CodeCompleter, - Results.getCompletionContext(), + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), Results.data(), Results.size()); } struct Sema::CodeCompleteExpressionData { CodeCompleteExpressionData(QualType PreferredType = QualType()) - : PreferredType(PreferredType), IntegralConstantExpression(false), - ObjCCollection(false) { } + : PreferredType(PreferredType), IntegralConstantExpression(false), + ObjCCollection(false) {} QualType PreferredType; bool IntegralConstantExpression; @@ -3738,12 +3903,11 @@ void Sema::CodeCompleteExpression(Scope *S, bool PreferredTypeIsPointer = false; if (!Data.PreferredType.isNull()) - PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() - || Data.PreferredType->isMemberPointerType() - || Data.PreferredType->isBlockPointerType(); + PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType() || + Data.PreferredType->isMemberPointerType() || + Data.PreferredType->isBlockPointerType(); - if (S->getFnParent() && - !Data.ObjCCollection && + if (S->getFnParent() && !Data.ObjCCollection && !Data.IntegralConstantExpression) AddPrettyFunctionResults(getLangOpts(), Results); @@ -3761,13 +3925,13 @@ void Sema::CodeCompleteExpression(Scope *S, QualType PreferredType) { void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) { if (E.isInvalid()) CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction); - else if (getLangOpts().ObjC1) + else if (getLangOpts().ObjC) CodeCompleteObjCInstanceMessage(S, E.get(), None, false); } /// The set of properties that have already been added, referenced by /// property name. -typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet; +typedef llvm::SmallPtrSet<IdentifierInfo *, 16> AddedPropertiesSet; /// Retrieve the container definition, if any? static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) { @@ -3825,11 +3989,13 @@ static void AddObjCBlockCall(ASTContext &Context, const PrintingPolicy &Policy, Builder.AddChunk(CodeCompletionString::CK_RightParen); } -static void AddObjCProperties( - const CodeCompletionContext &CCContext, ObjCContainerDecl *Container, - bool AllowCategories, bool AllowNullaryMethods, DeclContext *CurContext, - AddedPropertiesSet &AddedProperties, ResultBuilder &Results, - bool IsBaseExprStatement = false, bool IsClassProperty = false) { +static void +AddObjCProperties(const CodeCompletionContext &CCContext, + ObjCContainerDecl *Container, bool AllowCategories, + bool AllowNullaryMethods, DeclContext *CurContext, + AddedPropertiesSet &AddedProperties, ResultBuilder &Results, + bool IsBaseExprStatement = false, + bool IsClassProperty = false, bool InOriginalClass = true) { typedef CodeCompletionResult Result; // Retrieve the definition. @@ -3844,8 +4010,10 @@ static void AddObjCProperties( // expressions. if (!P->getType().getTypePtr()->isBlockPointerType() || !IsBaseExprStatement) { - Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), - CurContext); + Result R = Result(P, Results.getBasePriority(P), nullptr); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); return; } @@ -3856,8 +4024,10 @@ static void AddObjCProperties( findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc, BlockProtoLoc); if (!BlockLoc) { - Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), - CurContext); + Result R = Result(P, Results.getBasePriority(P), nullptr); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); return; } @@ -3868,9 +4038,10 @@ static void AddObjCProperties( AddObjCBlockCall(Container->getASTContext(), getCompletionPrintingPolicy(Results.getSema()), Builder, P, BlockLoc, BlockProtoLoc); - Results.MaybeAddResult( - Result(Builder.TakeString(), P, Results.getBasePriority(P)), - CurContext); + Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P)); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); // Provide additional block setter completion iff the base expression is a // statement and the block property is mutable. @@ -3896,13 +4067,15 @@ static void AddObjCProperties( // otherwise the setter completion should show up before the default // property completion, as we normally want to use the result of the // call. - Results.MaybeAddResult( + Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P) + (BlockLoc.getTypePtr()->getReturnType()->isVoidType() ? CCD_BlockPropertySetter - : -CCD_BlockPropertySetter)), - CurContext); + : -CCD_BlockPropertySetter)); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); } }; @@ -3930,10 +4103,11 @@ static void AddObjCProperties( AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), Builder); Builder.AddTypedTextChunk( Results.getAllocator().CopyString(Name->getName())); - Results.MaybeAddResult( - Result(Builder.TakeString(), M, - CCP_MemberDeclaration + CCD_MethodAsProperty), - CurContext); + Result R = Result(Builder.TakeString(), M, + CCP_MemberDeclaration + CCD_MethodAsProperty); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); }; if (IsClassProperty) { @@ -3959,42 +4133,47 @@ static void AddObjCProperties( for (auto *P : Protocol->protocols()) AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); - } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){ + IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/ false); + } else if (ObjCInterfaceDecl *IFace = + dyn_cast<ObjCInterfaceDecl>(Container)) { if (AllowCategories) { // Look through categories. for (auto *Cat : IFace->known_categories()) AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + InOriginalClass); } // Look through protocols. for (auto *I : IFace->all_referenced_protocols()) AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/ false); // Look in the superclass. if (IFace->getSuperClass()) AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, - Results, IsBaseExprStatement, IsClassProperty); - } else if (const ObjCCategoryDecl *Category - = dyn_cast<ObjCCategoryDecl>(Container)) { + Results, IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/ false); + } else if (const auto *Category = + dyn_cast<ObjCCategoryDecl>(Container)) { // Look through protocols. for (auto *P : Category->protocols()) AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/ false); } } -static void AddRecordMembersCompletionResults(Sema &SemaRef, - ResultBuilder &Results, Scope *S, - QualType BaseType, - RecordDecl *RD, - Optional<FixItHint> AccessOpFixIt) { +static void +AddRecordMembersCompletionResults(Sema &SemaRef, ResultBuilder &Results, + Scope *S, QualType BaseType, RecordDecl *RD, + Optional<FixItHint> AccessOpFixIt) { // Indicate that we are performing a member access, and the cv-qualifiers // for the base object type. Results.setObjectTypeQualifiers(BaseType.getQualifiers()); @@ -4003,8 +4182,8 @@ static void AddRecordMembersCompletionResults(Sema &SemaRef, Results.allowNestedNameSpecifiers(); std::vector<FixItHint> FixIts; if (AccessOpFixIt) - FixIts.emplace_back(AccessOpFixIt.getValue()); - CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext, std::move(FixIts)); + FixIts.emplace_back(AccessOpFixIt.getValue()); + CodeCompletionDeclConsumer Consumer(Results, RD, BaseType, std::move(FixIts)); SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer, SemaRef.CodeCompleter->includeGlobals(), /*IncludeDependentBases=*/true, @@ -4045,7 +4224,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, enum CodeCompletionContext::Kind contextKind; if (IsArrow) { - if (const PointerType *Ptr = ConvertedBaseType->getAs<PointerType>()) + if (const auto *Ptr = ConvertedBaseType->getAs<PointerType>()) ConvertedBaseType = Ptr->getPointeeType(); } @@ -4065,7 +4244,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, CodeCompleter->getCodeCompletionTUInfo(), CCContext, &ResultBuilder::IsMember); - auto DoCompletion = [&](Expr *Base, bool IsArrow, Optional<FixItHint> AccessOpFixIt) -> bool { + auto DoCompletion = [&](Expr *Base, bool IsArrow, + Optional<FixItHint> AccessOpFixIt) -> bool { if (!Base) return false; @@ -4119,7 +4299,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, for (auto *I : BaseType->getAs<ObjCObjectPointerType>()->quals()) AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true, CurContext, AddedProperties, Results, - IsBaseExprStatement); + IsBaseExprStatement, /*IsClassProperty*/ false, + /*InOriginalClass*/ false); } else if ((IsArrow && BaseType->isObjCObjectPointerType()) || (!IsArrow && BaseType->isObjCObjectType())) { // Objective-C instance variable access. @@ -4132,7 +4313,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, // Add all ivars from this class and its superclasses. if (Class) { - CodeCompletionDeclConsumer Consumer(Results, CurContext); + CodeCompletionDeclConsumer Consumer(Results, Class, BaseType); Results.setFilter(&ResultBuilder::IsObjCIvar); LookupVisibleDecls( Class, LookupMemberName, Consumer, CodeCompleter->includeGlobals(), @@ -4194,8 +4375,8 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { return; ResultBuilder::LookupFilter Filter = nullptr; - enum CodeCompletionContext::Kind ContextKind - = CodeCompletionContext::CCC_Other; + enum CodeCompletionContext::Kind ContextKind = + CodeCompletionContext::CCC_Other; switch ((DeclSpec::TST)TagSpec) { case DeclSpec::TST_enum: Filter = &ResultBuilder::IsEnum; @@ -4237,7 +4418,7 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) { } HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), - Results.data(),Results.size()); + Results.data(), Results.size()); } static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results, @@ -4261,8 +4442,7 @@ void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) { Results.EnterNewScope(); AddTypeQualifierResults(DS, Results, LangOpts); Results.ExitScope(); - HandleCodeCompleteResults(this, CodeCompleter, - Results.getCompletionContext(), + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), Results.data(), Results.size()); } @@ -4297,6 +4477,9 @@ void Sema::CodeCompleteCase(Scope *S) { return; SwitchStmt *Switch = getCurFunction()->SwitchStack.back().getPointer(); + // Condition expression might be invalid, do not continue in this case. + if (!Switch->getCond()) + return; QualType type = Switch->getCond()->IgnoreImplicit()->getType(); if (!type->isEnumeralType()) { CodeCompleteExpressionData Data(type); @@ -4324,9 +4507,9 @@ void Sema::CodeCompleteCase(Scope *S) { continue; Expr *CaseVal = Case->getLHS()->IgnoreParenCasts(); - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal)) - if (EnumConstantDecl *Enumerator - = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { + if (auto *DRE = dyn_cast<DeclRefExpr>(CaseVal)) + if (auto *Enumerator = + dyn_cast<EnumConstantDecl>(DRE->getDecl())) { // We look into the AST of the case statement to determine which // enumerator was named. Alternatively, we could compute the value of // the integral constant expression, then compare it against the @@ -4391,10 +4574,9 @@ static bool anyNullArguments(ArrayRef<Expr *> Args) { typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate; -static void mergeCandidatesWithResults(Sema &SemaRef, - SmallVectorImpl<ResultCandidate> &Results, - OverloadCandidateSet &CandidateSet, - SourceLocation Loc) { +static void mergeCandidatesWithResults( + Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results, + OverloadCandidateSet &CandidateSet, SourceLocation Loc) { if (!CandidateSet.empty()) { // Sort the overload candidate set by placing the best overloads first. std::stable_sort( @@ -4405,7 +4587,7 @@ static void mergeCandidatesWithResults(Sema &SemaRef, }); // Add the remaining viable overload candidates as code-completion results. - for (auto &Candidate : CandidateSet) { + for (OverloadCandidate &Candidate : CandidateSet) { if (Candidate.Function && Candidate.Function->isDeleted()) continue; if (Candidate.Viable) @@ -4417,22 +4599,21 @@ static void mergeCandidatesWithResults(Sema &SemaRef, /// Get the type of the Nth parameter from a given set of overload /// candidates. static QualType getParamType(Sema &SemaRef, - ArrayRef<ResultCandidate> Candidates, - unsigned N) { + ArrayRef<ResultCandidate> Candidates, unsigned N) { // Given the overloads 'Candidates' for a function call matching all arguments // up to N, return the type of the Nth parameter if it is the same for all // overload candidates. QualType ParamType; for (auto &Candidate : Candidates) { - if (auto FType = Candidate.getFunctionType()) - if (auto Proto = dyn_cast<FunctionProtoType>(FType)) + if (const auto *FType = Candidate.getFunctionType()) + if (const auto *Proto = dyn_cast<FunctionProtoType>(FType)) if (N < Proto->getNumParams()) { if (ParamType.isNull()) ParamType = Proto->getParamType(N); else if (!SemaRef.Context.hasSameUnqualifiedType( - ParamType.getNonReferenceType(), - Proto->getParamType(N).getNonReferenceType())) + ParamType.getNonReferenceType(), + Proto->getParamType(N).getNonReferenceType())) // Otherwise return a default-constructed QualType. return QualType(); } @@ -4491,13 +4672,12 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase(); AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs, /*SuppressUsedConversions=*/false, - /*PartialOverloading=*/true, - FirstArgumentIsBase); + /*PartialOverloading=*/true, FirstArgumentIsBase); } else { FunctionDecl *FD = nullptr; - if (auto MCE = dyn_cast<MemberExpr>(NakedFn)) + if (auto *MCE = dyn_cast<MemberExpr>(NakedFn)) FD = dyn_cast<FunctionDecl>(MCE->getMemberDecl()); - else if (auto DRE = dyn_cast<DeclRefExpr>(NakedFn)) + else if (auto *DRE = dyn_cast<DeclRefExpr>(NakedFn)) FD = dyn_cast<FunctionDecl>(DRE->getDecl()); if (FD) { // We check whether it's a resolved function declaration. if (!getLangOpts().CPlusPlus || @@ -4514,8 +4694,8 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, // call operator, so we check if it does and add them as candidates. // A complete type is needed to lookup for member function call operators. if (isCompleteType(Loc, NakedFn->getType())) { - DeclarationName OpName = Context.DeclarationNames - .getCXXOperatorName(OO_Call); + DeclarationName OpName = + Context.DeclarationNames.getCXXOperatorName(OO_Call); LookupResult R(*this, OpName, Loc, LookupOrdinaryName); LookupQualifiedName(R, DC); R.suppressDiagnostics(); @@ -4535,7 +4715,7 @@ QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, if (auto FP = T->getAs<FunctionProtoType>()) { if (!TooManyArguments(FP->getNumParams(), Args.size(), - /*PartialOverloading=*/true) || + /*PartialOverloading=*/true) || FP->isVariadic()) Results.push_back(ResultCandidate(FP)); } else if (auto FT = T->getAs<FunctionType>()) @@ -4567,19 +4747,18 @@ QualType Sema::ProduceConstructorSignatureHelp(Scope *S, QualType Type, OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal); - for (auto C : LookupConstructors(RD)) { - if (auto FD = dyn_cast<FunctionDecl>(C)) { - AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), - Args, CandidateSet, + for (NamedDecl *C : LookupConstructors(RD)) { + if (auto *FD = dyn_cast<FunctionDecl>(C)) { + AddOverloadCandidate(FD, DeclAccessPair::make(FD, C->getAccess()), Args, + CandidateSet, /*SuppressUsedConversions=*/false, /*PartialOverloading=*/true); - } else if (auto FTD = dyn_cast<FunctionTemplateDecl>(C)) { - AddTemplateOverloadCandidate(FTD, - DeclAccessPair::make(FTD, C->getAccess()), - /*ExplicitTemplateArgs=*/nullptr, - Args, CandidateSet, - /*SuppressUsedConversions=*/false, - /*PartialOverloading=*/true); + } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(C)) { + AddTemplateOverloadCandidate( + FTD, DeclAccessPair::make(FTD, C->getAccess()), + /*ExplicitTemplateArgs=*/nullptr, Args, CandidateSet, + /*SuppressUsedConversions=*/false, + /*PartialOverloading=*/true); } } @@ -4614,7 +4793,12 @@ void Sema::CodeCompleteInitializer(Scope *S, Decl *D) { return; } - CodeCompleteExpression(S, VD->getType()); + CodeCompleteExpressionData Data; + Data.PreferredType = VD->getType(); + // Ignore VD to avoid completing the variable itself, e.g. in 'int foo = ^'. + Data.IgnoreDecls.push_back(VD); + + CodeCompleteExpression(S, Data); } void Sema::CodeCompleteReturn(Scope *S) { @@ -4622,9 +4806,9 @@ void Sema::CodeCompleteReturn(Scope *S) { if (isa<BlockDecl>(CurContext)) { if (BlockScopeInfo *BSI = getCurBlock()) ResultType = BSI->ReturnType; - } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext)) + } else if (const auto *Function = dyn_cast<FunctionDecl>(CurContext)) ResultType = Function->getReturnType(); - else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext)) + else if (const auto *Method = dyn_cast<ObjCMethodDecl>(CurContext)) ResultType = Method->getReturnType(); if (ResultType.isNull()) @@ -4691,18 +4875,96 @@ void Sema::CodeCompleteAfterIf(Scope *S) { AddMacroResults(PP, Results, CodeCompleter->loadExternal(), false); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), - Results.data(),Results.size()); + Results.data(), Results.size()); +} + +static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS, + tok::TokenKind Op) { + if (!LHS) + return QualType(); + + QualType LHSType = LHS->getType(); + if (LHSType->isPointerType()) { + if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal) + return S.getASTContext().getPointerDiffType(); + // Pointer difference is more common than subtracting an int from a pointer. + if (Op == tok::minus) + return LHSType; + } + + switch (Op) { + // No way to infer the type of RHS from LHS. + case tok::comma: + return QualType(); + // Prefer the type of the left operand for all of these. + // Arithmetic operations. + case tok::plus: + case tok::plusequal: + case tok::minus: + case tok::minusequal: + case tok::percent: + case tok::percentequal: + case tok::slash: + case tok::slashequal: + case tok::star: + case tok::starequal: + // Assignment. + case tok::equal: + // Comparison operators. + case tok::equalequal: + case tok::exclaimequal: + case tok::less: + case tok::lessequal: + case tok::greater: + case tok::greaterequal: + case tok::spaceship: + return LHS->getType(); + // Binary shifts are often overloaded, so don't try to guess those. + case tok::greatergreater: + case tok::greatergreaterequal: + case tok::lessless: + case tok::lesslessequal: + if (LHSType->isIntegralOrEnumerationType()) + return S.getASTContext().IntTy; + return QualType(); + // Logical operators, assume we want bool. + case tok::ampamp: + case tok::pipepipe: + case tok::caretcaret: + return S.getASTContext().BoolTy; + // Operators often used for bit manipulation are typically used with the type + // of the left argument. + case tok::pipe: + case tok::pipeequal: + case tok::caret: + case tok::caretequal: + case tok::amp: + case tok::ampequal: + if (LHSType->isIntegralOrEnumerationType()) + return LHSType; + return QualType(); + // RHS should be a pointer to a member of the 'LHS' type, but we can't give + // any particular type here. + case tok::periodstar: + case tok::arrowstar: + return QualType(); + default: + // FIXME(ibiryukov): handle the missing op, re-add the assertion. + // assert(false && "unhandled binary op"); + return QualType(); + } } -void Sema::CodeCompleteAssignmentRHS(Scope *S, Expr *LHS) { - if (LHS) - CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType()); +void Sema::CodeCompleteBinaryRHS(Scope *S, Expr *LHS, tok::TokenKind Op) { + auto PreferredType = getPreferredTypeOfBinaryRHS(*this, LHS, Op); + if (!PreferredType.isNull()) + CodeCompleteExpression(S, PreferredType); else CodeCompleteOrdinaryName(S, PCC_Expression); } void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, - bool EnteringContext) { + bool EnteringContext, QualType BaseType) { if (SS.isEmpty() || !CodeCompleter) return; @@ -4711,7 +4973,7 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, // it can be useful for global code completion which have information about // contexts/symbols that are not in the AST. if (SS.isInvalid()) { - CodeCompletionContext CC(CodeCompletionContext::CCC_Name); + CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol); CC.setCXXScopeSpecifier(SS); HandleCodeCompleteResults(this, CodeCompleter, CC, nullptr, 0); return; @@ -4729,7 +4991,7 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext::CCC_Name); + CodeCompletionContext::CCC_Symbol); Results.EnterNewScope(); // The "template" keyword can follow "::" in the grammar, but only @@ -4749,7 +5011,7 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, if (CodeCompleter->includeNamespaceLevelDecls() || (!Ctx->isNamespace() && !Ctx->isTranslationUnit())) { - CodeCompletionDeclConsumer Consumer(Results, CurContext); + CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType); LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer, /*IncludeGlobalScope=*/true, /*IncludeDependentBases=*/true, @@ -4769,7 +5031,10 @@ void Sema::CodeCompleteUsing(Scope *S) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext::CCC_PotentiallyQualifiedName, + // This can be both a using alias or using + // declaration, in the former we expect a new name and a + // symbol in the latter case. + CodeCompletionContext::CCC_SymbolOrNewName, &ResultBuilder::IsNestedNameSpecifier); Results.EnterNewScope(); @@ -4809,7 +5074,7 @@ void Sema::CodeCompleteUsingDirective(Scope *S) { Results.data(), Results.size()); } -void Sema::CodeCompleteNamespaceDecl(Scope *S) { +void Sema::CodeCompleteNamespaceDecl(Scope *S) { if (!CodeCompleter) return; @@ -4817,14 +5082,14 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) { if (!S->getParent()) Ctx = Context.getTranslationUnitDecl(); - bool SuppressedGlobalResults - = Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx); + bool SuppressedGlobalResults = + Ctx && !CodeCompleter->includeGlobals() && isa<TranslationUnitDecl>(Ctx); ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), SuppressedGlobalResults - ? CodeCompletionContext::CCC_Namespace - : CodeCompletionContext::CCC_Other, + ? CodeCompletionContext::CCC_Namespace + : CodeCompletionContext::CCC_Other, &ResultBuilder::IsNamespace); if (Ctx && Ctx->isFileContext() && !SuppressedGlobalResults) { @@ -4834,7 +5099,8 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) { // definition of each namespace. std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest; for (DeclContext::specific_decl_iterator<NamespaceDecl> - NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end()); + NS(Ctx->decls_begin()), + NSEnd(Ctx->decls_end()); NS != NSEnd; ++NS) OrigToLatest[NS->getOriginalNamespace()] = *NS; @@ -4842,22 +5108,21 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S) { // namespace to the list of results. Results.EnterNewScope(); for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator - NS = OrigToLatest.begin(), - NSEnd = OrigToLatest.end(); + NS = OrigToLatest.begin(), + NSEnd = OrigToLatest.end(); NS != NSEnd; ++NS) - Results.AddResult(CodeCompletionResult( - NS->second, Results.getBasePriority(NS->second), - nullptr), - CurContext, nullptr, false); + Results.AddResult( + CodeCompletionResult(NS->second, Results.getBasePriority(NS->second), + nullptr), + CurContext, nullptr, false); Results.ExitScope(); } - HandleCodeCompleteResults(this, CodeCompleter, - Results.getCompletionContext(), - Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), + Results.data(), Results.size()); } -void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { +void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { if (!CodeCompleter) return; @@ -4870,9 +5135,8 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) { LookupVisibleDecls(S, LookupOrdinaryName, Consumer, CodeCompleter->includeGlobals(), CodeCompleter->loadExternal()); - HandleCodeCompleteResults(this, CodeCompleter, - Results.getCompletionContext(), - Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), + Results.data(), Results.size()); } void Sema::CodeCompleteOperatorName(Scope *S) { @@ -4887,8 +5151,8 @@ void Sema::CodeCompleteOperatorName(Scope *S) { Results.EnterNewScope(); // Add the names of overloadable operators. -#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ - if (std::strcmp(Spelling, "?")) \ +#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ + if (std::strcmp(Spelling, "?")) \ Results.AddResult(Result(Spelling)); #include "clang/Basic/OperatorKinds.def" @@ -4908,20 +5172,19 @@ void Sema::CodeCompleteOperatorName(Scope *S) { } void Sema::CodeCompleteConstructorInitializer( - Decl *ConstructorD, - ArrayRef <CXXCtorInitializer *> Initializers) { + Decl *ConstructorD, ArrayRef<CXXCtorInitializer *> Initializers) { if (!ConstructorD) return; AdjustDeclIfTemplate(ConstructorD); - CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD); + auto *Constructor = dyn_cast<CXXConstructorDecl>(ConstructorD); if (!Constructor) return; ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext::CCC_PotentiallyQualifiedName); + CodeCompletionContext::CCC_Symbol); Results.EnterNewScope(); // Fill in any already-initialized fields or base classes. @@ -4929,39 +5192,96 @@ void Sema::CodeCompleteConstructorInitializer( llvm::SmallPtrSet<CanQualType, 4> InitializedBases; for (unsigned I = 0, E = Initializers.size(); I != E; ++I) { if (Initializers[I]->isBaseInitializer()) - InitializedBases.insert( - Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0))); + InitializedBases.insert(Context.getCanonicalType( + QualType(Initializers[I]->getBaseClass(), 0))); else - InitializedFields.insert(cast<FieldDecl>( - Initializers[I]->getAnyMember())); + InitializedFields.insert( + cast<FieldDecl>(Initializers[I]->getAnyMember())); } // Add completions for base classes. - CodeCompletionBuilder Builder(Results.getAllocator(), - Results.getCodeCompletionTUInfo()); PrintingPolicy Policy = getCompletionPrintingPolicy(*this); bool SawLastInitializer = Initializers.empty(); CXXRecordDecl *ClassDecl = Constructor->getParent(); + + auto GenerateCCS = [&](const NamedDecl *ND, const char *Name) { + CodeCompletionBuilder Builder(Results.getAllocator(), + Results.getCodeCompletionTUInfo()); + Builder.AddTypedTextChunk(Name); + Builder.AddChunk(CodeCompletionString::CK_LeftParen); + if (const auto *Function = dyn_cast<FunctionDecl>(ND)) + AddFunctionParameterChunks(PP, Policy, Function, Builder); + else if (const auto *FunTemplDecl = dyn_cast<FunctionTemplateDecl>(ND)) + AddFunctionParameterChunks(PP, Policy, FunTemplDecl->getTemplatedDecl(), + Builder); + Builder.AddChunk(CodeCompletionString::CK_RightParen); + return Builder.TakeString(); + }; + auto AddDefaultCtorInit = [&](const char *Name, const char *Type, + const NamedDecl *ND) { + CodeCompletionBuilder Builder(Results.getAllocator(), + Results.getCodeCompletionTUInfo()); + Builder.AddTypedTextChunk(Name); + Builder.AddChunk(CodeCompletionString::CK_LeftParen); + Builder.AddPlaceholderChunk(Type); + Builder.AddChunk(CodeCompletionString::CK_RightParen); + if (ND) { + auto CCR = CodeCompletionResult( + Builder.TakeString(), ND, + SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration); + if (isa<FieldDecl>(ND)) + CCR.CursorKind = CXCursor_MemberRef; + return Results.AddResult(CCR); + } + return Results.AddResult(CodeCompletionResult( + Builder.TakeString(), + SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration)); + }; + auto AddCtorsWithName = [&](const CXXRecordDecl *RD, unsigned int Priority, + const char *Name, const FieldDecl *FD) { + if (!RD) + return AddDefaultCtorInit(Name, + FD ? Results.getAllocator().CopyString( + FD->getType().getAsString(Policy)) + : Name, + FD); + auto Ctors = getConstructors(Context, RD); + if (Ctors.begin() == Ctors.end()) + return AddDefaultCtorInit(Name, Name, RD); + for (const NamedDecl *Ctor : Ctors) { + auto CCR = CodeCompletionResult(GenerateCCS(Ctor, Name), RD, Priority); + CCR.CursorKind = getCursorKindForDecl(Ctor); + Results.AddResult(CCR); + } + }; + auto AddBase = [&](const CXXBaseSpecifier &Base) { + const char *BaseName = + Results.getAllocator().CopyString(Base.getType().getAsString(Policy)); + const auto *RD = Base.getType()->getAsCXXRecordDecl(); + AddCtorsWithName( + RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration, + BaseName, nullptr); + }; + auto AddField = [&](const FieldDecl *FD) { + const char *FieldName = + Results.getAllocator().CopyString(FD->getIdentifier()->getName()); + const CXXRecordDecl *RD = FD->getType()->getAsCXXRecordDecl(); + AddCtorsWithName( + RD, SawLastInitializer ? CCP_NextInitializer : CCP_MemberDeclaration, + FieldName, FD); + }; + for (const auto &Base : ClassDecl->bases()) { if (!InitializedBases.insert(Context.getCanonicalType(Base.getType())) .second) { - SawLastInitializer - = !Initializers.empty() && - Initializers.back()->isBaseInitializer() && - Context.hasSameUnqualifiedType(Base.getType(), - QualType(Initializers.back()->getBaseClass(), 0)); + SawLastInitializer = + !Initializers.empty() && Initializers.back()->isBaseInitializer() && + Context.hasSameUnqualifiedType( + Base.getType(), QualType(Initializers.back()->getBaseClass(), 0)); continue; } - Builder.AddTypedTextChunk( - Results.getAllocator().CopyString( - Base.getType().getAsString(Policy))); - Builder.AddChunk(CodeCompletionString::CK_LeftParen); - Builder.AddPlaceholderChunk("args"); - Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - SawLastInitializer? CCP_NextInitializer - : CCP_MemberDeclaration)); + AddBase(Base); SawLastInitializer = false; } @@ -4969,23 +5289,14 @@ void Sema::CodeCompleteConstructorInitializer( for (const auto &Base : ClassDecl->vbases()) { if (!InitializedBases.insert(Context.getCanonicalType(Base.getType())) .second) { - SawLastInitializer - = !Initializers.empty() && - Initializers.back()->isBaseInitializer() && - Context.hasSameUnqualifiedType(Base.getType(), - QualType(Initializers.back()->getBaseClass(), 0)); + SawLastInitializer = + !Initializers.empty() && Initializers.back()->isBaseInitializer() && + Context.hasSameUnqualifiedType( + Base.getType(), QualType(Initializers.back()->getBaseClass(), 0)); continue; } - Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString( - Base.getType().getAsString(Policy))); - Builder.AddChunk(CodeCompletionString::CK_LeftParen); - Builder.AddPlaceholderChunk("args"); - Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - SawLastInitializer? CCP_NextInitializer - : CCP_MemberDeclaration)); + AddBase(Base); SawLastInitializer = false; } @@ -4993,27 +5304,16 @@ void Sema::CodeCompleteConstructorInitializer( for (auto *Field : ClassDecl->fields()) { if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl())) .second) { - SawLastInitializer - = !Initializers.empty() && - Initializers.back()->isAnyMemberInitializer() && - Initializers.back()->getAnyMember() == Field; + SawLastInitializer = !Initializers.empty() && + Initializers.back()->isAnyMemberInitializer() && + Initializers.back()->getAnyMember() == Field; continue; } if (!Field->getDeclName()) continue; - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - Field->getIdentifier()->getName())); - Builder.AddChunk(CodeCompletionString::CK_LeftParen); - Builder.AddPlaceholderChunk("args"); - Builder.AddChunk(CodeCompletionString::CK_RightParen); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - SawLastInitializer? CCP_NextInitializer - : CCP_MemberDeclaration, - CXCursor_MemberRef, - CXAvailability_Available, - Field)); + AddField(Field); SawLastInitializer = false; } Results.ExitScope(); @@ -5054,9 +5354,7 @@ void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, for (; S && !isNamespaceScope(S); S = S->getParent()) { for (const auto *D : S->decls()) { const auto *Var = dyn_cast<VarDecl>(D); - if (!Var || - !Var->hasLocalStorage() || - Var->hasAttr<BlocksAttr>()) + if (!Var || !Var->hasLocalStorage() || Var->hasAttr<BlocksAttr>()) continue; if (Known.insert(Var->getIdentifier()).second) @@ -5077,26 +5375,25 @@ void Sema::CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, /// Macro that optionally prepends an "@" to the string literal passed in via /// Keyword, depending on whether NeedAt is true or false. -#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) ((NeedAt)? "@" Keyword : Keyword) +#define OBJC_AT_KEYWORD_NAME(NeedAt, Keyword) ((NeedAt) ? "@" Keyword : Keyword) static void AddObjCImplementationResults(const LangOptions &LangOpts, - ResultBuilder &Results, - bool NeedAt) { + ResultBuilder &Results, bool NeedAt) { typedef CodeCompletionResult Result; // Since we have an implementation, we can end it. - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end"))); CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); - if (LangOpts.ObjC2) { + if (LangOpts.ObjC) { // @dynamic - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"dynamic")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "dynamic")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("property"); Results.AddResult(Result(Builder.TakeString())); // @synthesize - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synthesize")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synthesize")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("property"); Results.AddResult(Result(Builder.TakeString())); @@ -5104,22 +5401,21 @@ static void AddObjCImplementationResults(const LangOptions &LangOpts, } static void AddObjCInterfaceResults(const LangOptions &LangOpts, - ResultBuilder &Results, - bool NeedAt) { + ResultBuilder &Results, bool NeedAt) { typedef CodeCompletionResult Result; // Since we have an interface or protocol, we can end it. - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"end"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "end"))); - if (LangOpts.ObjC2) { + if (LangOpts.ObjC) { // @property - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"property"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "property"))); // @required - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"required"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "required"))); // @optional - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"optional"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "optional"))); } } @@ -5129,7 +5425,7 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) { Results.getCodeCompletionTUInfo()); // @class name ; - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"class")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "class")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("name"); Results.AddResult(Result(Builder.TakeString())); @@ -5138,26 +5434,27 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) { // @interface name // FIXME: Could introduce the whole pattern, including superclasses and // such. - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"interface")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "interface")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("class"); Results.AddResult(Result(Builder.TakeString())); // @protocol name - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("protocol"); Results.AddResult(Result(Builder.TakeString())); // @implementation name - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"implementation")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "implementation")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("class"); Results.AddResult(Result(Builder.TakeString())); } // @compatibility_alias name - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"compatibility_alias")); + Builder.AddTypedTextChunk( + OBJC_AT_KEYWORD_NAME(NeedAt, "compatibility_alias")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("alias"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); @@ -5200,7 +5497,7 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { Results.getSema().getLangOpts().ConstStrings) EncodeType = "const char[]"; Builder.AddResultTypeChunk(EncodeType); - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"encode")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "encode")); Builder.AddChunk(CodeCompletionString::CK_LeftParen); Builder.AddPlaceholderChunk("type-name"); Builder.AddChunk(CodeCompletionString::CK_RightParen); @@ -5208,7 +5505,7 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { // @protocol ( protocol-name ) Builder.AddResultTypeChunk("Protocol *"); - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"protocol")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "protocol")); Builder.AddChunk(CodeCompletionString::CK_LeftParen); Builder.AddPlaceholderChunk("protocol-name"); Builder.AddChunk(CodeCompletionString::CK_RightParen); @@ -5216,7 +5513,7 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { // @selector ( selector ) Builder.AddResultTypeChunk("SEL"); - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"selector")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "selector")); Builder.AddChunk(CodeCompletionString::CK_LeftParen); Builder.AddPlaceholderChunk("selector"); Builder.AddChunk(CodeCompletionString::CK_RightParen); @@ -5224,21 +5521,21 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) { // @"string" Builder.AddResultTypeChunk("NSString *"); - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"\"")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "\"")); Builder.AddPlaceholderChunk("string"); Builder.AddTextChunk("\""); Results.AddResult(Result(Builder.TakeString())); // @[objects, ...] Builder.AddResultTypeChunk("NSArray *"); - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"[")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "[")); Builder.AddPlaceholderChunk("objects, ..."); Builder.AddChunk(CodeCompletionString::CK_RightBracket); Results.AddResult(Result(Builder.TakeString())); // @{key : object, ...} Builder.AddResultTypeChunk("NSDictionary *"); - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "{")); Builder.AddPlaceholderChunk("key"); Builder.AddChunk(CodeCompletionString::CK_Colon); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); @@ -5262,7 +5559,7 @@ static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) { if (Results.includeCodePatterns()) { // @try { statements } @catch ( declaration ) { statements } @finally // { statements } - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"try")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "try")); Builder.AddChunk(CodeCompletionString::CK_LeftBrace); Builder.AddPlaceholderChunk("statements"); Builder.AddChunk(CodeCompletionString::CK_RightBrace); @@ -5281,14 +5578,14 @@ static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) { } // @throw - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"throw")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "throw")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("expression"); Results.AddResult(Result(Builder.TakeString())); if (Results.includeCodePatterns()) { // @synchronized ( expression ) { statements } - Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"synchronized")); + Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt, "synchronized")); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddChunk(CodeCompletionString::CK_LeftParen); Builder.AddPlaceholderChunk("expression"); @@ -5301,14 +5598,13 @@ static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) { } static void AddObjCVisibilityResults(const LangOptions &LangOpts, - ResultBuilder &Results, - bool NeedAt) { + ResultBuilder &Results, bool NeedAt) { typedef CodeCompletionResult Result; - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"private"))); - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"protected"))); - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"public"))); - if (LangOpts.ObjC2) - Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,"package"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "private"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "protected"))); + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "public"))); + if (LangOpts.ObjC) + Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt, "package"))); } void Sema::CodeCompleteObjCAtVisibility(Scope *S) { @@ -5360,14 +5656,12 @@ static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) { return true; // Check for more than one of { assign, copy, retain, strong, weak }. - unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign | - ObjCDeclSpec::DQ_PR_unsafe_unretained | - ObjCDeclSpec::DQ_PR_copy | - ObjCDeclSpec::DQ_PR_retain | - ObjCDeclSpec::DQ_PR_strong | - ObjCDeclSpec::DQ_PR_weak); - if (AssignCopyRetMask && - AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign && + unsigned AssignCopyRetMask = + Attributes & + (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_unsafe_unretained | + ObjCDeclSpec::DQ_PR_copy | ObjCDeclSpec::DQ_PR_retain | + ObjCDeclSpec::DQ_PR_strong | ObjCDeclSpec::DQ_PR_weak); + if (AssignCopyRetMask && AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign && AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained && AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy && AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain && @@ -5445,11 +5739,10 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { enum ObjCMethodKind { MK_Any, ///< Any kind of method, provided it means other specified criteria. MK_ZeroArgSelector, ///< Zero-argument (unary) selector. - MK_OneArgSelector ///< One-argument selector. + MK_OneArgSelector ///< One-argument selector. }; -static bool isAcceptableObjCSelector(Selector Sel, - ObjCMethodKind WantKind, +static bool isAcceptableObjCSelector(Selector Sel, ObjCMethodKind WantKind, ArrayRef<IdentifierInfo *> SelIdents, bool AllowSameLength = true) { unsigned NumSelIdents = SelIdents.size(); @@ -5457,9 +5750,12 @@ static bool isAcceptableObjCSelector(Selector Sel, return false; switch (WantKind) { - case MK_Any: break; - case MK_ZeroArgSelector: return Sel.isUnarySelector(); - case MK_OneArgSelector: return Sel.getNumArgs() == 1; + case MK_Any: + break; + case MK_ZeroArgSelector: + return Sel.isUnarySelector(); + case MK_OneArgSelector: + return Sel.getNumArgs() == 1; } if (!AllowSameLength && NumSelIdents && NumSelIdents == Sel.getNumArgs()) @@ -5480,11 +5776,9 @@ static bool isAcceptableObjCMethod(ObjCMethodDecl *Method, AllowSameLength); } -namespace { - /// A set of selectors, which is used to avoid introducing multiple - /// completions with the same selector into the result set. - typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet; -} +/// A set of selectors, which is used to avoid introducing multiple +/// completions with the same selector into the result set. +typedef llvm::SmallPtrSet<Selector, 16> VisitedSelectorSet; /// Add all of the Objective-C methods in the given Objective-C /// container to the set of results. @@ -5517,7 +5811,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container, Container = getContainerDef(Container); ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container); IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass()); - for (auto *M : Container->methods()) { + for (ObjCMethodDecl *M : Container->methods()) { // The instance methods on the root class can be messaged via the // metaclass. if (M->isInstanceMethod() == WantInstanceMethods || @@ -5534,16 +5828,16 @@ static void AddObjCMethods(ObjCContainerDecl *Container, R.StartParameter = SelIdents.size(); R.AllParametersAreInformative = (WantKind != MK_Any); if (!InOriginalClass) - R.Priority += CCD_InBaseClass; + setInBaseClass(R); Results.MaybeAddResult(R, CurContext); } } // Visit the protocols of protocols. - if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { + if (const auto *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { if (Protocol->hasDefinition()) { - const ObjCList<ObjCProtocolDecl> &Protocols - = Protocol->getReferencedProtocols(); + const ObjCList<ObjCProtocolDecl> &Protocols = + Protocol->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) @@ -5556,19 +5850,19 @@ static void AddObjCMethods(ObjCContainerDecl *Container, return; // Add methods in protocols. - for (auto *I : IFace->protocols()) + for (ObjCProtocolDecl *I : IFace->protocols()) AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext, Selectors, AllowSameLength, Results, false, IsRootClass); // Add methods in categories. - for (auto *CatDecl : IFace->known_categories()) { + for (ObjCCategoryDecl *CatDecl : IFace->known_categories()) { AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, CurContext, Selectors, AllowSameLength, Results, InOriginalClass, IsRootClass); // Add a categories protocol methods. - const ObjCList<ObjCProtocolDecl> &Protocols - = CatDecl->getReferencedProtocols(); + const ObjCList<ObjCProtocolDecl> &Protocols = + CatDecl->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) @@ -5596,13 +5890,12 @@ static void AddObjCMethods(ObjCContainerDecl *Container, IsRootClass); } - void Sema::CodeCompleteObjCPropertyGetter(Scope *S) { // Try to find the interface where getters might live. ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); if (!Class) { - if (ObjCCategoryDecl *Category - = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) + if (ObjCCategoryDecl *Category = + dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) Class = Category->getClassInterface(); if (!Class) @@ -5625,11 +5918,10 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S) { void Sema::CodeCompleteObjCPropertySetter(Scope *S) { // Try to find the interface where setters might live. - ObjCInterfaceDecl *Class - = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); + ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurContext); if (!Class) { - if (ObjCCategoryDecl *Category - = dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) + if (ObjCCategoryDecl *Category = + dyn_cast_or_null<ObjCCategoryDecl>(CurContext)) Class = Category->getClassInterface(); if (!Class) @@ -5643,8 +5935,8 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S) { Results.EnterNewScope(); VisitedSelectorSet Selectors; - AddObjCMethods(Class, true, MK_OneArgSelector, None, CurContext, - Selectors, /*AllowSameLength=*/true, Results); + AddObjCMethods(Class, true, MK_OneArgSelector, None, CurContext, Selectors, + /*AllowSameLength=*/true, Results); Results.ExitScope(); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), @@ -5675,9 +5967,9 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, if ((DS.getObjCDeclQualifier() & (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref | ObjCDeclSpec::DQ_Oneway)) == 0) { - Results.AddResult("bycopy"); - Results.AddResult("byref"); - Results.AddResult("oneway"); + Results.AddResult("bycopy"); + Results.AddResult("byref"); + Results.AddResult("oneway"); } if ((DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability) == 0) { Results.AddResult("nonnull"); @@ -5733,7 +6025,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS, /// common uses of Objective-C. This routine returns that class type, /// or NULL if no better result could be determined. static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { - ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E); + auto *Msg = dyn_cast_or_null<ObjCMessageExpr>(E); if (!Msg) return nullptr; @@ -5753,8 +6045,8 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { ObjCInterfaceDecl *IFace = nullptr; switch (Msg->getReceiverKind()) { case ObjCMessageExpr::Class: - if (const ObjCObjectType *ObjType - = Msg->getClassReceiver()->getAs<ObjCObjectType>()) + if (const ObjCObjectType *ObjType = + Msg->getClassReceiver()->getAs<ObjCObjectType>()) IFace = ObjType->getInterface(); break; @@ -5776,27 +6068,27 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { ObjCInterfaceDecl *Super = IFace->getSuperClass(); if (Method->isInstanceMethod()) return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) - .Case("retain", IFace) - .Case("strong", IFace) - .Case("autorelease", IFace) - .Case("copy", IFace) - .Case("copyWithZone", IFace) - .Case("mutableCopy", IFace) - .Case("mutableCopyWithZone", IFace) - .Case("awakeFromCoder", IFace) - .Case("replacementObjectFromCoder", IFace) + .Case("retain", IFace) + .Case("strong", IFace) + .Case("autorelease", IFace) + .Case("copy", IFace) + .Case("copyWithZone", IFace) + .Case("mutableCopy", IFace) + .Case("mutableCopyWithZone", IFace) + .Case("awakeFromCoder", IFace) + .Case("replacementObjectFromCoder", IFace) + .Case("class", IFace) + .Case("classForCoder", IFace) + .Case("superclass", Super) + .Default(nullptr); + + return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) + .Case("new", IFace) + .Case("alloc", IFace) + .Case("allocWithZone", IFace) .Case("class", IFace) - .Case("classForCoder", IFace) .Case("superclass", Super) .Default(nullptr); - - return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName()) - .Case("new", IFace) - .Case("alloc", IFace) - .Case("allocWithZone", IFace) - .Case("class", IFace) - .Case("superclass", Super) - .Default(nullptr); } // Add a special completion for a message send to "super", which fills in the @@ -5815,10 +6107,10 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { /// /// \returns the Objective-C method declaration that would be invoked by /// this "super" completion. If NULL, no completion was added. -static ObjCMethodDecl *AddSuperSendCompletion( - Sema &S, bool NeedSuperKeyword, - ArrayRef<IdentifierInfo *> SelIdents, - ResultBuilder &Results) { +static ObjCMethodDecl * +AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword, + ArrayRef<IdentifierInfo *> SelIdents, + ResultBuilder &Results) { ObjCMethodDecl *CurMethod = S.getCurMethodDecl(); if (!CurMethod) return nullptr; @@ -5838,7 +6130,7 @@ static ObjCMethodDecl *AddSuperSendCompletion( if (!SuperMethod) { for (const auto *Cat : Class->known_categories()) { if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(), - CurMethod->isInstanceMethod()))) + CurMethod->isInstanceMethod()))) break; } } @@ -5853,8 +6145,8 @@ static ObjCMethodDecl *AddSuperSendCompletion( return nullptr; for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(), - CurPEnd = CurMethod->param_end(), - SuperP = SuperMethod->param_begin(); + CurPEnd = CurMethod->param_end(), + SuperP = SuperMethod->param_begin(); CurP != CurPEnd; ++CurP, ++SuperP) { // Make sure the parameter types are compatible. if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(), @@ -5872,8 +6164,7 @@ static ObjCMethodDecl *AddSuperSendCompletion( // Give this completion a return type. AddResultTypeChunk(S.Context, getCompletionPrintingPolicy(S), SuperMethod, - Results.getCompletionContext().getBaseType(), - Builder); + Results.getCompletionContext().getBaseType(), Builder); // If we need the "super" keyword, add it (plus some spacing). if (NeedSuperKeyword) { @@ -5884,11 +6175,11 @@ static ObjCMethodDecl *AddSuperSendCompletion( Selector Sel = CurMethod->getSelector(); if (Sel.isUnarySelector()) { if (NeedSuperKeyword) - Builder.AddTextChunk(Builder.getAllocator().CopyString( - Sel.getNameForSlot(0))); + Builder.AddTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(0))); else - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - Sel.getNameForSlot(0))); + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(0))); } else { ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(); for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) { @@ -5897,20 +6188,17 @@ static ObjCMethodDecl *AddSuperSendCompletion( if (I < SelIdents.size()) Builder.AddInformativeChunk( - Builder.getAllocator().CopyString( - Sel.getNameForSlot(I) + ":")); + Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); else if (NeedSuperKeyword || I > SelIdents.size()) { Builder.AddTextChunk( - Builder.getAllocator().CopyString( - Sel.getNameForSlot(I) + ":")); + Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( - (*CurP)->getIdentifier()->getName())); + (*CurP)->getIdentifier()->getName())); } else { Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString( - Sel.getNameForSlot(I) + ":")); + Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); Builder.AddPlaceholderChunk(Builder.getAllocator().CopyString( - (*CurP)->getIdentifier()->getName())); + (*CurP)->getIdentifier()->getName())); } } } @@ -5922,12 +6210,13 @@ static ObjCMethodDecl *AddSuperSendCompletion( void Sema::CodeCompleteObjCMessageReceiver(Scope *S) { typedef CodeCompletionResult Result; - ResultBuilder Results(*this, CodeCompleter->getAllocator(), - CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext::CCC_ObjCMessageReceiver, - getLangOpts().CPlusPlus11 - ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture - : &ResultBuilder::IsObjCMessageReceiver); + ResultBuilder Results( + *this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), + CodeCompletionContext::CCC_ObjCMessageReceiver, + getLangOpts().CPlusPlus11 + ? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture + : &ResultBuilder::IsObjCMessageReceiver); CodeCompletionDeclConsumer Consumer(Results, CurContext); Results.EnterNewScope(); @@ -5976,8 +6265,7 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, // send [super ...] is actually calling an instance method on the // current object. return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents, - AtArgumentExpression, - CDecl); + AtArgumentExpression, CDecl); } // Fall through to send to the superclass in CDecl. @@ -5985,13 +6273,12 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, // "super" may be the name of a type or variable. Figure out which // it is. IdentifierInfo *Super = getSuperIdentifier(); - NamedDecl *ND = LookupSingleName(S, Super, SuperLoc, - LookupOrdinaryName); + NamedDecl *ND = LookupSingleName(S, Super, SuperLoc, LookupOrdinaryName); if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) { // "super" names an interface. Use it. } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) { - if (const ObjCObjectType *Iface - = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>()) + if (const ObjCObjectType *Iface = + Context.getTypeDeclType(TD)->getAs<ObjCObjectType>()) CDecl = Iface->getInterface(); } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) { // "super" names an unresolved type; we can't be more specific. @@ -6001,11 +6288,10 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, SourceLocation TemplateKWLoc; UnqualifiedId id; id.setIdentifier(Super, SuperLoc); - ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id, - false, false); + ExprResult SuperExpr = + ActOnIdExpression(S, SS, TemplateKWLoc, id, false, false); return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(), - SelIdents, - AtArgumentExpression); + SelIdents, AtArgumentExpression); } // Fall through @@ -6036,8 +6322,8 @@ static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results, if (R.Priority <= BestPriority) { const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration); if (NumSelIdents <= Method->param_size()) { - QualType MyPreferredType = Method->parameters()[NumSelIdents - 1] - ->getType(); + QualType MyPreferredType = + Method->parameters()[NumSelIdents - 1]->getType(); if (R.Priority < BestPriority || PreferredType.isNull()) { BestPriority = R.Priority; PreferredType = MyPreferredType; @@ -6056,8 +6342,7 @@ static QualType getPreferredArgumentTypeForMessageSend(ResultBuilder &Results, static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver, ArrayRef<IdentifierInfo *> SelIdents, - bool AtArgumentExpression, - bool IsSuper, + bool AtArgumentExpression, bool IsSuper, ResultBuilder &Results) { typedef CodeCompletionResult Result; ObjCInterfaceDecl *CDecl = nullptr; @@ -6078,8 +6363,8 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, // If this is a send-to-super, try to add the special "super" send // completion. if (IsSuper) { - if (ObjCMethodDecl *SuperMethod - = AddSuperSendCompletion(SemaRef, false, SelIdents, Results)) + if (ObjCMethodDecl *SuperMethod = + AddSuperSendCompletion(SemaRef, false, SelIdents, Results)) Results.Ignore(SuperMethod); } @@ -6090,9 +6375,8 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, VisitedSelectorSet Selectors; if (CDecl) - AddObjCMethods(CDecl, false, MK_Any, SelIdents, - SemaRef.CurContext, Selectors, AtArgumentExpression, - Results); + AddObjCMethods(CDecl, false, MK_Any, SelIdents, SemaRef.CurContext, + Selectors, AtArgumentExpression, Results); else { // We're messaging "id" as a type; provide all class/factory methods. @@ -6111,11 +6395,10 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, } for (Sema::GlobalMethodPool::iterator M = SemaRef.MethodPool.begin(), - MEnd = SemaRef.MethodPool.end(); + MEnd = SemaRef.MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.second; - MethList && MethList->getMethod(); - MethList = MethList->getNext()) { + MethList && MethList->getMethod(); MethList = MethList->getNext()) { if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents)) continue; @@ -6138,10 +6421,11 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, QualType T = this->GetTypeFromParser(Receiver); - ResultBuilder Results(*this, CodeCompleter->getAllocator(), - CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, - T, SelIdents)); + ResultBuilder Results( + *this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), + CodeCompletionContext(CodeCompletionContext::CCC_ObjCClassMessage, T, + SelIdents)); AddClassMessageCompletions(*this, S, Receiver, SelIdents, AtArgumentExpression, IsSuper, Results); @@ -6152,8 +6436,8 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, // code-complete the expression using the corresponding parameter type as // our preferred type, improving completion results. if (AtArgumentExpression) { - QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results, - SelIdents.size()); + QualType PreferredType = + getPreferredArgumentTypeForMessageSend(Results, SelIdents.size()); if (PreferredType.isNull()) CodeCompleteOrdinaryName(S, PCC_Expression); else @@ -6161,8 +6445,7 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, return; } - HandleCodeCompleteResults(this, CodeCompleter, - Results.getCompletionContext(), + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), Results.data(), Results.size()); } @@ -6182,10 +6465,11 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, return; RecExpr = Conv.get(); } - QualType ReceiverType = RecExpr? RecExpr->getType() - : Super? Context.getObjCObjectPointerType( + QualType ReceiverType = RecExpr + ? RecExpr->getType() + : Super ? Context.getObjCObjectPointerType( Context.getObjCInterfaceType(Super)) - : Context.getObjCIdType(); + : Context.getObjCIdType(); // If we're messaging an expression with type "id" or "Class", check // whether we know something special about the receiver that allows @@ -6193,13 +6477,12 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) { if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) { if (ReceiverType->isObjCClassType()) - return CodeCompleteObjCClassMessage(S, - ParsedType::make(Context.getObjCInterfaceType(IFace)), - SelIdents, - AtArgumentExpression, Super); + return CodeCompleteObjCClassMessage( + S, ParsedType::make(Context.getObjCInterfaceType(IFace)), SelIdents, + AtArgumentExpression, Super); - ReceiverType = Context.getObjCObjectPointerType( - Context.getObjCInterfaceType(IFace)); + ReceiverType = + Context.getObjCObjectPointerType(Context.getObjCInterfaceType(IFace)); } } else if (RecExpr && getLangOpts().CPlusPlus) { ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr); @@ -6210,18 +6493,19 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, } // Build the set of methods we can see. - ResultBuilder Results(*this, CodeCompleter->getAllocator(), - CodeCompleter->getCodeCompletionTUInfo(), - CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage, - ReceiverType, SelIdents)); + ResultBuilder Results( + *this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo(), + CodeCompletionContext(CodeCompletionContext::CCC_ObjCInstanceMessage, + ReceiverType, SelIdents)); Results.EnterNewScope(); // If this is a send-to-super, try to add the special "super" send // completion. if (Super) { - if (ObjCMethodDecl *SuperMethod - = AddSuperSendCompletion(*this, false, SelIdents, Results)) + if (ObjCMethodDecl *SuperMethod = + AddSuperSendCompletion(*this, false, SelIdents, Results)) Results.Ignore(SuperMethod); } @@ -6240,30 +6524,29 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, ReceiverType->isObjCQualifiedClassType()) { if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface()) - AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, - CurContext, Selectors, AtArgumentExpression, Results); + AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, CurContext, + Selectors, AtArgumentExpression, Results); } } // Handle messages to a qualified ID ("id<foo>"). - else if (const ObjCObjectPointerType *QualID - = ReceiverType->getAsObjCQualifiedIdType()) { + else if (const ObjCObjectPointerType *QualID = + ReceiverType->getAsObjCQualifiedIdType()) { // Search protocols for instance methods. for (auto *I : QualID->quals()) - AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, - Selectors, AtArgumentExpression, Results); + AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, Selectors, + AtArgumentExpression, Results); } // Handle messages to a pointer to interface type. - else if (const ObjCObjectPointerType *IFacePtr - = ReceiverType->getAsObjCInterfacePointerType()) { + else if (const ObjCObjectPointerType *IFacePtr = + ReceiverType->getAsObjCInterfacePointerType()) { // Search the class, its superclasses, etc., for instance methods. AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents, - CurContext, Selectors, AtArgumentExpression, - Results); + CurContext, Selectors, AtArgumentExpression, Results); // Search protocols for instance methods. for (auto *I : IFacePtr->quals()) - AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, - Selectors, AtArgumentExpression, Results); + AddObjCMethods(I, true, MK_Any, SelIdents, CurContext, Selectors, + AtArgumentExpression, Results); } // Handle messages to "id". else if (ReceiverType->isObjCIdType()) { @@ -6287,8 +6570,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, MEnd = MethodPool.end(); M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.first; - MethList && MethList->getMethod(); - MethList = MethList->getNext()) { + MethList && MethList->getMethod(); MethList = MethList->getNext()) { if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents)) continue; @@ -6305,15 +6587,14 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, } Results.ExitScope(); - // If we're actually at the argument expression (rather than prior to the // selector), we're actually performing code completion for an expression. // Determine whether we have a single, best method. If so, we can // code-complete the expression using the corresponding parameter type as // our preferred type, improving completion results. if (AtArgumentExpression) { - QualType PreferredType = getPreferredArgumentTypeForMessageSend(Results, - SelIdents.size()); + QualType PreferredType = + getPreferredArgumentTypeForMessageSend(Results, SelIdents.size()); if (PreferredType.isNull()) CodeCompleteOrdinaryName(S, PCC_Expression); else @@ -6321,9 +6602,8 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, return; } - HandleCodeCompleteResults(this, CodeCompleter, - Results.getCompletionContext(), - Results.data(),Results.size()); + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), + Results.data(), Results.size()); } void Sema::CodeCompleteObjCForCollection(Scope *S, @@ -6347,8 +6627,8 @@ void Sema::CodeCompleteObjCSelector(Scope *S, // If we have an external source, load the entire class method // pool from the AST file. if (ExternalSource) { - for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); - I != N; ++I) { + for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N; + ++I) { Selector Sel = ExternalSource->GetExternalSelector(I); if (Sel.isNull() || MethodPool.count(Sel)) continue; @@ -6362,7 +6642,7 @@ void Sema::CodeCompleteObjCSelector(Scope *S, CodeCompletionContext::CCC_SelectorName); Results.EnterNewScope(); for (GlobalMethodPool::iterator M = MethodPool.begin(), - MEnd = MethodPool.end(); + MEnd = MethodPool.end(); M != MEnd; ++M) { Selector Sel = M->first; @@ -6372,8 +6652,8 @@ void Sema::CodeCompleteObjCSelector(Scope *S, CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); if (Sel.isUnarySelector()) { - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - Sel.getNameForSlot(0))); + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(0))); Results.AddResult(Builder.TakeString()); continue; } @@ -6382,8 +6662,8 @@ void Sema::CodeCompleteObjCSelector(Scope *S, for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) { if (I == SelIdents.size()) { if (!Accumulator.empty()) { - Builder.AddInformativeChunk(Builder.getAllocator().CopyString( - Accumulator)); + Builder.AddInformativeChunk( + Builder.getAllocator().CopyString(Accumulator)); Accumulator.clear(); } } @@ -6391,7 +6671,7 @@ void Sema::CodeCompleteObjCSelector(Scope *S, Accumulator += Sel.getNameForSlot(I); Accumulator += ':'; } - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( Accumulator)); + Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(Accumulator)); Results.AddResult(Builder.TakeString()); } Results.ExitScope(); @@ -6411,13 +6691,14 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext, // Record any protocols we find. if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D)) if (!OnlyForwardDeclarations || !Proto->hasDefinition()) - Results.AddResult(Result(Proto, Results.getBasePriority(Proto),nullptr), - CurContext, nullptr, false); + Results.AddResult( + Result(Proto, Results.getBasePriority(Proto), nullptr), CurContext, + nullptr, false); } } void Sema::CodeCompleteObjCProtocolReferences( - ArrayRef<IdentifierLocPair> Protocols) { + ArrayRef<IdentifierLocPair> Protocols) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_ObjCProtocolName); @@ -6429,8 +6710,7 @@ void Sema::CodeCompleteObjCProtocolReferences( // already seen. // FIXME: This doesn't work when caching code-completion results. for (const IdentifierLocPair &Pair : Protocols) - if (ObjCProtocolDecl *Protocol = LookupProtocol(Pair.first, - Pair.second)) + if (ObjCProtocolDecl *Protocol = LookupProtocol(Pair.first, Pair.second)) Results.Ignore(Protocol); // Add all protocols. @@ -6476,8 +6756,9 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext, if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D)) if ((!OnlyForwardDeclarations || !Class->hasDefinition()) && (!OnlyUnimplemented || !Class->getImplementation())) - Results.AddResult(Result(Class, Results.getBasePriority(Class),nullptr), - CurContext, nullptr, false); + Results.AddResult( + Result(Class, Results.getBasePriority(Class), nullptr), CurContext, + nullptr, false); } } @@ -6507,8 +6788,8 @@ void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName, Results.EnterNewScope(); // Make sure that we ignore the class we're currently defining. - NamedDecl *CurClass - = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); + NamedDecl *CurClass = + LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); if (CurClass && isa<ObjCInterfaceDecl>(CurClass)) Results.Ignore(CurClass); @@ -6554,9 +6835,10 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, // Ignore any categories we find that have already been implemented by this // interface. llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames; - NamedDecl *CurClass - = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); - if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){ + NamedDecl *CurClass = + LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); + if (ObjCInterfaceDecl *Class = + dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)) { for (const auto *Cat : Class->visible_categories()) CategoryNames.insert(Cat->getIdentifier()); } @@ -6567,9 +6849,9 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, for (const auto *D : TU->decls()) if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D)) if (CategoryNames.insert(Category->getIdentifier()).second) - Results.AddResult(Result(Category, Results.getBasePriority(Category), - nullptr), - CurContext, nullptr, false); + Results.AddResult( + Result(Category, Results.getBasePriority(Category), nullptr), + CurContext, nullptr, false); Results.ExitScope(); HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), @@ -6584,8 +6866,8 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S, // Find the corresponding interface. If we couldn't find the interface, the // program itself is ill-formed. However, we'll try to be helpful still by // providing the list of all of the categories we know about. - NamedDecl *CurClass - = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); + NamedDecl *CurClass = + LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName); ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass); if (!Class) return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc); @@ -6620,15 +6902,13 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S, void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { CodeCompletionContext CCContext(CodeCompletionContext::CCC_Other); ResultBuilder Results(*this, CodeCompleter->getAllocator(), - CodeCompleter->getCodeCompletionTUInfo(), - CCContext); + CodeCompleter->getCodeCompletionTUInfo(), CCContext); // Figure out where this @synthesize lives. - ObjCContainerDecl *Container - = dyn_cast_or_null<ObjCContainerDecl>(CurContext); - if (!Container || - (!isa<ObjCImplementationDecl>(Container) && - !isa<ObjCCategoryImplDecl>(Container))) + ObjCContainerDecl *Container = + dyn_cast_or_null<ObjCContainerDecl>(CurContext); + if (!Container || (!isa<ObjCImplementationDecl>(Container) && + !isa<ObjCCategoryImplDecl>(Container))) return; // Ignore any properties that have already been implemented. @@ -6640,8 +6920,8 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { // Add any properties that we find. AddedPropertiesSet AddedProperties; Results.EnterNewScope(); - if (ObjCImplementationDecl *ClassImpl - = dyn_cast<ObjCImplementationDecl>(Container)) + if (ObjCImplementationDecl *ClassImpl = + dyn_cast<ObjCImplementationDecl>(Container)) AddObjCProperties(CCContext, ClassImpl->getClassInterface(), false, /*AllowNullaryMethods=*/false, CurContext, AddedProperties, Results); @@ -6656,37 +6936,37 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) { Results.data(), Results.size()); } -void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, - IdentifierInfo *PropertyName) { +void Sema::CodeCompleteObjCPropertySynthesizeIvar( + Scope *S, IdentifierInfo *PropertyName) { typedef CodeCompletionResult Result; ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), CodeCompletionContext::CCC_Other); // Figure out where this @synthesize lives. - ObjCContainerDecl *Container - = dyn_cast_or_null<ObjCContainerDecl>(CurContext); - if (!Container || - (!isa<ObjCImplementationDecl>(Container) && - !isa<ObjCCategoryImplDecl>(Container))) + ObjCContainerDecl *Container = + dyn_cast_or_null<ObjCContainerDecl>(CurContext); + if (!Container || (!isa<ObjCImplementationDecl>(Container) && + !isa<ObjCCategoryImplDecl>(Container))) return; // Figure out which interface we're looking into. ObjCInterfaceDecl *Class = nullptr; - if (ObjCImplementationDecl *ClassImpl - = dyn_cast<ObjCImplementationDecl>(Container)) + if (ObjCImplementationDecl *ClassImpl = + dyn_cast<ObjCImplementationDecl>(Container)) Class = ClassImpl->getClassInterface(); else - Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl() - ->getClassInterface(); + Class = cast<ObjCCategoryImplDecl>(Container) + ->getCategoryDecl() + ->getClassInterface(); // Determine the type of the property we're synthesizing. QualType PropertyType = Context.getObjCIdType(); if (Class) { if (ObjCPropertyDecl *Property = Class->FindPropertyDeclaration( PropertyName, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { - PropertyType - = Property->getType().getNonReferenceType().getUnqualifiedType(); + PropertyType = + Property->getType().getNonReferenceType().getUnqualifiedType(); // Give preference to ivars Results.setPreferredType(PropertyType); @@ -6701,7 +6981,7 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, NameWithPrefix += PropertyName->getName(); std::string NameWithSuffix = PropertyName->getName().str(); NameWithSuffix += '_'; - for(; Class; Class = Class->getSuperClass()) { + for (; Class; Class = Class->getSuperClass()) { for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar; Ivar = Ivar->getNextIvar()) { Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr), @@ -6717,8 +6997,8 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, // Reduce the priority of this result by one, to give it a slight // advantage over other results whose names don't match so closely. if (Results.size() && - Results.data()[Results.size() - 1].Kind - == CodeCompletionResult::RK_Declaration && + Results.data()[Results.size() - 1].Kind == + CodeCompletionResult::RK_Declaration && Results.data()[Results.size() - 1].Declaration == Ivar) Results.data()[Results.size() - 1].Priority--; } @@ -6732,14 +7012,14 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, typedef CodeCompletionResult Result; CodeCompletionAllocator &Allocator = Results.getAllocator(); CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo(), - Priority,CXAvailability_Available); + Priority, CXAvailability_Available); PrintingPolicy Policy = getCompletionPrintingPolicy(*this); - Builder.AddResultTypeChunk(GetCompletionTypeString(PropertyType, Context, - Policy, Allocator)); + Builder.AddResultTypeChunk( + GetCompletionTypeString(PropertyType, Context, Policy, Allocator)); Builder.AddTypedTextChunk(Allocator.CopyString(NameWithPrefix)); - Results.AddResult(Result(Builder.TakeString(), Priority, - CXCursor_ObjCIvarDecl)); + Results.AddResult( + Result(Builder.TakeString(), Priority, CXCursor_ObjCIvarDecl)); } Results.ExitScope(); @@ -6750,8 +7030,9 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, // Mapping from selectors to the methods that implement that selector, along // with the "in original class" flag. -typedef llvm::DenseMap< - Selector, llvm::PointerIntPair<ObjCMethodDecl *, 1, bool> > KnownMethodsMap; +typedef llvm::DenseMap<Selector, + llvm::PointerIntPair<ObjCMethodDecl *, 1, bool>> + KnownMethodsMap; /// Find all of the methods that reside in the given container /// (and its superclasses, protocols, etc.) that meet the given @@ -6771,8 +7052,8 @@ static void FindImplementableMethods(ASTContext &Context, IFace = IFace->getDefinition(); Container = IFace; - const ObjCList<ObjCProtocolDecl> &Protocols - = IFace->getReferencedProtocols(); + const ObjCList<ObjCProtocolDecl> &Protocols = + IFace->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) @@ -6788,14 +7069,14 @@ static void FindImplementableMethods(ASTContext &Context, // Visit the superclass. if (IFace->getSuperClass()) FindImplementableMethods(Context, IFace->getSuperClass(), - WantInstanceMethods, ReturnType, - KnownMethods, false); + WantInstanceMethods, ReturnType, KnownMethods, + false); } if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { // Recurse into protocols. - const ObjCList<ObjCProtocolDecl> &Protocols - = Category->getReferencedProtocols(); + const ObjCList<ObjCProtocolDecl> &Protocols = + Category->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) @@ -6817,10 +7098,10 @@ static void FindImplementableMethods(ASTContext &Context, Container = Protocol; // Recurse into protocols. - const ObjCList<ObjCProtocolDecl> &Protocols - = Protocol->getReferencedProtocols(); + const ObjCList<ObjCProtocolDecl> &Protocols = + Protocol->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), - E = Protocols.end(); + E = Protocols.end(); I != E; ++I) FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType, KnownMethods, false); @@ -6843,8 +7124,7 @@ static void FindImplementableMethods(ASTContext &Context, /// Add the parenthesized return or parameter type chunk to a code /// completion string. -static void AddObjCPassingTypeChunk(QualType Type, - unsigned ObjCDeclQuals, +static void AddObjCPassingTypeChunk(QualType Type, unsigned ObjCDeclQuals, ASTContext &Context, const PrintingPolicy &Policy, CodeCompletionBuilder &Builder) { @@ -6852,15 +7132,14 @@ static void AddObjCPassingTypeChunk(QualType Type, std::string Quals = formatObjCParamQualifiers(ObjCDeclQuals, Type); if (!Quals.empty()) Builder.AddTextChunk(Builder.getAllocator().CopyString(Quals)); - Builder.AddTextChunk(GetCompletionTypeString(Type, Context, Policy, - Builder.getAllocator())); + Builder.AddTextChunk( + GetCompletionTypeString(Type, Context, Policy, Builder.getAllocator())); Builder.AddChunk(CodeCompletionString::CK_RightParen); } /// Determine whether the given class is or inherits from a class by /// the given name. -static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, - StringRef Name) { +static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, StringRef Name) { if (!Class) return false; @@ -6874,8 +7153,7 @@ static bool InheritsFromClassNamed(ObjCInterfaceDecl *Class, /// Key-Value Observing (KVO). static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, bool IsInstanceMethod, - QualType ReturnType, - ASTContext &Context, + QualType ReturnType, ASTContext &Context, VisitedSelectorSet &KnownSelectors, ResultBuilder &Results) { IdentifierInfo *PropName = Property->getIdentifier(); @@ -6900,7 +7178,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, const char *CopiedKey; KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key) - : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {} + : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {} operator const char *() { if (CopiedKey) @@ -6915,19 +7193,19 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, if (!UpperKey.empty()) UpperKey[0] = toUppercase(UpperKey[0]); - bool ReturnTypeMatchesProperty = ReturnType.isNull() || - Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(), - Property->getType()); - bool ReturnTypeMatchesVoid - = ReturnType.isNull() || ReturnType->isVoidType(); + bool ReturnTypeMatchesProperty = + ReturnType.isNull() || + Context.hasSameUnqualifiedType(ReturnType.getNonReferenceType(), + Property->getType()); + bool ReturnTypeMatchesVoid = ReturnType.isNull() || ReturnType->isVoidType(); // Add the normal accessor -(type)key. if (IsInstanceMethod && KnownSelectors.insert(Selectors.getNullarySelector(PropName)).second && ReturnTypeMatchesProperty && !Property->getGetterMethodDecl()) { if (ReturnType.isNull()) - AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, - Context, Policy, Builder); + AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy, + Builder); Builder.AddTypedTextChunk(Key); Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, @@ -6939,9 +7217,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, if (IsInstanceMethod && ((!ReturnType.isNull() && (ReturnType->isIntegerType() || ReturnType->isBooleanType())) || - (ReturnType.isNull() && - (Property->getType()->isIntegerType() || - Property->getType()->isBooleanType())))) { + (ReturnType.isNull() && (Property->getType()->isIntegerType() || + Property->getType()->isBooleanType())))) { std::string SelectorName = (Twine("is") + UpperKey).str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) @@ -6952,8 +7229,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddChunk(CodeCompletionString::CK_RightParen); } - Builder.AddTypedTextChunk( - Allocator.CopyString(SelectorId->getName())); + Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName())); Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, CXCursor_ObjCInstanceMethodDecl)); } @@ -6971,11 +7247,10 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddChunk(CodeCompletionString::CK_RightParen); } - Builder.AddTypedTextChunk( - Allocator.CopyString(SelectorId->getName())); + Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName())); Builder.AddTypedTextChunk(":"); - AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, - Context, Policy, Builder); + AddObjCPassingTypeChunk(Property->getType(), /*Quals=*/0, Context, Policy, + Builder); Builder.AddTextChunk(Key); Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, CXCursor_ObjCInstanceMethodDecl)); @@ -6987,8 +7262,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, unsigned IndexedSetterPriority = CCP_CodePattern; unsigned UnorderedGetterPriority = CCP_CodePattern; unsigned UnorderedSetterPriority = CCP_CodePattern; - if (const ObjCObjectPointerType *ObjCPointer - = Property->getType()->getAs<ObjCObjectPointerType>()) { + if (const auto *ObjCPointer = + Property->getType()->getAs<ObjCObjectPointerType>()) { if (ObjCInterfaceDecl *IFace = ObjCPointer->getInterfaceDecl()) { // If this interface type is not provably derived from a known // collection, penalize the corresponding completions. @@ -7024,12 +7299,11 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddChunk(CodeCompletionString::CK_RightParen); } - Builder.AddTypedTextChunk( - Allocator.CopyString(SelectorId->getName())); - Results.AddResult(Result(Builder.TakeString(), - std::min(IndexedGetterPriority, - UnorderedGetterPriority), - CXCursor_ObjCInstanceMethodDecl)); + Builder.AddTypedTextChunk(Allocator.CopyString(SelectorId->getName())); + Results.AddResult( + Result(Builder.TakeString(), + std::min(IndexedGetterPriority, UnorderedGetterPriority), + CXCursor_ObjCInstanceMethodDecl)); } } @@ -7037,8 +7311,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // Add -(id)objectInKeyAtIndex:(NSUInteger)index if (IsInstanceMethod && (ReturnType.isNull() || ReturnType->isObjCObjectPointerType())) { - std::string SelectorName - = (Twine("objectIn") + UpperKey + "AtIndex").str(); + std::string SelectorName = (Twine("objectIn") + UpperKey + "AtIndex").str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) { if (ReturnType.isNull()) { @@ -7062,10 +7335,10 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, (ReturnType.isNull() || (ReturnType->isObjCObjectPointerType() && ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && - ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() - ->getName() == "NSArray"))) { - std::string SelectorName - = (Twine(Property->getName()) + "AtIndexes").str(); + ReturnType->getAs<ObjCObjectPointerType>() + ->getInterfaceDecl() + ->getName() == "NSArray"))) { + std::string SelectorName = (Twine(Property->getName()) + "AtIndexes").str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) { if (ReturnType.isNull()) { @@ -7087,10 +7360,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // Add -(void)getKey:(type **)buffer range:(NSRange)inRange if (IsInstanceMethod && ReturnTypeMatchesVoid) { std::string SelectorName = (Twine("get") + UpperKey).str(); - IdentifierInfo *SelectorIds[2] = { - &Context.Idents.get(SelectorName), - &Context.Idents.get("range") - }; + IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName), + &Context.Idents.get("range")}; if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) { if (ReturnType.isNull()) { @@ -7121,10 +7392,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // - (void)insertObject:(type *)object inKeyAtIndex:(NSUInteger)index if (IsInstanceMethod && ReturnTypeMatchesVoid) { std::string SelectorName = (Twine("in") + UpperKey + "AtIndex").str(); - IdentifierInfo *SelectorIds[2] = { - &Context.Idents.get("insertObject"), - &Context.Idents.get(SelectorName) - }; + IdentifierInfo *SelectorIds[2] = {&Context.Idents.get("insertObject"), + &Context.Idents.get(SelectorName)}; if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) { if (ReturnType.isNull()) { @@ -7153,10 +7422,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // - (void)insertKey:(NSArray *)array atIndexes:(NSIndexSet *)indexes if (IsInstanceMethod && ReturnTypeMatchesVoid) { std::string SelectorName = (Twine("insert") + UpperKey).str(); - IdentifierInfo *SelectorIds[2] = { - &Context.Idents.get(SelectorName), - &Context.Idents.get("atIndexes") - }; + IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName), + &Context.Idents.get("atIndexes")}; if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) { if (ReturnType.isNull()) { @@ -7183,8 +7450,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // -(void)removeObjectFromKeyAtIndex:(NSUInteger)index if (IsInstanceMethod && ReturnTypeMatchesVoid) { - std::string SelectorName - = (Twine("removeObjectFrom") + UpperKey + "AtIndex").str(); + std::string SelectorName = + (Twine("removeObjectFrom") + UpperKey + "AtIndex").str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) { if (ReturnType.isNull()) { @@ -7205,8 +7472,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // -(void)removeKeyAtIndexes:(NSIndexSet *)indexes if (IsInstanceMethod && ReturnTypeMatchesVoid) { - std::string SelectorName - = (Twine("remove") + UpperKey + "AtIndexes").str(); + std::string SelectorName = (Twine("remove") + UpperKey + "AtIndexes").str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) { if (ReturnType.isNull()) { @@ -7227,12 +7493,10 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // - (void)replaceObjectInKeyAtIndex:(NSUInteger)index withObject:(id)object if (IsInstanceMethod && ReturnTypeMatchesVoid) { - std::string SelectorName - = (Twine("replaceObjectIn") + UpperKey + "AtIndex").str(); - IdentifierInfo *SelectorIds[2] = { - &Context.Idents.get(SelectorName), - &Context.Idents.get("withObject") - }; + std::string SelectorName = + (Twine("replaceObjectIn") + UpperKey + "AtIndex").str(); + IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName), + &Context.Idents.get("withObject")}; if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) { if (ReturnType.isNull()) { @@ -7259,13 +7523,11 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // - (void)replaceKeyAtIndexes:(NSIndexSet *)indexes withKey:(NSArray *)array if (IsInstanceMethod && ReturnTypeMatchesVoid) { - std::string SelectorName1 - = (Twine("replace") + UpperKey + "AtIndexes").str(); + std::string SelectorName1 = + (Twine("replace") + UpperKey + "AtIndexes").str(); std::string SelectorName2 = (Twine("with") + UpperKey).str(); - IdentifierInfo *SelectorIds[2] = { - &Context.Idents.get(SelectorName1), - &Context.Idents.get(SelectorName2) - }; + IdentifierInfo *SelectorIds[2] = {&Context.Idents.get(SelectorName1), + &Context.Idents.get(SelectorName2)}; if (KnownSelectors.insert(Selectors.getSelector(2, SelectorIds)).second) { if (ReturnType.isNull()) { @@ -7296,8 +7558,9 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, (ReturnType.isNull() || (ReturnType->isObjCObjectPointerType() && ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && - ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() - ->getName() == "NSEnumerator"))) { + ReturnType->getAs<ObjCObjectPointerType>() + ->getInterfaceDecl() + ->getName() == "NSEnumerator"))) { std::string SelectorName = (Twine("enumeratorOf") + UpperKey).str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) @@ -7310,7 +7573,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); Results.AddResult(Result(Builder.TakeString(), UnorderedGetterPriority, - CXCursor_ObjCInstanceMethodDecl)); + CXCursor_ObjCInstanceMethodDecl)); } } @@ -7333,9 +7596,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddPlaceholderChunk("object-type"); Builder.AddTextChunk(" *"); } else { - Builder.AddTextChunk(GetCompletionTypeString(ReturnType, Context, - Policy, - Builder.getAllocator())); + Builder.AddTextChunk(GetCompletionTypeString( + ReturnType, Context, Policy, Builder.getAllocator())); } Builder.AddChunk(CodeCompletionString::CK_RightParen); Builder.AddTextChunk("object"); @@ -7347,8 +7609,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // Mutable unordered accessors // - (void)addKeyObject:(type *)object if (IsInstanceMethod && ReturnTypeMatchesVoid) { - std::string SelectorName - = (Twine("add") + UpperKey + Twine("Object")).str(); + std::string SelectorName = + (Twine("add") + UpperKey + Twine("Object")).str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) { if (ReturnType.isNull()) { @@ -7391,8 +7653,8 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, // - (void)removeKeyObject:(type *)object if (IsInstanceMethod && ReturnTypeMatchesVoid) { - std::string SelectorName - = (Twine("remove") + UpperKey + Twine("Object")).str(); + std::string SelectorName = + (Twine("remove") + UpperKey + Twine("Object")).str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getUnarySelector(SelectorId)).second) { if (ReturnType.isNull()) { @@ -7460,10 +7722,11 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, (ReturnType.isNull() || (ReturnType->isObjCObjectPointerType() && ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() && - ReturnType->getAs<ObjCObjectPointerType>()->getInterfaceDecl() - ->getName() == "NSSet"))) { - std::string SelectorName - = (Twine("keyPathsForValuesAffecting") + UpperKey).str(); + ReturnType->getAs<ObjCObjectPointerType>() + ->getInterfaceDecl() + ->getName() == "NSSet"))) { + std::string SelectorName = + (Twine("keyPathsForValuesAffecting") + UpperKey).str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) .second) { @@ -7475,17 +7738,16 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, - CXCursor_ObjCClassMethodDecl)); + CXCursor_ObjCClassMethodDecl)); } } // + (BOOL)automaticallyNotifiesObserversForKey if (!IsInstanceMethod && - (ReturnType.isNull() || - ReturnType->isIntegerType() || + (ReturnType.isNull() || ReturnType->isIntegerType() || ReturnType->isBooleanType())) { - std::string SelectorName - = (Twine("automaticallyNotifiesObserversOf") + UpperKey).str(); + std::string SelectorName = + (Twine("automaticallyNotifiesObserversOf") + UpperKey).str(); IdentifierInfo *SelectorId = &Context.Idents.get(SelectorName); if (KnownSelectors.insert(Selectors.getNullarySelector(SelectorId)) .second) { @@ -7497,7 +7759,7 @@ static void AddObjCKeyValueCompletions(ObjCPropertyDecl *Property, Builder.AddTypedTextChunk(Allocator.CopyString(SelectorName)); Results.AddResult(Result(Builder.TakeString(), CCP_CodePattern, - CXCursor_ObjCClassMethodDecl)); + CXCursor_ObjCClassMethodDecl)); } } } @@ -7509,8 +7771,8 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, QualType ReturnType = GetTypeFromParser(ReturnTy); Decl *IDecl = nullptr; if (CurContext->isObjCContainer()) { - ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); - IDecl = OCD; + ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext); + IDecl = OCD; } // Determine where we should start searching for methods. ObjCContainerDecl *SearchDecl = nullptr; @@ -7519,8 +7781,8 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) { SearchDecl = Impl->getClassInterface(); IsInImplementation = true; - } else if (ObjCCategoryImplDecl *CatImpl - = dyn_cast<ObjCCategoryImplDecl>(D)) { + } else if (ObjCCategoryImplDecl *CatImpl = + dyn_cast<ObjCCategoryImplDecl>(D)) { SearchDecl = CatImpl->getCategoryDecl(); IsInImplementation = true; } else @@ -7534,15 +7796,14 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, if (!SearchDecl) { HandleCodeCompleteResults(this, CodeCompleter, - CodeCompletionContext::CCC_Other, - nullptr, 0); + CodeCompletionContext::CCC_Other, nullptr, 0); return; } // Find all of the methods that we could declare/implement here. KnownMethodsMap KnownMethods; - FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, - ReturnType, KnownMethods); + FindImplementableMethods(Context, SearchDecl, IsInstanceMethod, ReturnType, + KnownMethods); // Add declarations or definitions for each of the known methods. typedef CodeCompletionResult Result; @@ -7552,7 +7813,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, Results.EnterNewScope(); PrintingPolicy Policy = getCompletionPrintingPolicy(*this); for (KnownMethodsMap::iterator M = KnownMethods.begin(), - MEnd = KnownMethods.end(); + MEnd = KnownMethods.end(); M != MEnd; ++M) { ObjCMethodDecl *Method = M->second.getPointer(); CodeCompletionBuilder Builder(Results.getAllocator(), @@ -7569,21 +7830,20 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, if (ReturnType.isNull()) { QualType ResTy = Method->getSendResultType().stripObjCKindOfType(Context); AttributedType::stripOuterNullability(ResTy); - AddObjCPassingTypeChunk(ResTy, - Method->getObjCDeclQualifier(), Context, Policy, - Builder); + AddObjCPassingTypeChunk(ResTy, Method->getObjCDeclQualifier(), Context, + Policy, Builder); } Selector Sel = Method->getSelector(); // Add the first part of the selector to the pattern. - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - Sel.getNameForSlot(0))); + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(Sel.getNameForSlot(0))); // Add parameters to the pattern. unsigned I = 0; for (ObjCMethodDecl::param_iterator P = Method->param_begin(), - PEnd = Method->param_end(); + PEnd = Method->param_end(); P != PEnd; (void)++P, ++I) { // Add the part of the selector name. if (I == 0) @@ -7591,7 +7851,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, else if (I < Sel.getNumArgs()) { Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddTypedTextChunk( - Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); + Builder.getAllocator().CopyString(Sel.getNameForSlot(I) + ":")); } else break; @@ -7601,16 +7861,14 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, ParamType = (*P)->getType(); else ParamType = (*P)->getOriginalType(); - ParamType = ParamType.substObjCTypeArgs(Context, {}, - ObjCSubstitutionContext::Parameter); + ParamType = ParamType.substObjCTypeArgs( + Context, {}, ObjCSubstitutionContext::Parameter); AttributedType::stripOuterNullability(ParamType); - AddObjCPassingTypeChunk(ParamType, - (*P)->getObjCDeclQualifier(), - Context, Policy, - Builder); + AddObjCPassingTypeChunk(ParamType, (*P)->getObjCDeclQualifier(), Context, + Policy, Builder); if (IdentifierInfo *Id = (*P)->getIdentifier()) - Builder.AddTextChunk(Builder.getAllocator().CopyString( Id->getName())); + Builder.AddTextChunk(Builder.getAllocator().CopyString(Id->getName())); } if (Method->isVariadic()) { @@ -7638,25 +7896,24 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, } unsigned Priority = CCP_CodePattern; + auto R = Result(Builder.TakeString(), Method, Priority); if (!M->second.getInt()) - Priority += CCD_InBaseClass; - - Results.AddResult(Result(Builder.TakeString(), Method, Priority)); + setInBaseClass(R); + Results.AddResult(std::move(R)); } // Add Key-Value-Coding and Key-Value-Observing accessor methods for all of // the properties in this class and its categories. - if (Context.getLangOpts().ObjC2) { + if (Context.getLangOpts().ObjC) { SmallVector<ObjCContainerDecl *, 4> Containers; Containers.push_back(SearchDecl); VisitedSelectorSet KnownSelectors; for (KnownMethodsMap::iterator M = KnownMethods.begin(), - MEnd = KnownMethods.end(); + MEnd = KnownMethods.end(); M != MEnd; ++M) KnownSelectors.insert(M->first); - ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(SearchDecl); if (!IFace) if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl)) @@ -7680,16 +7937,14 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod, Results.data(), Results.size()); } -void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, - bool IsInstanceMethod, - bool AtParameterName, - ParsedType ReturnTy, - ArrayRef<IdentifierInfo *> SelIdents) { +void Sema::CodeCompleteObjCMethodDeclSelector( + Scope *S, bool IsInstanceMethod, bool AtParameterName, ParsedType ReturnTy, + ArrayRef<IdentifierInfo *> SelIdents) { // If we have an external source, load the entire class method // pool from the AST file. if (ExternalSource) { - for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); - I != N; ++I) { + for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors(); I != N; + ++I) { Selector Sel = ExternalSource->GetExternalSelector(I); if (Sel.isNull() || MethodPool.count(Sel)) continue; @@ -7711,10 +7966,9 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, for (GlobalMethodPool::iterator M = MethodPool.begin(), MEnd = MethodPool.end(); M != MEnd; ++M) { - for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first : - &M->second.second; - MethList && MethList->getMethod(); - MethList = MethList->getNext()) { + for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first + : &M->second.second; + MethList && MethList->getMethod(); MethList = MethList->getNext()) { if (!isAcceptableObjCMethod(MethList->getMethod(), MK_Any, SelIdents)) continue; @@ -7729,7 +7983,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - Param->getIdentifier()->getName())); + Param->getIdentifier()->getName())); Results.AddResult(Builder.TakeString()); } } @@ -7875,7 +8129,7 @@ void Sema::CodeCompletePreprocessorDirective(bool InConditional) { Builder.AddPlaceholderChunk("arguments"); Results.AddResult(Builder.TakeString()); - if (getLangOpts().ObjC1) { + if (getLangOpts().ObjC) { // #import "header" Builder.AddTypedTextChunk("import"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); @@ -7927,29 +8181,27 @@ void Sema::CodeCompletePreprocessorDirective(bool InConditional) { } void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) { - CodeCompleteOrdinaryName(S, - S->getFnParent()? Sema::PCC_RecoveryInFunction - : Sema::PCC_Namespace); + CodeCompleteOrdinaryName(S, S->getFnParent() ? Sema::PCC_RecoveryInFunction + : Sema::PCC_Namespace); } void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) { ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), - IsDefinition? CodeCompletionContext::CCC_MacroName - : CodeCompletionContext::CCC_MacroNameUse); + IsDefinition ? CodeCompletionContext::CCC_MacroName + : CodeCompletionContext::CCC_MacroNameUse); if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) { // Add just the names of macros, not their arguments. CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); Results.EnterNewScope(); for (Preprocessor::macro_iterator M = PP.macro_begin(), - MEnd = PP.macro_end(); + MEnd = PP.macro_end(); M != MEnd; ++M) { - Builder.AddTypedTextChunk(Builder.getAllocator().CopyString( - M->first->getName())); - Results.AddResult(CodeCompletionResult(Builder.TakeString(), - CCP_CodePattern, - CXCursor_MacroDefinition)); + Builder.AddTypedTextChunk( + Builder.getAllocator().CopyString(M->first->getName())); + Results.AddResult(CodeCompletionResult( + Builder.TakeString(), CCP_CodePattern, CXCursor_MacroDefinition)); } Results.ExitScope(); } else if (IsDefinition) { @@ -7970,7 +8222,7 @@ void Sema::CodeCompletePreprocessorExpression() { CodeCompleter ? CodeCompleter->loadExternal() : false, true); - // defined (<macro>) + // defined (<macro>) Results.EnterNewScope(); CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); @@ -8041,7 +8293,7 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) { std::error_code EC; unsigned Count = 0; for (auto It = FS->dir_begin(Dir, EC); - !EC && It != vfs::directory_iterator(); It.increment(EC)) { + !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) { if (++Count == 2500) // If we happen to hit a huge directory, break; // bail out early so we're not too slow. StringRef Filename = llvm::sys::path::filename(It->path()); @@ -8070,7 +8322,6 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) { // Helper: adds results relative to IncludeDir, if possible. auto AddFilesFromDirLookup = [&](const DirectoryLookup &IncludeDir, bool IsSystem) { - llvm::SmallString<128> Dir; switch (IncludeDir.getLookupType()) { case DirectoryLookup::LT_HeaderMap: // header maps are not (currently) enumerable. @@ -8098,7 +8349,7 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) { AddFilesFromDirLookup(D, false); } for (const auto &D : make_range(S.angled_dir_begin(), S.angled_dir_end())) - AddFilesFromDirLookup(D, true); + AddFilesFromDirLookup(D, false); for (const auto &D : make_range(S.system_dir_begin(), S.system_dir_end())) AddFilesFromDirLookup(D, true); @@ -8108,8 +8359,8 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) { void Sema::CodeCompleteNaturalLanguage() { HandleCodeCompleteResults(this, CodeCompleter, - CodeCompletionContext::CCC_NaturalLanguage, - nullptr, 0); + CodeCompletionContext::CCC_NaturalLanguage, nullptr, + 0); } void Sema::CodeCompleteAvailabilityPlatformName() { @@ -8128,9 +8379,9 @@ void Sema::CodeCompleteAvailabilityPlatformName() { Results.data(), Results.size()); } -void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo, - SmallVectorImpl<CodeCompletionResult> &Results) { +void Sema::GatherGlobalCodeCompletions( + CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, + SmallVectorImpl<CodeCompletionResult> &Results) { ResultBuilder Builder(*this, Allocator, CCTUInfo, CodeCompletionContext::CCC_Recovery); if (!CodeCompleter || CodeCompleter->includeGlobals()) { @@ -8147,6 +8398,6 @@ void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator, true); Results.clear(); - Results.insert(Results.end(), - Builder.data(), Builder.data() + Builder.size()); + Results.insert(Results.end(), Builder.data(), + Builder.data() + Builder.size()); } diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp index 826cd48a8a..cc79238470 100644 --- a/lib/Sema/SemaCoroutine.cpp +++ b/lib/Sema/SemaCoroutine.cpp @@ -565,8 +565,8 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { // Create an initialization sequence for the promise type using the // constructor arguments, wrapped in a parenthesized list expression. - Expr *PLE = new (Context) ParenListExpr(Context, FD->getLocation(), - CtorArgExprs, FD->getLocation()); + Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(), + CtorArgExprs, FD->getLocation()); InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); InitializationKind Kind = InitializationKind::CreateForInit( VD->getLocation(), /*DirectInit=*/true, PLE); @@ -841,6 +841,19 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E, E = R.get(); } + // Move the return value if we can + if (E) { + auto NRVOCandidate = this->getCopyElisionCandidate(E->getType(), E, CES_AsIfByStdMove); + if (NRVOCandidate) { + InitializedEntity Entity = + InitializedEntity::InitializeResult(Loc, E->getType(), NRVOCandidate); + ExprResult MoveResult = this->PerformMoveOrCopyInitialization( + Entity, NRVOCandidate, E->getType(), E); + if (MoveResult.get()) + E = MoveResult.get(); + } + } + // FIXME: If the operand is a reference to a variable that's about to go out // of scope, we should treat the operand as an xvalue for this overload // resolution. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d02b971230..6dab332f4f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2111,7 +2111,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New, // Allow multiple definitions for ObjC built-in typedefs. // FIXME: Verify the underlying types are equivalent! - if (getLangOpts().ObjC1) { + if (getLangOpts().ObjC) { const IdentifierInfo *TypeID = New->getIdentifier(); switch (TypeID->getLength()) { default: break; @@ -3192,7 +3192,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, if (RequiresAdjustment) { const FunctionType *AdjustedType = New->getType()->getAs<FunctionType>(); AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo); - New->setType(QualType(AdjustedType, 0)); + + QualType AdjustedQT = QualType(AdjustedType, 0); + LangAS AS = Old->getType().getAddressSpace(); + AdjustedQT = Context.getAddrSpaceQualType(AdjustedQT, AS); + + New->setType(AdjustedQT); NewQType = Context.getCanonicalType(New->getType()); NewType = cast<FunctionType>(NewQType); } @@ -5575,11 +5580,13 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, if (VLATy->getElementType()->isVariablyModifiedType()) return QualType(); - llvm::APSInt Res; + Expr::EvalResult Result; if (!VLATy->getSizeExpr() || - !VLATy->getSizeExpr()->EvaluateAsInt(Res, Context)) + !VLATy->getSizeExpr()->EvaluateAsInt(Result, Context)) return QualType(); + llvm::APSInt Res = Result.Val.getInt(); + // Check whether the array size is negative. if (Res.isSigned() && Res.isNegative()) { SizeIsNegative = true; @@ -7352,19 +7359,23 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { return; } } - // OpenCL v1.2 s6.5 - All program scope variables must be declared in the + // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the // __constant address space. - // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static + // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static // variables inside a function can also be declared in the global // address space. + // OpenCL C++ v1.0 s2.5 inherits rule from OpenCL C v2.0 and allows local + // address space additionally. + // FIXME: Add local AS for OpenCL C++. if (NewVD->isFileVarDecl() || NewVD->isStaticLocal() || NewVD->hasExternalStorage()) { if (!T->isSamplerT() && !(T.getAddressSpace() == LangAS::opencl_constant || (T.getAddressSpace() == LangAS::opencl_global && - getLangOpts().OpenCLVersion == 200))) { + (getLangOpts().OpenCLVersion == 200 || + getLangOpts().OpenCLCPlusPlus)))) { int Scope = NewVD->isStaticLocal() | NewVD->hasExternalStorage() << 1; - if (getLangOpts().OpenCLVersion == 200) + if (getLangOpts().OpenCLVersion == 200 || getLangOpts().OpenCLCPlusPlus) Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) << Scope << "global or constant"; else @@ -8095,7 +8106,7 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) { const Type *UnderlyingTy = PT->getPointeeOrArrayElementType(); // Call ourself to check an underlying type of an array. Since the // getPointeeOrArrayElementType returns an innermost type which is not an - // array, this recusive call only happens once. + // array, this recursive call only happens once. return getOpenCLKernelParameterType(S, QualType(UnderlyingTy, 0)); } @@ -9362,20 +9373,6 @@ bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) { PrevVD->getType()); } -namespace MultiVersioning { -enum Type { None, Target, CPUSpecific, CPUDispatch}; -} // MultiVersionType - -static MultiVersioning::Type -getMultiVersionType(const FunctionDecl *FD) { - if (FD->hasAttr<TargetAttr>()) - return MultiVersioning::Target; - if (FD->hasAttr<CPUDispatchAttr>()) - return MultiVersioning::CPUDispatch; - if (FD->hasAttr<CPUSpecificAttr>()) - return MultiVersioning::CPUSpecific; - return MultiVersioning::None; -} /// Check the target attribute of the function for MultiVersion /// validity. /// @@ -9412,10 +9409,31 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) { return false; } +static bool HasNonMultiVersionAttributes(const FunctionDecl *FD, + MultiVersionKind MVType) { + for (const Attr *A : FD->attrs()) { + switch (A->getKind()) { + case attr::CPUDispatch: + case attr::CPUSpecific: + if (MVType != MultiVersionKind::CPUDispatch && + MVType != MultiVersionKind::CPUSpecific) + return true; + break; + case attr::Target: + if (MVType != MultiVersionKind::Target) + return true; + break; + default: + return true; + } + } + return false; +} + static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, const FunctionDecl *NewFD, bool CausesMV, - MultiVersioning::Type MVType) { + MultiVersionKind MVType) { enum DoesntSupport { FuncTemplates = 0, VirtFuncs = 1, @@ -9436,8 +9454,8 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, }; bool IsCPUSpecificCPUDispatchMVType = - MVType == MultiVersioning::CPUDispatch || - MVType == MultiVersioning::CPUSpecific; + MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific; if (OldFD && !OldFD->getType()->getAs<FunctionProtoType>()) { S.Diag(OldFD->getLocation(), diag::err_multiversion_noproto); @@ -9457,15 +9475,14 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, // For now, disallow all other attributes. These should be opt-in, but // an analysis of all of them is a future FIXME. - if (CausesMV && OldFD && - std::distance(OldFD->attr_begin(), OldFD->attr_end()) != 1) { + if (CausesMV && OldFD && HasNonMultiVersionAttributes(OldFD, MVType)) { S.Diag(OldFD->getLocation(), diag::err_multiversion_no_other_attrs) << IsCPUSpecificCPUDispatchMVType; S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); return true; } - if (std::distance(NewFD->attr_begin(), NewFD->attr_end()) != 1) + if (HasNonMultiVersionAttributes(NewFD, MVType)) return S.Diag(NewFD->getLocation(), diag::err_multiversion_no_other_attrs) << IsCPUSpecificCPUDispatchMVType; @@ -9498,8 +9515,8 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) << IsCPUSpecificCPUDispatchMVType << DefaultedFuncs; - if (NewFD->isConstexpr() && (MVType == MultiVersioning::CPUDispatch || - MVType == MultiVersioning::CPUSpecific)) + if (NewFD->isConstexpr() && (MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific)) return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) << IsCPUSpecificCPUDispatchMVType << ConstexprFuncs; @@ -9563,19 +9580,19 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, /// /// Returns true if there was an error, false otherwise. static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD, - MultiVersioning::Type MVType, + MultiVersionKind MVType, const TargetAttr *TA, const CPUDispatchAttr *CPUDisp, const CPUSpecificAttr *CPUSpec) { - assert(MVType != MultiVersioning::None && + assert(MVType != MultiVersionKind::None && "Function lacks multiversion attribute"); // Target only causes MV if it is default, otherwise this is a normal // function. - if (MVType == MultiVersioning::Target && !TA->isDefaultVersion()) + if (MVType == MultiVersionKind::Target && !TA->isDefaultVersion()) return false; - if (MVType == MultiVersioning::Target && CheckMultiVersionValue(S, FD)) { + if (MVType == MultiVersionKind::Target && CheckMultiVersionValue(S, FD)) { FD->setInvalidDecl(); return true; } @@ -9589,6 +9606,15 @@ static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD, return false; } +static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) { + for (const Decl *D = FD->getPreviousDecl(); D; D = D->getPreviousDecl()) { + if (D->getAsFunction()->getMultiVersionKind() != MultiVersionKind::None) + return true; + } + + return false; +} + static bool CheckTargetCausesMultiVersioning( Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, const TargetAttr *NewTA, bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, @@ -9596,11 +9622,12 @@ static bool CheckTargetCausesMultiVersioning( const auto *OldTA = OldFD->getAttr<TargetAttr>(); TargetAttr::ParsedTargetAttr NewParsed = NewTA->parse(); // Sort order doesn't matter, it just needs to be consistent. - llvm::sort(NewParsed.Features.begin(), NewParsed.Features.end()); + llvm::sort(NewParsed.Features); // If the old decl is NOT MultiVersioned yet, and we don't cause that // to change, this is a simple redeclaration. - if (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr()) + if (!NewTA->isDefaultVersion() && + (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr())) return false; // Otherwise, this decl causes MultiVersioning. @@ -9612,7 +9639,7 @@ static bool CheckTargetCausesMultiVersioning( } if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, true, - MultiVersioning::Target)) { + MultiVersionKind::Target)) { NewFD->setInvalidDecl(); return true; } @@ -9622,6 +9649,15 @@ static bool CheckTargetCausesMultiVersioning( return true; } + // If this is 'default', permit the forward declaration. + if (!OldFD->isMultiVersion() && !OldTA && NewTA->isDefaultVersion()) { + Redeclaration = true; + OldDecl = OldFD; + OldFD->setIsMultiVersion(); + NewFD->setIsMultiVersion(); + return false; + } + if (CheckMultiVersionValue(S, OldFD)) { S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); NewFD->setInvalidDecl(); @@ -9640,7 +9676,10 @@ static bool CheckTargetCausesMultiVersioning( for (const auto *FD : OldFD->redecls()) { const auto *CurTA = FD->getAttr<TargetAttr>(); - if (!CurTA || CurTA->isInherited()) { + // We allow forward declarations before ANY multiversioning attributes, but + // nothing after the fact. + if (PreviousDeclsHaveMultiVersionAttribute(FD) && + (!CurTA || CurTA->isInherited())) { S.Diag(FD->getLocation(), diag::err_multiversion_required_in_redecl) << 0; S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); @@ -9662,17 +9701,17 @@ static bool CheckTargetCausesMultiVersioning( /// multiversioned declaration collection. static bool CheckMultiVersionAdditionalDecl( Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, - MultiVersioning::Type NewMVType, const TargetAttr *NewTA, + MultiVersionKind NewMVType, const TargetAttr *NewTA, const CPUDispatchAttr *NewCPUDisp, const CPUSpecificAttr *NewCPUSpec, bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, LookupResult &Previous) { - MultiVersioning::Type OldMVType = getMultiVersionType(OldFD); + MultiVersionKind OldMVType = OldFD->getMultiVersionKind(); // Disallow mixing of multiversioning types. - if ((OldMVType == MultiVersioning::Target && - NewMVType != MultiVersioning::Target) || - (NewMVType == MultiVersioning::Target && - OldMVType != MultiVersioning::Target)) { + if ((OldMVType == MultiVersionKind::Target && + NewMVType != MultiVersionKind::Target) || + (NewMVType == MultiVersionKind::Target && + OldMVType != MultiVersionKind::Target)) { S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed); S.Diag(OldFD->getLocation(), diag::note_previous_declaration); NewFD->setInvalidDecl(); @@ -9682,7 +9721,7 @@ static bool CheckMultiVersionAdditionalDecl( TargetAttr::ParsedTargetAttr NewParsed; if (NewTA) { NewParsed = NewTA->parse(); - llvm::sort(NewParsed.Features.begin(), NewParsed.Features.end()); + llvm::sort(NewParsed.Features); } bool UseMemberUsingDeclRules = @@ -9697,7 +9736,7 @@ static bool CheckMultiVersionAdditionalDecl( if (S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules)) continue; - if (NewMVType == MultiVersioning::Target) { + if (NewMVType == MultiVersionKind::Target) { const auto *CurTA = CurFD->getAttr<TargetAttr>(); if (CurTA->getFeaturesStr() == NewTA->getFeaturesStr()) { NewFD->setIsMultiVersion(); @@ -9720,7 +9759,7 @@ static bool CheckMultiVersionAdditionalDecl( // Handle CPUDispatch/CPUSpecific versions. // Only 1 CPUDispatch function is allowed, this will make it go through // the redeclaration errors. - if (NewMVType == MultiVersioning::CPUDispatch && + if (NewMVType == MultiVersionKind::CPUDispatch && CurFD->hasAttr<CPUDispatchAttr>()) { if (CurCPUDisp->cpus_size() == NewCPUDisp->cpus_size() && std::equal( @@ -9741,7 +9780,7 @@ static bool CheckMultiVersionAdditionalDecl( NewFD->setInvalidDecl(); return true; } - if (NewMVType == MultiVersioning::CPUSpecific && CurCPUSpec) { + if (NewMVType == MultiVersionKind::CPUSpecific && CurCPUSpec) { if (CurCPUSpec->cpus_size() == NewCPUSpec->cpus_size() && std::equal( @@ -9777,7 +9816,7 @@ static bool CheckMultiVersionAdditionalDecl( // Else, this is simply a non-redecl case. Checking the 'value' is only // necessary in the Target case, since The CPUSpecific/Dispatch cases are // handled in the attribute adding step. - if (NewMVType == MultiVersioning::Target && + if (NewMVType == MultiVersionKind::Target && CheckMultiVersionValue(S, NewFD)) { NewFD->setInvalidDecl(); return true; @@ -9788,6 +9827,15 @@ static bool CheckMultiVersionAdditionalDecl( return true; } + // Permit forward declarations in the case where these two are compatible. + if (!OldFD->isMultiVersion()) { + OldFD->setIsMultiVersion(); + NewFD->setIsMultiVersion(); + Redeclaration = true; + OldDecl = OldFD; + return false; + } + NewFD->setIsMultiVersion(); Redeclaration = false; MergeTypeWithPrevious = false; @@ -9819,14 +9867,14 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, return true; } - MultiVersioning::Type MVType = getMultiVersionType(NewFD); + MultiVersionKind MVType = NewFD->getMultiVersionKind(); // Main isn't allowed to become a multiversion function, however it IS // permitted to have 'main' be marked with the 'target' optimization hint. if (NewFD->isMain()) { - if ((MVType == MultiVersioning::Target && NewTA->isDefaultVersion()) || - MVType == MultiVersioning::CPUDispatch || - MVType == MultiVersioning::CPUSpecific) { + if ((MVType == MultiVersionKind::Target && NewTA->isDefaultVersion()) || + MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific) { S.Diag(NewFD->getLocation(), diag::err_multiversion_not_allowed_on_main); NewFD->setInvalidDecl(); return true; @@ -9839,7 +9887,7 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, NewFD->getDeclContext()->getRedeclContext()) { // If there's no previous declaration, AND this isn't attempting to cause // multiversioning, this isn't an error condition. - if (MVType == MultiVersioning::None) + if (MVType == MultiVersionKind::None) return false; return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA, NewCPUDisp, NewCPUSpec); @@ -9847,29 +9895,21 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, FunctionDecl *OldFD = OldDecl->getAsFunction(); - if (!OldFD->isMultiVersion() && MVType == MultiVersioning::None) + if (!OldFD->isMultiVersion() && MVType == MultiVersionKind::None) return false; - if (OldFD->isMultiVersion() && MVType == MultiVersioning::None) { + if (OldFD->isMultiVersion() && MVType == MultiVersionKind::None) { S.Diag(NewFD->getLocation(), diag::err_multiversion_required_in_redecl) - << (getMultiVersionType(OldFD) != MultiVersioning::Target); + << (OldFD->getMultiVersionKind() != MultiVersionKind::Target); NewFD->setInvalidDecl(); return true; } // Handle the target potentially causes multiversioning case. - if (!OldFD->isMultiVersion() && MVType == MultiVersioning::Target) + if (!OldFD->isMultiVersion() && MVType == MultiVersionKind::Target) return CheckTargetCausesMultiVersioning(S, OldFD, NewFD, NewTA, Redeclaration, OldDecl, MergeTypeWithPrevious, Previous); - // Previous declarations lack CPUDispatch/CPUSpecific. - if (!OldFD->isMultiVersion()) { - S.Diag(OldFD->getLocation(), diag::err_multiversion_required_in_redecl) - << 1; - S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); - NewFD->setInvalidDecl(); - return true; - } // At this point, we have a multiversion function decl (in OldFD) AND an // appropriate attribute in the current function decl. Resolve that these are @@ -9982,7 +10022,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); if (!getLangOpts().CPlusPlus14 && MD && MD->isConstexpr() && !MD->isStatic() && !isa<CXXConstructorDecl>(MD) && - (MD->getTypeQualifiers() & Qualifiers::Const) == 0) { + !MD->getTypeQualifiers().hasConst()) { CXXMethodDecl *OldMD = nullptr; if (OldDecl) OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl->getAsFunction()); @@ -9990,7 +10030,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - EPI.TypeQuals |= Qualifiers::Const; + EPI.TypeQuals.addConst(); MD->setType(Context.getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI)); @@ -10022,11 +10062,17 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (FunctionTemplateDecl *OldTemplateDecl = dyn_cast<FunctionTemplateDecl>(OldDecl)) { auto *OldFD = OldTemplateDecl->getTemplatedDecl(); - NewFD->setPreviousDeclaration(OldFD); - adjustDeclContextForDeclaratorDecl(NewFD, OldFD); FunctionTemplateDecl *NewTemplateDecl = NewFD->getDescribedFunctionTemplate(); assert(NewTemplateDecl && "Template/non-template mismatch"); + + // The call to MergeFunctionDecl above may have created some state in + // NewTemplateDecl that needs to be merged with OldTemplateDecl before we + // can add it as a redeclaration. + NewTemplateDecl->mergePrevDecl(OldTemplateDecl); + + NewFD->setPreviousDeclaration(OldFD); + adjustDeclContextForDeclaratorDecl(NewFD, OldFD); if (NewFD->isCXXClassMember()) { NewFD->setAccess(OldTemplateDecl->getAccess()); NewTemplateDecl->setAccess(OldTemplateDecl->getAccess()); @@ -10479,7 +10525,7 @@ namespace { Expr *Base = E; bool ReferenceField = false; - // Get the field memebers used. + // Get the field members used. while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) { FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); if (!FD) @@ -11707,7 +11753,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { // In Objective-C, don't allow jumps past the implicit initialization of a // local retaining variable. - if (getLangOpts().ObjC1 && + if (getLangOpts().ObjC && var->hasLocalStorage()) { switch (var->getType().getObjCLifetime()) { case Qualifiers::OCL_None: @@ -11826,37 +11872,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { QualType type = var->getType(); if (type->isDependentType()) return; - // __block variables might require us to capture a copy-initializer. - if (var->hasAttr<BlocksAttr>()) { - // It's currently invalid to ever have a __block variable with an - // array type; should we diagnose that here? - - // Regardless, we don't want to ignore array nesting when - // constructing this copy. - if (type->isStructureOrClassType()) { - EnterExpressionEvaluationContext scope( - *this, ExpressionEvaluationContext::PotentiallyEvaluated); - SourceLocation poi = var->getLocation(); - Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi); - ExprResult result - = PerformMoveOrCopyInitialization( - InitializedEntity::InitializeBlock(poi, type, false), - var, var->getType(), varRef, /*AllowNRVO=*/true); - if (!result.isInvalid()) { - result = MaybeCreateExprWithCleanups(result); - Expr *init = result.getAs<Expr>(); - Context.setBlockVarCopyInit(var, init, canThrow(init)); - } - - // The destructor's exception spefication is needed when IRGen generates - // block copy/destroy functions. Resolve it here. - if (const CXXRecordDecl *RD = type->getAsCXXRecordDecl()) - if (CXXDestructorDecl *DD = RD->getDestructor()) { - auto *FPT = DD->getType()->getAs<FunctionProtoType>(); - FPT = ResolveExceptionSpec(poi, FPT); - } - } - } + if (var->hasAttr<BlocksAttr>()) + getCurFunction()->addByrefBlockVar(var); Expr *Init = var->getInit(); bool IsGlobal = GlobalStorage && !var->isStaticLocal(); @@ -11947,6 +11964,49 @@ static bool hasDependentAlignment(VarDecl *VD) { return false; } +/// Check if VD needs to be dllexport/dllimport due to being in a +/// dllexport/import function. +void Sema::CheckStaticLocalForDllExport(VarDecl *VD) { + assert(VD->isStaticLocal()); + + auto *FD = dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod()); + + // Find outermost function when VD is in lambda function. + while (FD && !getDLLAttr(FD) && + !FD->hasAttr<DLLExportStaticLocalAttr>() && + !FD->hasAttr<DLLImportStaticLocalAttr>()) { + FD = dyn_cast_or_null<FunctionDecl>(FD->getParentFunctionOrMethod()); + } + + if (!FD) + return; + + // Static locals inherit dll attributes from their function. + if (Attr *A = getDLLAttr(FD)) { + auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext())); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + } else if (Attr *A = FD->getAttr<DLLExportStaticLocalAttr>()) { + auto *NewAttr = ::new (getASTContext()) DLLExportAttr(A->getRange(), + getASTContext(), + A->getSpellingListIndex()); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + + // Export this function to enforce exporting this static variable even + // if it is not used in this compilation unit. + if (!FD->hasAttr<DLLExportAttr>()) + FD->addAttr(NewAttr); + + } else if (Attr *A = FD->getAttr<DLLImportStaticLocalAttr>()) { + auto *NewAttr = ::new (getASTContext()) DLLImportAttr(A->getRange(), + getASTContext(), + A->getSpellingListIndex()); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + } +} + /// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform /// any semantic actions necessary after any initializer has been attached. void Sema::FinalizeDeclaration(Decl *ThisDecl) { @@ -12000,14 +12060,9 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { } if (VD->isStaticLocal()) { - if (FunctionDecl *FD = - dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod())) { - // Static locals inherit dll attributes from their function. - if (Attr *A = getDLLAttr(FD)) { - auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext())); - NewAttr->setInherited(true); - VD->addAttr(NewAttr); - } + CheckStaticLocalForDllExport(VD); + + if (dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod())) { // CUDA 8.0 E.3.9.4: Within the body of a __device__ or __global__ // function, only __shared__ variables or variables without any device // memory qualifiers may be declared with static storage class. @@ -12687,6 +12742,29 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, } } } + + if (!Definition) + // Similar to friend functions a friend function template may be a + // definition and do not have a body if it is instantiated in a class + // template. + if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) { + for (auto I : FTD->redecls()) { + auto D = cast<FunctionTemplateDecl>(I); + if (D != FTD) { + assert(!D->isThisDeclarationADefinition() && + "More than one definition in redeclaration chain"); + if (D->getFriendObjectKind() != Decl::FOK_None) + if (FunctionTemplateDecl *FT = + D->getInstantiatedFromMemberTemplate()) { + if (FT->isThisDeclarationADefinition()) { + Definition = D->getTemplatedDecl(); + break; + } + } + } + } + } + if (!Definition) return; @@ -12778,6 +12856,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, // Parsing the function declaration failed in some way. Push on a fake scope // anyway so we can try to parse the function body. PushFunctionScope(); + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); return D; } @@ -12788,6 +12867,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, else FD = cast<FunctionDecl>(D); + // Do not push if it is a lambda because one is already pushed when building + // the lambda in ActOnStartOfLambdaDefinition(). + if (!isLambdaCallOperator(FD)) + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); + // Check for defining attributes before the check for redefinition. if (const auto *Attr = FD->getAttr<AliasAttr>()) { Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0; @@ -12996,6 +13080,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { return ActOnFinishFunctionBody(D, BodyArg, false); } +/// RAII object that pops an ExpressionEvaluationContext when exiting a function +/// body. +class ExitFunctionBodyRAII { +public: + ExitFunctionBodyRAII(Sema &S, bool IsLambda) : S(S), IsLambda(IsLambda) {} + ~ExitFunctionBodyRAII() { + if (!IsLambda) + S.PopExpressionEvaluationContext(); + } + +private: + Sema &S; + bool IsLambda = false; +}; + Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation) { FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr; @@ -13006,6 +13105,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (getLangOpts().CoroutinesTS && getCurFunction()->isCoroutine()) CheckCompletedCoroutineBody(FD, Body); + // Do not call PopExpressionEvaluationContext() if it is a lambda because one + // is already popped when finishing the lambda in BuildLambdaExpr(). This is + // meant to pop the context added in ActOnStartOfFunctionDef(). + ExitFunctionBodyRAII ExitRAII(*this, isLambdaCallOperator(FD)); + if (FD) { FD->setBody(Body); FD->setWillHaveBody(false); @@ -13060,7 +13164,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!FD->isInvalidDecl()) { // Don't diagnose unused parameters of defaulted or deleted functions. - if (!FD->isDeleted() && !FD->isDefaulted()) + if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody()) DiagnoseUnusedParameters(FD->parameters()); DiagnoseSizeOfParametersAndReturnValue(FD->parameters(), FD->getReturnType(), FD); @@ -13155,7 +13259,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); if (!MD->isInvalidDecl()) { - DiagnoseUnusedParameters(MD->parameters()); + if (!MD->hasSkippedBody()) + DiagnoseUnusedParameters(MD->parameters()); DiagnoseSizeOfParametersAndReturnValue(MD->parameters(), MD->getReturnType(), MD); @@ -13745,76 +13850,106 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, // struct class-key shall be used to refer to a class (clause 9) // declared using the class or struct class-key. TagTypeKind OldTag = Previous->getTagKind(); - if (!isDefinition || !isClassCompatTagKind(NewTag)) - if (OldTag == NewTag) + if (OldTag != NewTag && + !(isClassCompatTagKind(OldTag) && isClassCompatTagKind(NewTag))) + return false; + + // Tags are compatible, but we might still want to warn on mismatched tags. + // Non-class tags can't be mismatched at this point. + if (!isClassCompatTagKind(NewTag)) + return true; + + // Declarations for which -Wmismatched-tags is disabled are entirely ignored + // by our warning analysis. We don't want to warn about mismatches with (eg) + // declarations in system headers that are designed to be specialized, but if + // a user asks us to warn, we should warn if their code contains mismatched + // declarations. + auto IsIgnoredLoc = [&](SourceLocation Loc) { + return getDiagnostics().isIgnored(diag::warn_struct_class_tag_mismatch, + Loc); + }; + if (IsIgnoredLoc(NewTagLoc)) + return true; + + auto IsIgnored = [&](const TagDecl *Tag) { + return IsIgnoredLoc(Tag->getLocation()); + }; + while (IsIgnored(Previous)) { + Previous = Previous->getPreviousDecl(); + if (!Previous) return true; + OldTag = Previous->getTagKind(); + } - if (isClassCompatTagKind(OldTag) && isClassCompatTagKind(NewTag)) { - // Warn about the struct/class tag mismatch. - bool isTemplate = false; - if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous)) - isTemplate = Record->getDescribedClassTemplate(); + bool isTemplate = false; + if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous)) + isTemplate = Record->getDescribedClassTemplate(); - if (inTemplateInstantiation()) { + if (inTemplateInstantiation()) { + if (OldTag != NewTag) { // In a template instantiation, do not offer fix-its for tag mismatches // since they usually mess up the template instead of fixing the problem. Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch) << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name << getRedeclDiagFromTagKind(OldTag); + // FIXME: Note previous location? + } + return true; + } + + if (isDefinition) { + // On definitions, check all previous tags and issue a fix-it for each + // one that doesn't match the current tag. + if (Previous->getDefinition()) { + // Don't suggest fix-its for redefinitions. return true; } - if (isDefinition) { - // On definitions, check previous tags and issue a fix-it for each - // one that doesn't match the current tag. - if (Previous->getDefinition()) { - // Don't suggest fix-its for redefinitions. - return true; - } + bool previousMismatch = false; + for (const TagDecl *I : Previous->redecls()) { + if (I->getTagKind() != NewTag) { + // Ignore previous declarations for which the warning was disabled. + if (IsIgnored(I)) + continue; - bool previousMismatch = false; - for (auto I : Previous->redecls()) { - if (I->getTagKind() != NewTag) { - if (!previousMismatch) { - previousMismatch = true; - Diag(NewTagLoc, diag::warn_struct_class_previous_tag_mismatch) - << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name - << getRedeclDiagFromTagKind(I->getTagKind()); - } - Diag(I->getInnerLocStart(), diag::note_struct_class_suggestion) - << getRedeclDiagFromTagKind(NewTag) - << FixItHint::CreateReplacement(I->getInnerLocStart(), - TypeWithKeyword::getTagTypeKindName(NewTag)); + if (!previousMismatch) { + previousMismatch = true; + Diag(NewTagLoc, diag::warn_struct_class_previous_tag_mismatch) + << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name + << getRedeclDiagFromTagKind(I->getTagKind()); } + Diag(I->getInnerLocStart(), diag::note_struct_class_suggestion) + << getRedeclDiagFromTagKind(NewTag) + << FixItHint::CreateReplacement(I->getInnerLocStart(), + TypeWithKeyword::getTagTypeKindName(NewTag)); } - return true; - } - - // Check for a previous definition. If current tag and definition - // are same type, do nothing. If no definition, but disagree with - // with previous tag type, give a warning, but no fix-it. - const TagDecl *Redecl = Previous->getDefinition() ? - Previous->getDefinition() : Previous; - if (Redecl->getTagKind() == NewTag) { - return true; } + return true; + } + // Identify the prevailing tag kind: this is the kind of the definition (if + // there is a non-ignored definition), or otherwise the kind of the prior + // (non-ignored) declaration. + const TagDecl *PrevDef = Previous->getDefinition(); + if (PrevDef && IsIgnored(PrevDef)) + PrevDef = nullptr; + const TagDecl *Redecl = PrevDef ? PrevDef : Previous; + if (Redecl->getTagKind() != NewTag) { Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch) << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name << getRedeclDiagFromTagKind(OldTag); Diag(Redecl->getLocation(), diag::note_previous_use); // If there is a previous definition, suggest a fix-it. - if (Previous->getDefinition()) { - Diag(NewTagLoc, diag::note_struct_class_suggestion) - << getRedeclDiagFromTagKind(Redecl->getTagKind()) - << FixItHint::CreateReplacement(SourceRange(NewTagLoc), - TypeWithKeyword::getTagTypeKindName(Redecl->getTagKind())); + if (PrevDef) { + Diag(NewTagLoc, diag::note_struct_class_suggestion) + << getRedeclDiagFromTagKind(Redecl->getTagKind()) + << FixItHint::CreateReplacement(SourceRange(NewTagLoc), + TypeWithKeyword::getTagTypeKindName(Redecl->getTagKind())); } - - return true; } - return false; + + return true; } /// Add a minimal nested name specifier fixit hint to allow lookup of a tag name @@ -14615,7 +14750,7 @@ CreateNewDecl: // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; - if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && + if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC) && cast<EnumDecl>(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. // Conflicts are diagnosed above. Do nothing. @@ -15090,22 +15225,6 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, } } - // TR 18037 does not allow fields to be declared with address spaces. - if (T.getQualifiers().hasAddressSpace() || - T->isDependentAddressSpaceType() || - T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) { - Diag(Loc, diag::err_field_with_address_space); - D.setInvalidType(); - } - - // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be - // used as structure or union field: image, sampler, event or block types. - if (LangOpts.OpenCL && (T->isEventT() || T->isImageType() || - T->isSamplerT() || T->isBlockPointerType())) { - Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T; - D.setInvalidType(); - } - DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (D.getDeclSpec().isInlineSpecified()) @@ -15217,12 +15336,30 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } } - // OpenCL v1.2 s6.9.c: bitfields are not supported. - if (BitWidth && getLangOpts().OpenCL) { - Diag(Loc, diag::err_opencl_bitfields); + // TR 18037 does not allow fields to be declared with address space + if (T.getQualifiers().hasAddressSpace() || T->isDependentAddressSpaceType() || + T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) { + Diag(Loc, diag::err_field_with_address_space); + Record->setInvalidDecl(); InvalidDecl = true; } + if (LangOpts.OpenCL) { + // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be + // used as structure or union field: image, sampler, event or block types. + if (T->isEventT() || T->isImageType() || T->isSamplerT() || + T->isBlockPointerType()) { + Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T; + Record->setInvalidDecl(); + InvalidDecl = true; + } + // OpenCL v1.2 s6.9.c: bitfields are not supported. + if (BitWidth) { + Diag(Loc, diag::err_opencl_bitfields); + InvalidDecl = true; + } + } + // Anonymous bit-fields cannot be cv-qualified (CWG 2229). if (!InvalidDecl && getLangOpts().CPlusPlus && !II && BitWidth && T.hasQualifiers()) { @@ -15794,7 +15931,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, } ObjCFieldLifetimeErrReported = true; } - } else if (getLangOpts().ObjC1 && + } else if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC && Record && !Record->hasObjectMember()) { if (FD->getType()->isObjCObjectPointerType() || @@ -16292,8 +16429,10 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, // Verify that there isn't already something declared with this name in this // scope. - NamedDecl *PrevDecl = LookupSingleName(S, Id, IdLoc, LookupOrdinaryName, - ForVisibleRedeclaration); + LookupResult R(*this, Id, IdLoc, LookupOrdinaryName, ForVisibleRedeclaration); + LookupName(R, S); + NamedDecl *PrevDecl = R.getAsSingle<NamedDecl>(); + if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(IdLoc, PrevDecl); @@ -16316,6 +16455,11 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, return nullptr; if (PrevDecl) { + if (!TheEnumDecl->isScoped() && isa<ValueDecl>(PrevDecl)) { + // Check for other kinds of shadowing not already handled. + CheckShadow(New, PrevDecl, R); + } + // When in C++, we may get a TagDecl with the same name; in this case the // enum constant will 'hide' the tag. assert((getLangOpts().CPlusPlus || !isa<TagDecl>(PrevDecl)) && @@ -16573,7 +16717,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, NumNegativeBits = std::max(NumNegativeBits, (unsigned)InitVal.getMinSignedBits()); - // Keep track of whether every enum element has type int (very commmon). + // Keep track of whether every enum element has type int (very common). if (AllElementsInt) AllElementsInt = ECD->getType() == Context.IntTy; } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 17b93e0add..78374b8089 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -392,9 +392,49 @@ bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum, /// Applies the given attribute to the Decl without performing any /// additional semantic checking. template <typename AttrType> +static void handleSimpleAttribute(Sema &S, Decl *D, SourceRange SR, + unsigned SpellingIndex) { + D->addAttr(::new (S.Context) AttrType(SR, S.Context, SpellingIndex)); +} + +template <typename AttrType> static void handleSimpleAttribute(Sema &S, Decl *D, const ParsedAttr &AL) { - D->addAttr(::new (S.Context) AttrType(AL.getRange(), S.Context, - AL.getAttributeSpellingListIndex())); + handleSimpleAttribute<AttrType>(S, D, AL.getRange(), + AL.getAttributeSpellingListIndex()); +} + + +template <typename... DiagnosticArgs> +static const Sema::SemaDiagnosticBuilder& +appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) { + return Bldr; +} + +template <typename T, typename... DiagnosticArgs> +static const Sema::SemaDiagnosticBuilder& +appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg, + DiagnosticArgs &&... ExtraArgs) { + return appendDiagnostics(Bldr << std::forward<T>(ExtraArg), + std::forward<DiagnosticArgs>(ExtraArgs)...); +} + +/// Add an attribute {@code AttrType} to declaration {@code D}, +/// provided the given {@code Check} function returns {@code true} +/// on type of {@code D}. +/// If check does not pass, emit diagnostic {@code DiagID}, +/// passing in all parameters specified in {@code ExtraArgs}. +template <typename AttrType, typename... DiagnosticArgs> +static void +handleSimpleAttributeWithCheck(Sema &S, ValueDecl *D, SourceRange SR, + unsigned SpellingIndex, + llvm::function_ref<bool(QualType)> Check, + unsigned DiagID, DiagnosticArgs... ExtraArgs) { + if (!Check(D->getType())) { + Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID); + appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...); + return; + } + handleSimpleAttribute<AttrType>(S, D, SR, SpellingIndex); } template <typename AttrType> @@ -2410,6 +2450,15 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getReplacementExpr())) Replacement = SE->getString(); + if (II->isStr("swift")) { + if (Introduced.isValid() || Obsoleted.isValid() || + (!IsUnavailable && !Deprecated.isValid())) { + S.Diag(AL.getLoc(), + diag::warn_availability_swift_unavailable_deprecated_only); + return; + } + } + AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, AL.getRange(), II, false/*Implicit*/, Introduced.Version, @@ -4143,7 +4192,7 @@ static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const auto *VD = cast<VarDecl>(D); // extern __shared__ is only allowed on arrays with no length (e.g. // "int x[]"). - if (!S.getLangOpts().CUDARelocatableDeviceCode && VD->hasExternalStorage() && + if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() && !isa<IncompleteArrayType>(VD->getType())) { S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD; return; @@ -4282,6 +4331,11 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) { AL.getAttributeSpellingListIndex())); return; } + case ParsedAttr::AT_AArch64VectorPcs: + D->addAttr(::new(S.Context) + AArch64VectorPcsAttr(AL.getRange(), S.Context, + AL.getAttributeSpellingListIndex())); + return; case ParsedAttr::AT_IntelOclBicc: D->addAttr(::new (S.Context) IntelOclBiccAttr(AL.getRange(), S.Context, @@ -4359,6 +4413,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, case ParsedAttr::AT_VectorCall: CC = CC_X86VectorCall; break; + case ParsedAttr::AT_AArch64VectorPcs: + CC = CC_AArch64VectorCall; + break; case ParsedAttr::AT_RegCall: CC = CC_X86RegCall; break; @@ -4694,58 +4751,70 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) { //===----------------------------------------------------------------------===// // Checker-specific attribute handlers. //===----------------------------------------------------------------------===// - static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT) { return QT->isDependentType() || QT->isObjCRetainableType(); } -static bool isValidSubjectOfNSAttribute(Sema &S, QualType QT) { +static bool isValidSubjectOfNSAttribute(QualType QT) { return QT->isDependentType() || QT->isObjCObjectPointerType() || - S.Context.isObjCNSObjectType(QT); + QT->isObjCNSObjectType(); } -static bool isValidSubjectOfCFAttribute(Sema &S, QualType QT) { +static bool isValidSubjectOfCFAttribute(QualType QT) { return QT->isDependentType() || QT->isPointerType() || - isValidSubjectOfNSAttribute(S, QT); + isValidSubjectOfNSAttribute(QT); } -static void handleNSConsumedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - S.AddNSConsumedAttr(AL.getRange(), D, AL.getAttributeSpellingListIndex(), - AL.getKind() == ParsedAttr::AT_NSConsumed, - /*template instantiation*/ false); +static bool isValidSubjectOfOSAttribute(QualType QT) { + return QT->isDependentType() || QT->isPointerType(); } -void Sema::AddNSConsumedAttr(SourceRange AttrRange, Decl *D, - unsigned SpellingIndex, bool IsNSConsumed, - bool IsTemplateInstantiation) { - const auto *Param = cast<ParmVarDecl>(D); - bool TypeOK; - - if (IsNSConsumed) - TypeOK = isValidSubjectOfNSAttribute(*this, Param->getType()); - else - TypeOK = isValidSubjectOfCFAttribute(*this, Param->getType()); +void Sema::AddXConsumedAttr(Decl *D, SourceRange SR, unsigned SpellingIndex, + RetainOwnershipKind K, + bool IsTemplateInstantiation) { + ValueDecl *VD = cast<ValueDecl>(D); + switch (K) { + case RetainOwnershipKind::OS: + handleSimpleAttributeWithCheck<OSConsumedAttr>( + *this, VD, SR, SpellingIndex, &isValidSubjectOfOSAttribute, + diag::warn_ns_attribute_wrong_parameter_type, + /*ExtraArgs=*/SR, "os_consumed", /*pointers*/ 1); + return; + case RetainOwnershipKind::NS: + handleSimpleAttributeWithCheck<NSConsumedAttr>( + *this, VD, SR, SpellingIndex, &isValidSubjectOfNSAttribute, - if (!TypeOK) { - // These attributes are normally just advisory, but in ARC, ns_consumed - // is significant. Allow non-dependent code to contain inappropriate - // attributes even in ARC, but require template instantiations to be - // set up correctly. - Diag(D->getBeginLoc(), (IsTemplateInstantiation && IsNSConsumed && - getLangOpts().ObjCAutoRefCount - ? diag::err_ns_attribute_wrong_parameter_type - : diag::warn_ns_attribute_wrong_parameter_type)) - << AttrRange << (IsNSConsumed ? "ns_consumed" : "cf_consumed") - << (IsNSConsumed ? /*objc pointers*/ 0 : /*cf pointers*/ 1); + // These attributes are normally just advisory, but in ARC, ns_consumed + // is significant. Allow non-dependent code to contain inappropriate + // attributes even in ARC, but require template instantiations to be + // set up correctly. + ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount) + ? diag::err_ns_attribute_wrong_parameter_type + : diag::warn_ns_attribute_wrong_parameter_type), + /*ExtraArgs=*/SR, "ns_consumed", /*objc pointers*/ 0); + return; + case RetainOwnershipKind::CF: + handleSimpleAttributeWithCheck<CFConsumedAttr>( + *this, VD, SR, SpellingIndex, + &isValidSubjectOfCFAttribute, + diag::warn_ns_attribute_wrong_parameter_type, + /*ExtraArgs=*/SR, "cf_consumed", /*pointers*/1); return; } +} - if (IsNSConsumed) - D->addAttr(::new (Context) - NSConsumedAttr(AttrRange, Context, SpellingIndex)); - else - D->addAttr(::new (Context) - CFConsumedAttr(AttrRange, Context, SpellingIndex)); +static Sema::RetainOwnershipKind +parsedAttrToRetainOwnershipKind(const ParsedAttr &AL) { + switch (AL.getKind()) { + case ParsedAttr::AT_CFConsumed: + return Sema::RetainOwnershipKind::CF; + case ParsedAttr::AT_OSConsumed: + return Sema::RetainOwnershipKind::OS; + case ParsedAttr::AT_NSConsumed: + return Sema::RetainOwnershipKind::NS; + default: + llvm_unreachable("Wrong argument supplied"); + } } bool Sema::checkNSReturnsRetainedReturnType(SourceLocation Loc, QualType QT) { @@ -4757,24 +4826,26 @@ bool Sema::checkNSReturnsRetainedReturnType(SourceLocation Loc, QualType QT) { return true; } -static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, +static void handleXReturnsXRetainedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { QualType ReturnType; - if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) + if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) { ReturnType = MD->getReturnType(); - else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && - (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) + } else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && + (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) { return; // ignore: was handled as a type attribute - else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) + } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) { ReturnType = PD->getType(); - else if (const auto *FD = dyn_cast<FunctionDecl>(D)) + } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) { ReturnType = FD->getReturnType(); - else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) { + } else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) { + // Attributes on parameters are used for out-parameters, + // passed as pointers-to-pointers. ReturnType = Param->getType()->getPointeeType(); if (ReturnType.isNull()) { S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type) - << AL << /*pointer-to-CF*/ 2 << AL.getRange(); + << AL << /*pointer-to-CF-pointer*/ 2 << AL.getRange(); return; } } else if (AL.isUsedAsTypeAttr()) { @@ -4786,6 +4857,8 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, case ParsedAttr::AT_NSReturnsRetained: case ParsedAttr::AT_NSReturnsAutoreleased: case ParsedAttr::AT_NSReturnsNotRetained: + case ParsedAttr::AT_OSReturnsRetained: + case ParsedAttr::AT_OSReturnsNotRetained: ExpectedDeclKind = ExpectedFunctionOrMethod; break; @@ -4810,13 +4883,19 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, case ParsedAttr::AT_NSReturnsAutoreleased: case ParsedAttr::AT_NSReturnsNotRetained: - TypeOK = isValidSubjectOfNSAttribute(S, ReturnType); + TypeOK = isValidSubjectOfNSAttribute(ReturnType); Cf = false; break; case ParsedAttr::AT_CFReturnsRetained: case ParsedAttr::AT_CFReturnsNotRetained: - TypeOK = isValidSubjectOfCFAttribute(S, ReturnType); + TypeOK = isValidSubjectOfCFAttribute(ReturnType); + Cf = true; + break; + + case ParsedAttr::AT_OSReturnsRetained: + case ParsedAttr::AT_OSReturnsNotRetained: + TypeOK = isValidSubjectOfOSAttribute(ReturnType); Cf = true; break; } @@ -4849,24 +4928,25 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, default: llvm_unreachable("invalid ownership attribute"); case ParsedAttr::AT_NSReturnsAutoreleased: - D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr( - AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); + handleSimpleAttribute<NSReturnsAutoreleasedAttr>(S, D, AL); return; case ParsedAttr::AT_CFReturnsNotRetained: - D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr( - AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); + handleSimpleAttribute<CFReturnsNotRetainedAttr>(S, D, AL); return; case ParsedAttr::AT_NSReturnsNotRetained: - D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr( - AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); + handleSimpleAttribute<NSReturnsNotRetainedAttr>(S, D, AL); return; case ParsedAttr::AT_CFReturnsRetained: - D->addAttr(::new (S.Context) CFReturnsRetainedAttr( - AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); + handleSimpleAttribute<CFReturnsRetainedAttr>(S, D, AL); return; case ParsedAttr::AT_NSReturnsRetained: - D->addAttr(::new (S.Context) NSReturnsRetainedAttr( - AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); + handleSimpleAttribute<NSReturnsRetainedAttr>(S, D, AL); + return; + case ParsedAttr::AT_OSReturnsRetained: + handleSimpleAttribute<OSReturnsRetainedAttr>(S, D, AL); + return; + case ParsedAttr::AT_OSReturnsNotRetained: + handleSimpleAttribute<OSReturnsNotRetainedAttr>(S, D, AL); return; }; } @@ -5834,10 +5914,8 @@ static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { !S.checkStringLiteralArgumentAttr(AL, 1, Replacement)) return; - if (!S.getLangOpts().CPlusPlus14) - if (AL.isCXX11Attribute() && - !(AL.hasScope() && AL.getScopeName()->isStr("gnu"))) - S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL; + if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope()) + S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL; D->addAttr(::new (S.Context) DeprecatedAttr(AL.getRange(), S.Context, Str, Replacement, @@ -6322,17 +6400,25 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, break; case ParsedAttr::AT_CFConsumed: case ParsedAttr::AT_NSConsumed: - handleNSConsumedAttr(S, D, AL); + case ParsedAttr::AT_OSConsumed: + S.AddXConsumedAttr(D, AL.getRange(), AL.getAttributeSpellingListIndex(), + parsedAttrToRetainOwnershipKind(AL), + /*IsTemplateInstantiation=*/false); break; case ParsedAttr::AT_NSConsumesSelf: handleSimpleAttribute<NSConsumesSelfAttr>(S, D, AL); break; + case ParsedAttr::AT_OSConsumesThis: + handleSimpleAttribute<OSConsumesThisAttr>(S, D, AL); + break; case ParsedAttr::AT_NSReturnsAutoreleased: case ParsedAttr::AT_NSReturnsNotRetained: - case ParsedAttr::AT_CFReturnsNotRetained: case ParsedAttr::AT_NSReturnsRetained: + case ParsedAttr::AT_CFReturnsNotRetained: case ParsedAttr::AT_CFReturnsRetained: - handleNSReturnsRetainedAttr(S, D, AL); + case ParsedAttr::AT_OSReturnsNotRetained: + case ParsedAttr::AT_OSReturnsRetained: + handleXReturnsXRetainedAttr(S, D, AL); break; case ParsedAttr::AT_WorkGroupSizeHint: handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL); @@ -6358,6 +6444,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_Section: handleSectionAttr(S, D, AL); break; + case ParsedAttr::AT_SpeculativeLoadHardening: + handleSimpleAttribute<SpeculativeLoadHardeningAttr>(S, D, AL); + break; case ParsedAttr::AT_CodeSeg: handleCodeSegAttr(S, D, AL); break; @@ -6486,6 +6575,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_IntelOclBicc: case ParsedAttr::AT_PreserveMost: case ParsedAttr::AT_PreserveAll: + case ParsedAttr::AT_AArch64VectorPcs: handleCallConvAttr(S, D, AL); break; case ParsedAttr::AT_Suppress: @@ -6512,6 +6602,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case ParsedAttr::AT_InternalLinkage: handleInternalLinkageAttr(S, D, AL); break; + case ParsedAttr::AT_ExcludeFromExplicitInstantiation: + handleSimpleAttribute<ExcludeFromExplicitInstantiationAttr>(S, D, AL); + break; case ParsedAttr::AT_LTOVisibilityPublic: handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, AL); break; @@ -7732,7 +7825,7 @@ public: bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) { SemaRef.Diag(E->getBeginLoc(), diag::warn_at_available_unchecked_use) - << (!SemaRef.getLangOpts().ObjC1); + << (!SemaRef.getLangOpts().ObjC); return true; } @@ -7787,8 +7880,8 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( auto FixitDiag = SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence) << Range << D - << (SemaRef.getLangOpts().ObjC1 ? /*@available*/ 0 - : /*__builtin_available*/ 1); + << (SemaRef.getLangOpts().ObjC ? /*@available*/ 0 + : /*__builtin_available*/ 1); // Find the statement which should be enclosed in the if @available check. if (StmtStack.empty()) @@ -7832,8 +7925,8 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability( const char *ExtraIndentation = " "; std::string FixItString; llvm::raw_string_ostream FixItOS(FixItString); - FixItOS << "if (" << (SemaRef.getLangOpts().ObjC1 ? "@available" - : "__builtin_available") + FixItOS << "if (" << (SemaRef.getLangOpts().ObjC ? "@available" + : "__builtin_available") << "(" << AvailabilityAttr::getPlatformNameSourceSpelling( SemaRef.getASTContext().getTargetInfo().getPlatformName()) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3261a7031d..4a7ab11c71 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1803,7 +1803,7 @@ static void CheckConstexprCtorInitializer(Sema &SemaRef, static bool CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, SmallVectorImpl<SourceLocation> &ReturnStmts, - SourceLocation &Cxx1yLoc) { + SourceLocation &Cxx1yLoc, SourceLocation &Cxx2aLoc) { // - its function-body shall be [...] a compound-statement that contains only switch (S->getStmtClass()) { case Stmt::NullStmtClass: @@ -1840,7 +1840,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, CompoundStmt *CompStmt = cast<CompoundStmt>(S); for (auto *BodyIt : CompStmt->body()) { if (!CheckConstexprFunctionStmt(SemaRef, Dcl, BodyIt, ReturnStmts, - Cxx1yLoc)) + Cxx1yLoc, Cxx2aLoc)) return false; } return true; @@ -1858,11 +1858,11 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, IfStmt *If = cast<IfStmt>(S); if (!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getThen(), ReturnStmts, - Cxx1yLoc)) + Cxx1yLoc, Cxx2aLoc)) return false; if (If->getElse() && !CheckConstexprFunctionStmt(SemaRef, Dcl, If->getElse(), ReturnStmts, - Cxx1yLoc)) + Cxx1yLoc, Cxx2aLoc)) return false; return true; } @@ -1881,7 +1881,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, for (Stmt *SubStmt : S->children()) if (SubStmt && !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, - Cxx1yLoc)) + Cxx1yLoc, Cxx2aLoc)) return false; return true; @@ -1896,10 +1896,30 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, for (Stmt *SubStmt : S->children()) if (SubStmt && !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, - Cxx1yLoc)) + Cxx1yLoc, Cxx2aLoc)) return false; return true; + case Stmt::CXXTryStmtClass: + if (Cxx2aLoc.isInvalid()) + Cxx2aLoc = S->getBeginLoc(); + for (Stmt *SubStmt : S->children()) { + if (SubStmt && + !CheckConstexprFunctionStmt(SemaRef, Dcl, SubStmt, ReturnStmts, + Cxx1yLoc, Cxx2aLoc)) + return false; + } + return true; + + case Stmt::CXXCatchStmtClass: + // Do not bother checking the language mode (already covered by the + // try block check). + if (!CheckConstexprFunctionStmt(SemaRef, Dcl, + cast<CXXCatchStmt>(S)->getHandlerBlock(), + ReturnStmts, Cxx1yLoc, Cxx2aLoc)) + return false; + return true; + default: if (!isa<Expr>(S)) break; @@ -1920,6 +1940,8 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, /// /// \return true if the body is OK, false if we have diagnosed a problem. bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) { + SmallVector<SourceLocation, 4> ReturnStmts; + if (isa<CXXTryStmt>(Body)) { // C++11 [dcl.constexpr]p3: // The definition of a constexpr function shall satisfy the following @@ -1930,22 +1952,35 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) { // C++11 [dcl.constexpr]p4: // In the definition of a constexpr constructor, [...] // - its function-body shall not be a function-try-block; - Diag(Body->getBeginLoc(), diag::err_constexpr_function_try_block) + // + // This restriction is lifted in C++2a, as long as inner statements also + // apply the general constexpr rules. + Diag(Body->getBeginLoc(), + !getLangOpts().CPlusPlus2a + ? diag::ext_constexpr_function_try_block_cxx2a + : diag::warn_cxx17_compat_constexpr_function_try_block) << isa<CXXConstructorDecl>(Dcl); - return false; } - SmallVector<SourceLocation, 4> ReturnStmts; - // - its function-body shall be [...] a compound-statement that contains only // [... list of cases ...] - CompoundStmt *CompBody = cast<CompoundStmt>(Body); - SourceLocation Cxx1yLoc; - for (auto *BodyIt : CompBody->body()) { - if (!CheckConstexprFunctionStmt(*this, Dcl, BodyIt, ReturnStmts, Cxx1yLoc)) + // + // Note that walking the children here is enough to properly check for + // CompoundStmt and CXXTryStmt body. + SourceLocation Cxx1yLoc, Cxx2aLoc; + for (Stmt *SubStmt : Body->children()) { + if (SubStmt && + !CheckConstexprFunctionStmt(*this, Dcl, SubStmt, ReturnStmts, + Cxx1yLoc, Cxx2aLoc)) return false; } + if (Cxx2aLoc.isValid()) + Diag(Cxx2aLoc, + getLangOpts().CPlusPlus2a + ? diag::warn_cxx17_compat_constexpr_body_invalid_stmt + : diag::ext_constexpr_body_invalid_stmt_cxx2a) + << isa<CXXConstructorDecl>(Dcl); if (Cxx1yLoc.isValid()) Diag(Cxx1yLoc, getLangOpts().CPlusPlus14 @@ -2832,13 +2867,14 @@ static const ParsedAttr *getMSPropertyAttr(const ParsedAttributesView &list) { return nullptr; } -// Check if there is a field shadowing. -void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, - DeclarationName FieldName, - const CXXRecordDecl *RD) { - if (Diags.isIgnored(diag::warn_shadow_field, Loc)) - return; - +// Check if there is a field shadowing.
+void Sema::CheckShadowInheritedFields(const SourceLocation &Loc,
+ DeclarationName FieldName,
+ const CXXRecordDecl *RD,
+ bool DeclIsField) {
+ if (Diags.isIgnored(diag::warn_shadow_field, Loc))
+ return;
+
// To record a shadowed field in a base std::map<CXXRecordDecl*, NamedDecl*> Bases; auto FieldShadowed = [&](const CXXBaseSpecifier *Specifier, @@ -2872,13 +2908,13 @@ void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, continue; auto BaseField = It->second; assert(BaseField->getAccess() != AS_private); - if (AS_none != - CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) { - Diag(Loc, diag::warn_shadow_field) - << FieldName << RD << Base; - Diag(BaseField->getLocation(), diag::note_shadow_field); - Bases.erase(It); - } + if (AS_none !=
+ CXXRecordDecl::MergeAccess(P.Access, BaseField->getAccess())) {
+ Diag(Loc, diag::warn_shadow_field)
+ << FieldName << RD << Base << DeclIsField;
+ Diag(BaseField->getLocation(), diag::note_shadow_field);
+ Bases.erase(It);
+ }
} } @@ -3232,7 +3268,7 @@ namespace { ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParenImpCasts()); } - // Binding a reference to an unintialized field is not an + // Binding a reference to an uninitialized field is not an // uninitialized use. if (CheckReferenceOnly && !ReferenceField) return true; @@ -3730,8 +3766,7 @@ Sema::ActOnMemInitializer(Decl *ConstructorD, ArrayRef<Expr *> Args, SourceLocation RParenLoc, SourceLocation EllipsisLoc) { - Expr *List = new (Context) ParenListExpr(Context, LParenLoc, - Args, RParenLoc); + Expr *List = ParenListExpr::Create(Context, LParenLoc, Args, RParenLoc); return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy, DS, IdLoc, List, EllipsisLoc); } @@ -5706,8 +5741,28 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { continue; if (!getDLLAttr(Member)) { - auto *NewAttr = - cast<InheritableAttr>(ClassAttr->clone(getASTContext())); + InheritableAttr *NewAttr = nullptr; + + // Do not export/import inline function when -fno-dllexport-inlines is + // passed. But add attribute for later local static var check. + if (!getLangOpts().DllExportInlines && MD && MD->isInlined() && + TSK != TSK_ExplicitInstantiationDeclaration && + TSK != TSK_ExplicitInstantiationDefinition) { + if (ClassExported) { + NewAttr = ::new (getASTContext()) + DLLExportStaticLocalAttr(ClassAttr->getRange(), + getASTContext(), + ClassAttr->getSpellingListIndex()); + } else { + NewAttr = ::new (getASTContext()) + DLLImportStaticLocalAttr(ClassAttr->getRange(), + getASTContext(), + ClassAttr->getSpellingListIndex()); + } + } else { + NewAttr = cast<InheritableAttr>(ClassAttr->clone(getASTContext())); + } + NewAttr->setInherited(true); Member->addAttr(NewAttr); @@ -7222,8 +7277,17 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, if (getLangOpts().CUDA) { // We should delete the special member in CUDA mode if target inference // failed. - return inferCUDATargetForImplicitSpecialMember(RD, CSM, MD, SMI.ConstArg, - Diagnose); + // For inherited constructors (non-null ICI), CSM may be passed so that MD + // is treated as certain special member, which may not reflect what special + // member MD really is. However inferCUDATargetForImplicitSpecialMember + // expects CSM to match MD, therefore recalculate CSM. + assert(ICI || CSM == getSpecialMember(MD)); + auto RealCSM = CSM; + if (ICI) + RealCSM = getSpecialMember(MD); + + return inferCUDATargetForImplicitSpecialMember(RD, RealCSM, MD, + SMI.ConstArg, Diagnose); } return false; @@ -7654,7 +7718,7 @@ struct FindHiddenVirtualMethod { SmallVector<CXXMethodDecl *, 8> OverloadedMethods; private: - /// Check whether any most overriden method from MD in Methods + /// Check whether any most overridden method from MD in Methods static bool CheckMostOverridenMethods( const CXXMethodDecl *MD, const llvm::SmallPtrSetImpl<const CXXMethodDecl *> &Methods) { @@ -7738,7 +7802,7 @@ void Sema::FindHiddenVirtualMethods(CXXMethodDecl *MD, FHVM.Method = MD; FHVM.S = this; - // Keep the base methods that were overriden or introduced in the subclass + // Keep the base methods that were overridden or introduced in the subclass // by 'using' in a set. A base method not in this set is hidden. CXXRecordDecl *DC = MD->getParent(); DeclContext::lookup_result R = DC->lookup(MD->getDeclName()); @@ -8135,7 +8199,7 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, return R; FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); - EPI.TypeQuals = 0; + EPI.TypeQuals = Qualifiers(); EPI.RefQualifier = RQ_None; return Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), EPI); @@ -8341,7 +8405,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R, const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); EPI.Variadic = false; - EPI.TypeQuals = 0; + EPI.TypeQuals = Qualifiers(); EPI.RefQualifier = RQ_None; return Context.getFunctionType(Context.VoidTy, None, EPI); } @@ -11927,7 +11991,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // Dereference "this". DerefBuilder DerefThis(This); CastBuilder To(DerefThis, - Context.getCVRQualifiedType( + Context.getQualifiedType( BaseType, CopyAssignOperator->getTypeQualifiers()), VK_LValue, BasePath); @@ -12294,7 +12358,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, // Implicitly cast "this" to the appropriately-qualified base type. CastBuilder To(DerefThis, - Context.getCVRQualifiedType( + Context.getQualifiedType( BaseType, MoveAssignOperator->getTypeQualifiers()), VK_LValue, BasePath); @@ -13679,7 +13743,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, // Only the non-fragile NeXT runtime currently supports C++ catches // of ObjC types, and no runtime supports catching ObjC types by value. - if (!Invalid && getLangOpts().ObjC1) { + if (!Invalid && getLangOpts().ObjC) { QualType T = ExDeclType; if (const ReferenceType *RT = T->getAs<ReferenceType>()) T = RT->getPointeeType(); @@ -13831,6 +13895,8 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr); if (Converted.isInvalid()) Failed = true; + else + Converted = ConstantExpr::Create(Context, Converted.get()); llvm::APSInt Cond; if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond, @@ -13847,9 +13913,9 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *InnerCond = nullptr; std::string InnerCondDescription; std::tie(InnerCond, InnerCondDescription) = - findFailedBooleanCondition(Converted.get(), - /*AllowTopLevelCond=*/false); - if (InnerCond) { + findFailedBooleanCondition(Converted.get()); + if (InnerCond && !isa<CXXBoolLiteralExpr>(InnerCond) + && !isa<IntegerLiteral>(InnerCond)) { Diag(StaticAssertLoc, diag::err_static_assert_requirement_failed) << InnerCondDescription << !AssertMessage << Msg.str() << InnerCond->getSourceRange(); @@ -14937,8 +15003,11 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, // region. if (LangOpts.OpenMP && LangOpts.OpenMPIsDevice && !isInOpenMPDeclareTargetContext() && - !isInOpenMPTargetExecutionDirective()) + !isInOpenMPTargetExecutionDirective()) { + if (!DefinitionRequired) + MarkVirtualMembersReferenced(Loc, Class); return; + } // Try to insert this class into the map. LoadExternalVTableUses(); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index ac1d8cf7a3..3746bdad03 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -363,6 +363,8 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { assert((getCurMethodDecl() == nullptr) && "Methodparsing confused"); ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D); + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); + // If we don't have a valid method decl, simply return. if (!MDecl) return; @@ -2882,7 +2884,7 @@ void Sema::MatchAllMethodDeclarations(const SelectorSet &InsMap, IMPDecl, PI, IncompleteImpl, false, WarnCategoryMethodImpl); - // FIXME. For now, we are not checking for extact match of methods + // FIXME. For now, we are not checking for exact match of methods // in category implementation and its primary class's super class. if (!WarnCategoryMethodImpl && I->getSuperClass()) MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen, diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 4de205c504..e0850feaff 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -1051,6 +1051,9 @@ CanThrowResult Sema::canThrow(const Expr *E) { // [Can throw] if in a potentially-evaluated context the expression would // contain: switch (E->getStmtClass()) { + case Expr::ConstantExprClass: + return canThrow(cast<ConstantExpr>(E)->getSubExpr()); + case Expr::CXXThrowExprClass: // - a potentially evaluated throw-expression return CT_Can; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 26fb107688..4ba0fb12e7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -730,20 +730,33 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { return ExprError(); E = Res.get(); + QualType ScalarTy = Ty; + unsigned NumElts = 0; + if (const ExtVectorType *VecTy = Ty->getAs<ExtVectorType>()) { + NumElts = VecTy->getNumElements(); + ScalarTy = VecTy->getElementType(); + } + // If this is a 'float' or '__fp16' (CVR qualified or typedef) // promote to double. // Note that default argument promotion applies only to float (and // half/fp16); it does not apply to _Float16. - const BuiltinType *BTy = Ty->getAs<BuiltinType>(); + const BuiltinType *BTy = ScalarTy->getAs<BuiltinType>(); if (BTy && (BTy->getKind() == BuiltinType::Half || BTy->getKind() == BuiltinType::Float)) { if (getLangOpts().OpenCL && !getOpenCLOptions().isEnabled("cl_khr_fp64")) { - if (BTy->getKind() == BuiltinType::Half) { - E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get(); - } + if (BTy->getKind() == BuiltinType::Half) { + QualType Ty = Context.FloatTy; + if (NumElts != 0) + Ty = Context.getExtVectorType(Ty, NumElts); + E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); + } } else { - E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get(); + QualType Ty = Context.DoubleTy; + if (NumElts != 0) + Ty = Context.getExtVectorType(Ty, NumElts); + E = ImpCastExprToType(E, Ty, CK_FloatingCast).get(); } } @@ -1559,6 +1572,32 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { CharTy = Context.UnsignedCharTy; } + // Warn on initializing an array of char from a u8 string literal; this + // becomes ill-formed in C++2a. + if (getLangOpts().CPlusPlus && !getLangOpts().CPlusPlus2a && + !getLangOpts().Char8 && Kind == StringLiteral::UTF8) { + Diag(StringTokLocs.front(), diag::warn_cxx2a_compat_utf8_string); + + // Create removals for all 'u8' prefixes in the string literal(s). This + // ensures C++2a compatibility (but may change the program behavior when + // built by non-Clang compilers for which the execution character set is + // not always UTF-8). + auto RemovalDiag = PDiag(diag::note_cxx2a_compat_utf8_string_remove_u8); + SourceLocation RemovalDiagLoc; + for (const Token &Tok : StringToks) { + if (Tok.getKind() == tok::utf8_string_literal) { + if (RemovalDiagLoc.isInvalid()) + RemovalDiagLoc = Tok.getLocation(); + RemovalDiag << FixItHint::CreateRemoval(CharSourceRange::getCharRange( + Tok.getLocation(), + Lexer::AdvanceToTokenCharacter(Tok.getLocation(), 2, + getSourceManager(), getLangOpts()))); + } + } + Diag(RemovalDiagLoc, RemovalDiag); + } + + QualType CharTyConst = CharTy; // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) @@ -3036,7 +3075,7 @@ static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source, } ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT) { + PredefinedExpr::IdentKind IK) { // Pick the current block, lambda, captured statement or function. Decl *currentDecl = nullptr; if (const BlockScopeInfo *BSI = getCurBlock()) @@ -3060,11 +3099,11 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, else { // Pre-defined identifiers are of type char[x], where x is the length of // the string. - auto Str = PredefinedExpr::ComputeName(IT, currentDecl); + auto Str = PredefinedExpr::ComputeName(IK, currentDecl); unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); - if (IT == PredefinedExpr::LFunction || IT == PredefinedExpr::LFuncSig) { + if (IK == PredefinedExpr::LFunction || IK == PredefinedExpr::LFuncSig) { ResTy = Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst()); SmallString<32> RawChars; @@ -3083,24 +3122,24 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, } } - return new (Context) PredefinedExpr(Loc, ResTy, IT, SL); + return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL); } ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { - PredefinedExpr::IdentType IT; + PredefinedExpr::IdentKind IK; switch (Kind) { default: llvm_unreachable("Unknown simple primary expr!"); - case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] - case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break; - case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS] - case tok::kw___FUNCSIG__: IT = PredefinedExpr::FuncSig; break; // [MS] - case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; // [MS] - case tok::kw_L__FUNCSIG__: IT = PredefinedExpr::LFuncSig; break; // [MS] - case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break; + case tok::kw___func__: IK = PredefinedExpr::Func; break; // [C99 6.4.2.2] + case tok::kw___FUNCTION__: IK = PredefinedExpr::Function; break; + case tok::kw___FUNCDNAME__: IK = PredefinedExpr::FuncDName; break; // [MS] + case tok::kw___FUNCSIG__: IK = PredefinedExpr::FuncSig; break; // [MS] + case tok::kw_L__FUNCTION__: IK = PredefinedExpr::LFunction; break; // [MS] + case tok::kw_L__FUNCSIG__: IK = PredefinedExpr::LFuncSig; break; // [MS] + case tok::kw___PRETTY_FUNCTION__: IK = PredefinedExpr::PrettyFunction; break; } - return BuildPredefinedExpr(Loc, IT); + return BuildPredefinedExpr(Loc, IK); } ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) { @@ -3596,7 +3635,8 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T, // C99 6.5.3.4p1: if (T->isFunctionType() && - (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) { + (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf || + TraitKind == UETT_PreferredAlignOf)) { // sizeof(function)/alignof(function) is allowed as an extension. S.Diag(Loc, diag::ext_sizeof_alignof_function_type) << TraitKind << ArgRange; @@ -3674,7 +3714,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, // the expression to be complete. 'sizeof' requires the expression's type to // be complete (and will attempt to complete it if it's an array of unknown // bound). - if (ExprKind == UETT_AlignOf) { + if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) { if (RequireCompleteType(E->getExprLoc(), Context.getBaseElementType(E->getType()), diag::err_sizeof_alignof_incomplete_type, ExprKind, @@ -3698,7 +3738,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, // The operand for sizeof and alignof is in an unevaluated expression context, // so side effects could result in unintended consequences. - if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf) && + if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf || + ExprKind == UETT_PreferredAlignOf) && !inTemplateInstantiation() && E->HasSideEffects(Context, false)) Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context); @@ -3767,7 +3808,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, // C11 6.5.3.4/3, C++11 [expr.alignof]p3: // When alignof or _Alignof is applied to an array type, the result // is the alignment of the element type. - if (ExprKind == UETT_AlignOf || ExprKind == UETT_OpenMPRequiredSimdAlign) + if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf || + ExprKind == UETT_OpenMPRequiredSimdAlign) ExprType = Context.getBaseElementType(ExprType); if (ExprKind == UETT_VecStep) @@ -3796,7 +3838,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, return false; } -static bool CheckAlignOfExpr(Sema &S, Expr *E) { +static bool CheckAlignOfExpr(Sema &S, Expr *E, UnaryExprOrTypeTrait ExprKind) { E = E->IgnoreParens(); // Cannot know anything else if the expression is dependent. @@ -3850,7 +3892,7 @@ static bool CheckAlignOfExpr(Sema &S, Expr *E) { return false; } - return S.CheckUnaryExprOrTypeTraitOperand(E, UETT_AlignOf); + return S.CheckUnaryExprOrTypeTraitOperand(E, ExprKind); } bool Sema::CheckVecStepExpr(Expr *E) { @@ -4046,8 +4088,8 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, bool isInvalid = false; if (E->isTypeDependent()) { // Delay type-checking for type-dependent expressions. - } else if (ExprKind == UETT_AlignOf) { - isInvalid = CheckAlignOfExpr(*this, E); + } else if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) { + isInvalid = CheckAlignOfExpr(*this, E, ExprKind); } else if (ExprKind == UETT_VecStep) { isInvalid = CheckVecStepExpr(E); } else if (ExprKind == UETT_OpenMPRequiredSimdAlign) { @@ -4246,7 +4288,57 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, return CreateOverloadedArraySubscriptExpr(lbLoc, rbLoc, base, idx); } - return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); + ExprResult Res = CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); + + if (!Res.isInvalid() && isa<ArraySubscriptExpr>(Res.get())) + CheckSubscriptAccessOfNoDeref(cast<ArraySubscriptExpr>(Res.get())); + + return Res; +} + +void Sema::CheckAddressOfNoDeref(const Expr *E) { + ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back(); + const Expr *StrippedExpr = E->IgnoreParenImpCasts(); + + // For expressions like `&(*s).b`, the base is recorded and what should be + // checked. + const MemberExpr *Member = nullptr; + while ((Member = dyn_cast<MemberExpr>(StrippedExpr)) && !Member->isArrow()) + StrippedExpr = Member->getBase()->IgnoreParenImpCasts(); + + LastRecord.PossibleDerefs.erase(StrippedExpr); +} + +void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) { + QualType ResultTy = E->getType(); + ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back(); + + // Bail if the element is an array since it is not memory access. + if (isa<ArrayType>(ResultTy)) + return; + + if (ResultTy->hasAttr(attr::NoDeref)) { + LastRecord.PossibleDerefs.insert(E); + return; + } + + // Check if the base type is a pointer to a member access of a struct + // marked with noderef. + const Expr *Base = E->getBase(); + QualType BaseTy = Base->getType(); + if (!(isa<ArrayType>(BaseTy) || isa<PointerType>(BaseTy))) + // Not a pointer access + return; + + const MemberExpr *Member = nullptr; + while ((Member = dyn_cast<MemberExpr>(Base->IgnoreParenCasts())) && + Member->isArrow()) + Base = Member->getBase(); + + if (const auto *Ptr = dyn_cast<PointerType>(Base->getType())) { + if (Ptr->getPointeeType()->hasAttr(attr::NoDeref)) + LastRecord.PossibleDerefs.insert(E); + } } ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, @@ -4347,10 +4439,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, return ExprError(); if (LowerBound && !OriginalTy->isAnyPointerType()) { - llvm::APSInt LowerBoundValue; - if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) { + Expr::EvalResult Result; + if (LowerBound->EvaluateAsInt(Result, Context)) { // OpenMP 4.5, [2.4 Array Sections] // The array section must be a subset of the original array. + llvm::APSInt LowerBoundValue = Result.Val.getInt(); if (LowerBoundValue.isNegative()) { Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array) << LowerBound->getSourceRange(); @@ -4360,10 +4453,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, } if (Length) { - llvm::APSInt LengthValue; - if (Length->EvaluateAsInt(LengthValue, Context)) { + Expr::EvalResult Result; + if (Length->EvaluateAsInt(Result, Context)) { // OpenMP 4.5, [2.4 Array Sections] // The length must evaluate to non-negative integers. + llvm::APSInt LengthValue = Result.Val.getInt(); if (LengthValue.isNegative()) { Diag(Length->getExprLoc(), diag::err_omp_section_length_negative) << LengthValue.toString(/*Radix=*/10, /*Signed=*/true) @@ -4828,7 +4922,10 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, return true; } - Call->setNumArgs(Context, NumParams); + // We reserve space for the default arguments when we create + // the call expression, before calling ConvertArgumentsForCall. + assert((Call->getNumArgs() == NumParams) && + "We should have reserved space for the default arguments before!"); } // If too many are passed and not variadic, error on the extras and drop @@ -4869,7 +4966,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, Diag(FDecl->getBeginLoc(), diag::note_callee_decl) << FDecl; // This deletes the extra arguments. - Call->setNumArgs(Context, NumParams); + Call->shrinkNumArgs(NumParams); return true; } } @@ -5063,6 +5160,9 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLExtensionTypes.def" #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) #define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: #include "clang/AST/BuiltinTypes.def" @@ -5485,12 +5585,11 @@ ExprResult Sema::ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, /// block-pointer type. /// /// \param NDecl the declaration being called, if available -ExprResult -Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, - SourceLocation LParenLoc, - ArrayRef<Expr *> Args, - SourceLocation RParenLoc, - Expr *Config, bool IsExecConfig) { +ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, + SourceLocation LParenLoc, + ArrayRef<Expr *> Args, + SourceLocation RParenLoc, Expr *Config, + bool IsExecConfig, ADLCallKind UsesADL) { FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl); unsigned BuiltinID = (FDecl ? FDecl->getBuiltinID() : 0); @@ -5515,28 +5614,71 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // We special-case function promotion here because we only allow promoting // builtin functions to function pointers in the callee of a call. ExprResult Result; + QualType ResultTy; if (BuiltinID && Fn->getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)) { - Result = ImpCastExprToType(Fn, Context.getPointerType(FDecl->getType()), - CK_BuiltinFnToFnPtr).get(); + // Extract the return type from the (builtin) function pointer type. + // FIXME Several builtins still have setType in + // Sema::CheckBuiltinFunctionCall. One should review their definitions in + // Builtins.def to ensure they are correct before removing setType calls. + QualType FnPtrTy = Context.getPointerType(FDecl->getType()); + Result = ImpCastExprToType(Fn, FnPtrTy, CK_BuiltinFnToFnPtr).get(); + ResultTy = FDecl->getCallResultType(); } else { Result = CallExprUnaryConversions(Fn); + ResultTy = Context.BoolTy; } if (Result.isInvalid()) return ExprError(); Fn = Result.get(); - // Make the call expr early, before semantic checks. This guarantees cleanup - // of arguments and function on error. + // Check for a valid function type, but only if it is not a builtin which + // requires custom type checking. These will be handled by + // CheckBuiltinFunctionCall below just after creation of the call expression. + const FunctionType *FuncT = nullptr; + if (!BuiltinID || !Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) { + retry: + if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) { + // C99 6.5.2.2p1 - "The expression that denotes the called function shall + // have type pointer to function". + FuncT = PT->getPointeeType()->getAs<FunctionType>(); + if (!FuncT) + return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); + } else if (const BlockPointerType *BPT = + Fn->getType()->getAs<BlockPointerType>()) { + FuncT = BPT->getPointeeType()->castAs<FunctionType>(); + } else { + // Handle calls to expressions of unknown-any type. + if (Fn->getType() == Context.UnknownAnyTy) { + ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn); + if (rewrite.isInvalid()) return ExprError(); + Fn = rewrite.get(); + goto retry; + } + + return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); + } + } + + // Get the number of parameters in the function prototype, if any. + // We will allocate space for max(Args.size(), NumParams) arguments + // in the call expression. + const auto *Proto = dyn_cast_or_null<FunctionProtoType>(FuncT); + unsigned NumParams = Proto ? Proto->getNumParams() : 0; + CallExpr *TheCall; - if (Config) - TheCall = new (Context) CUDAKernelCallExpr(Context, Fn, - cast<CallExpr>(Config), Args, - Context.BoolTy, VK_RValue, - RParenLoc); - else - TheCall = new (Context) CallExpr(Context, Fn, Args, Context.BoolTy, - VK_RValue, RParenLoc); + if (Config) { + assert(UsesADL == ADLCallKind::NotADL && + "CUDAKernelCallExpr should not use ADL"); + TheCall = new (Context) + CUDAKernelCallExpr(Context, Fn, cast<CallExpr>(Config), Args, ResultTy, + VK_RValue, RParenLoc, NumParams); + } else { + TheCall = new (Context) CallExpr(Context, Fn, Args, ResultTy, VK_RValue, + RParenLoc, NumParams, UsesADL); + } if (!getLangOpts().CPlusPlus) { // C cannot always handle TypoExpr nodes in builtin calls and direct @@ -5547,39 +5689,16 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (!Result.isUsable()) return ExprError(); TheCall = dyn_cast<CallExpr>(Result.get()); if (!TheCall) return Result; - Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()); + // TheCall at this point has max(Args.size(), NumParams) arguments, + // with extra arguments nulled. We don't want to introduce nulled + // arguments in Args and so we only take the first Args.size() arguments. + Args = llvm::makeArrayRef(TheCall->getArgs(), Args.size()); } - // Bail out early if calling a builtin with custom typechecking. + // Bail out early if calling a builtin with custom type checking. if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall); - retry: - const FunctionType *FuncT; - if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) { - // C99 6.5.2.2p1 - "The expression that denotes the called function shall - // have type pointer to function". - FuncT = PT->getPointeeType()->getAs<FunctionType>(); - if (!FuncT) - return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) - << Fn->getType() << Fn->getSourceRange()); - } else if (const BlockPointerType *BPT = - Fn->getType()->getAs<BlockPointerType>()) { - FuncT = BPT->getPointeeType()->castAs<FunctionType>(); - } else { - // Handle calls to expressions of unknown-any type. - if (Fn->getType() == Context.UnknownAnyTy) { - ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn); - if (rewrite.isInvalid()) return ExprError(); - Fn = rewrite.get(); - TheCall->setCallee(Fn); - goto retry; - } - - return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) - << Fn->getType() << Fn->getSourceRange()); - } - if (getLangOpts().CUDA) { if (Config) { // CUDA: Kernel calls must be to global functions @@ -5608,7 +5727,6 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, TheCall->setType(FuncT->getCallResultType(Context)); TheCall->setValueKind(Expr::getValueKindForType(FuncT->getReturnType())); - const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT); if (Proto) { if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, RParenLoc, IsExecConfig)) @@ -5739,21 +5857,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, LiteralExpr = Result.get(); bool isFileScope = !CurContext->isFunctionOrMethod(); - if (isFileScope) { - if (!LiteralExpr->isTypeDependent() && - !LiteralExpr->isValueDependent() && - !literalType->isDependentType()) // C99 6.5.2.5p3 - if (CheckForConstantInitializer(LiteralExpr, literalType)) - return ExprError(); - } else if (literalType.getAddressSpace() != LangAS::opencl_private && - literalType.getAddressSpace() != LangAS::Default) { - // Embedded-C extensions to C99 6.5.2.5: - // "If the compound literal occurs inside the body of a function, the - // type name shall not be qualified by an address-space qualifier." - Diag(LParenLoc, diag::err_compound_literal_with_address_space) - << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); - return ExprError(); - } // In C, compound literals are l-values for some reason. // For GCC compatibility, in C++, file-scope array compound literals with @@ -5778,9 +5881,32 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, ? VK_RValue : VK_LValue; - return MaybeBindToTemporary( - new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - VK, LiteralExpr, isFileScope)); + if (isFileScope) + if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr)) + for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) { + Expr *Init = ILE->getInit(i); + ILE->setInit(i, ConstantExpr::Create(Context, Init)); + } + + Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + VK, LiteralExpr, isFileScope); + if (isFileScope) { + if (!LiteralExpr->isTypeDependent() && + !LiteralExpr->isValueDependent() && + !literalType->isDependentType()) // C99 6.5.2.5p3 + if (CheckForConstantInitializer(LiteralExpr, literalType)) + return ExprError(); + } else if (literalType.getAddressSpace() != LangAS::opencl_private && + literalType.getAddressSpace() != LangAS::Default) { + // Embedded-C extensions to C99 6.5.2.5: + // "If the compound literal occurs inside the body of a function, the + // type name shall not be qualified by an address-space qualifier." + Diag(LParenLoc, diag::err_compound_literal_with_address_space) + << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd()); + return ExprError(); + } + + return MaybeBindToTemporary(E); } ExprResult @@ -5862,6 +5988,8 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { LangAS DestAS = DestTy->getPointeeType().getAddressSpace(); if (SrcAS != DestAS) return CK_AddressSpaceConversion; + if (Context.hasCvrSimilarType(SrcTy, DestTy)) + return CK_NoOp; return CK_BitCast; } case Type::STK_BlockPointer: @@ -5882,10 +6010,33 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_FloatingComplex: case Type::STK_IntegralComplex: case Type::STK_MemberPointer: + case Type::STK_FixedPoint: llvm_unreachable("illegal cast from pointer"); } llvm_unreachable("Should have returned before this"); + case Type::STK_FixedPoint: + switch (DestTy->getScalarTypeKind()) { + case Type::STK_FixedPoint: + return CK_FixedPointCast; + case Type::STK_Bool: + return CK_FixedPointToBoolean; + case Type::STK_Integral: + case Type::STK_Floating: + case Type::STK_IntegralComplex: + case Type::STK_FloatingComplex: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << DestTy; + return CK_IntegralCast; + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: + case Type::STK_MemberPointer: + llvm_unreachable("illegal cast to pointer type"); + } + llvm_unreachable("Should have returned before this"); + case Type::STK_Bool: // casting from bool is like casting from an integer case Type::STK_Integral: switch (DestTy->getScalarTypeKind()) { @@ -5914,6 +6065,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { return CK_FloatingRealToComplex; case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); @@ -5941,6 +6097,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { llvm_unreachable("valid float->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); @@ -5970,6 +6131,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { llvm_unreachable("valid complex float->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); @@ -5999,6 +6165,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { llvm_unreachable("valid complex int->pointer cast?"); case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); + case Type::STK_FixedPoint: + Diag(Src.get()->getExprLoc(), + diag::err_unimplemented_conversion_with_fixed_point_type) + << SrcTy; + return CK_IntegralCast; } llvm_unreachable("Should have returned before this"); } @@ -6331,8 +6502,7 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) { ExprResult Sema::ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val) { - Expr *expr = new (Context) ParenListExpr(Context, L, Val, R); - return expr; + return ParenListExpr::Create(Context, L, Val, R); } /// Emit a specialized diagnostic when one expression is a null pointer @@ -7762,7 +7932,12 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, if (isa<PointerType>(RHSType)) { LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace(); LangAS AddrSpaceR = RHSType->getPointeeType().getAddressSpace(); - Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast; + if (AddrSpaceL != AddrSpaceR) + Kind = CK_AddressSpaceConversion; + else if (Context.hasCvrSimilarType(RHSType, LHSType)) + Kind = CK_NoOp; + else + Kind = CK_BitCast; return checkPointerTypesForAssignment(*this, LHSType, RHSType); } @@ -7830,7 +8005,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, } // id -> T^ - if (getLangOpts().ObjC1 && RHSType->isObjCIdType()) { + if (getLangOpts().ObjC && RHSType->isObjCIdType()) { Kind = CK_AnyPointerToBlockPointerCast; return Compatible; } @@ -8034,6 +8209,17 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, ExprResult LocalRHS = CallerRHS; ExprResult &RHS = ConvertRHS ? CallerRHS : LocalRHS; + if (const auto *LHSPtrType = LHSType->getAs<PointerType>()) { + if (const auto *RHSPtrType = RHS.get()->getType()->getAs<PointerType>()) { + if (RHSPtrType->getPointeeType()->hasAttr(attr::NoDeref) && + !LHSPtrType->getPointeeType()->hasAttr(attr::NoDeref)) { + Diag(RHS.get()->getExprLoc(), + diag::warn_noderef_to_dereferenceable_pointer) + << RHS.get()->getSourceRange(); + } + } + } + if (getLangOpts().CPlusPlus) { if (!LHSType->isRecordType() && !LHSType->isAtomicType()) { // C++ 5.17p3: If the left operand is not of class type, the @@ -8139,7 +8325,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, if (!Diagnose) return Incompatible; } - if (getLangOpts().ObjC1 && + if (getLangOpts().ObjC && (CheckObjCBridgeRelatedConversions(E->getBeginLoc(), LHSType, E->getType(), E, Diagnose) || ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) { @@ -8154,6 +8340,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS, if (ConvertRHS) RHS = ImpCastExprToType(E, Ty, Kind); } + return result; } @@ -8316,8 +8503,8 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, // Reject cases where the value of the Int is unknown as that would // possibly cause truncation, but accept cases where the scalar can be // demoted without loss of precision. - llvm::APSInt Result; - bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context); + Expr::EvalResult EVResult; + bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context); int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy); bool IntSigned = IntTy->hasSignedIntegerRepresentation(); bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation(); @@ -8325,6 +8512,7 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int, if (CstInt) { // If the scalar is constant and is of a higher order and has more active // bits that the vector element type, reject it. + llvm::APSInt Result = EVResult.Val.getInt(); unsigned NumBits = IntSigned ? (Result.isNegative() ? Result.getMinSignedBits() : Result.getActiveBits()) @@ -8352,8 +8540,9 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // Determine if the integer constant can be expressed as a floating point // number of the appropriate type. - llvm::APSInt Result; - bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context); + Expr::EvalResult EVResult; + bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context); + uint64_t Bits = 0; if (CstInt) { // Reject constants that would be truncated if they were converted to @@ -8361,6 +8550,7 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int, // FIXME: Ideally the conversion to an APFloat and from an APFloat // could be avoided if there was a convertFromAPInt method // which could signal back if implicit truncation occurred. + llvm::APSInt Result = EVResult.Val.getInt(); llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy)); Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(), llvm::APFloat::rmTowardZero); @@ -8670,13 +8860,40 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS, << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); } +static void DiagnoseDivisionSizeofPointer(Sema &S, Expr *LHS, Expr *RHS, + SourceLocation Loc) { + const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS); + const auto *RUE = dyn_cast<UnaryExprOrTypeTraitExpr>(RHS); + if (!LUE || !RUE) + return; + if (LUE->getKind() != UETT_SizeOf || LUE->isArgumentType() || + RUE->getKind() != UETT_SizeOf) + return; + + QualType LHSTy = LUE->getArgumentExpr()->IgnoreParens()->getType(); + QualType RHSTy; + + if (RUE->isArgumentType()) + RHSTy = RUE->getArgumentType(); + else + RHSTy = RUE->getArgumentExpr()->IgnoreParens()->getType(); + + if (!LHSTy->isPointerType() || RHSTy->isPointerType()) + return; + if (LHSTy->getPointeeType() != RHSTy) + return; + + S.Diag(Loc, diag::warn_division_sizeof_ptr) << LHS << LHS->getSourceRange(); +} + static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsDiv) { // Check for division/remainder by zero. - llvm::APSInt RHSValue; + Expr::EvalResult RHSValue; if (!RHS.get()->isValueDependent() && - RHS.get()->EvaluateAsInt(RHSValue, S.Context) && RHSValue == 0) + RHS.get()->EvaluateAsInt(RHSValue, S.Context) && + RHSValue.Val.getInt() == 0) S.DiagRuntimeBehavior(Loc, RHS.get(), S.PDiag(diag::warn_remainder_division_by_zero) << IsDiv << RHS.get()->getSourceRange()); @@ -8700,8 +8917,10 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, if (compType.isNull() || !compType->isArithmeticType()) return InvalidOperands(Loc, LHS, RHS); - if (IsDiv) + if (IsDiv) { DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv); + DiagnoseDivisionSizeofPointer(*this, LHS.get(), RHS.get(), Loc); + } return compType; } @@ -8916,8 +9135,9 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, if (!IsStringPlusInt || IndexExpr->isValueDependent()) return; - llvm::APSInt index; - if (IndexExpr->EvaluateAsInt(index, Self.getASTContext())) { + Expr::EvalResult Result; + if (IndexExpr->EvaluateAsInt(Result, Self.getASTContext())) { + llvm::APSInt index = Result.Val.getInt(); unsigned StrLenWithNull = StrExpr->getLength() + 1; if (index.isNonNegative() && index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull), @@ -9061,10 +9281,11 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS, if (PExp->IgnoreParenCasts()->isNullPointerConstant( Context, Expr::NPC_ValueDependentIsNotNull)) { // In C++ adding zero to a null pointer is defined. - llvm::APSInt KnownVal; + Expr::EvalResult KnownVal; if (!getLangOpts().CPlusPlus || (!IExp->isValueDependent() && - (!IExp->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) { + (!IExp->EvaluateAsInt(KnownVal, Context) || + KnownVal.Val.getInt() != 0))) { // Check the conditions to see if this is the 'p = nullptr + n' idiom. bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension( Context, BO_Add, PExp, IExp); @@ -9139,10 +9360,11 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) { // In C++ adding zero to a null pointer is defined. - llvm::APSInt KnownVal; + Expr::EvalResult KnownVal; if (!getLangOpts().CPlusPlus || (!RHS.get()->isValueDependent() && - (!RHS.get()->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) { + (!RHS.get()->EvaluateAsInt(KnownVal, Context) || + KnownVal.Val.getInt() != 0))) { diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false); } } @@ -9218,11 +9440,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, if (S.getLangOpts().OpenCL) return; - llvm::APSInt Right; // Check right/shifter operand + Expr::EvalResult RHSResult; if (RHS.get()->isValueDependent() || - !RHS.get()->EvaluateAsInt(Right, S.Context)) + !RHS.get()->EvaluateAsInt(RHSResult, S.Context)) return; + llvm::APSInt Right = RHSResult.Val.getInt(); if (Right.isNegative()) { S.DiagRuntimeBehavior(Loc, RHS.get(), @@ -9245,11 +9468,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, // according to C++ has undefined behavior ([expr.shift] 5.8/2). Unsigned // integers have defined behavior modulo one more than the maximum value // representable in the result type, so never warn for those. - llvm::APSInt Left; + Expr::EvalResult LHSResult; if (LHS.get()->isValueDependent() || LHSType->hasUnsignedIntegerRepresentation() || - !LHS.get()->EvaluateAsInt(Left, S.Context)) + !LHS.get()->EvaluateAsInt(LHSResult, S.Context)) return; + llvm::APSInt Left = LHSResult.Val.getInt(); // If LHS does not have a signed type and non-negative value // then, the behavior is undefined. Warn about it. @@ -10441,6 +10665,10 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, } if (getLangOpts().OpenCLVersion >= 200) { + if (LHSType->isClkEventT() && RHSType->isClkEventT()) { + return computeResultTy(); + } + if (LHSType->isQueueT() && RHSType->isQueueT()) { return computeResultTy(); } @@ -10615,8 +10843,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, // that isn't 0 or 1 (which indicate a potential logical operation that // happened to fold to true/false) then warn. // Parens on the RHS are ignored. - llvm::APSInt Result; - if (RHS.get()->EvaluateAsInt(Result, Context)) + Expr::EvalResult EVResult; + if (RHS.get()->EvaluateAsInt(EVResult, Context)) { + llvm::APSInt Result = EVResult.Val.getInt(); if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() && !RHS.get()->getExprLoc().isMacroID()) || (Result != 0 && Result != 1)) { @@ -10636,6 +10865,7 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS, SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()), RHS.get()->getEndLoc())); } + } } if (!Context.getLangOpts().CPlusPlus) { @@ -10886,30 +11116,38 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD, const RecordType *Ty, SourceLocation Loc, SourceRange Range, OriginalExprKind OEK, - bool &DiagnosticEmitted, - bool IsNested = false) { + bool &DiagnosticEmitted) { + std::vector<const RecordType *> RecordTypeList; + RecordTypeList.push_back(Ty); + unsigned NextToCheckIndex = 0; // We walk the record hierarchy breadth-first to ensure that we print // diagnostics in field nesting order. - // First, check every field for constness. - for (const FieldDecl *Field : Ty->getDecl()->fields()) { - if (Field->getType().isConstQualified()) { - if (!DiagnosticEmitted) { - S.Diag(Loc, diag::err_typecheck_assign_const) - << Range << NestedConstMember << OEK << VD - << IsNested << Field; - DiagnosticEmitted = true; + while (RecordTypeList.size() > NextToCheckIndex) { + bool IsNested = NextToCheckIndex > 0; + for (const FieldDecl *Field : + RecordTypeList[NextToCheckIndex]->getDecl()->fields()) { + // First, check every field for constness. + QualType FieldTy = Field->getType(); + if (FieldTy.isConstQualified()) { + if (!DiagnosticEmitted) { + S.Diag(Loc, diag::err_typecheck_assign_const) + << Range << NestedConstMember << OEK << VD + << IsNested << Field; + DiagnosticEmitted = true; + } + S.Diag(Field->getLocation(), diag::note_typecheck_assign_const) + << NestedConstMember << IsNested << Field + << FieldTy << Field->getSourceRange(); + } + + // Then we append it to the list to check next in order. + FieldTy = FieldTy.getCanonicalType(); + if (const auto *FieldRecTy = FieldTy->getAs<RecordType>()) { + if (llvm::find(RecordTypeList, FieldRecTy) == RecordTypeList.end()) + RecordTypeList.push_back(FieldRecTy); } - S.Diag(Field->getLocation(), diag::note_typecheck_assign_const) - << NestedConstMember << IsNested << Field - << Field->getType() << Field->getSourceRange(); } - } - // Then, recurse. - for (const FieldDecl *Field : Ty->getDecl()->fields()) { - QualType FTy = Field->getType(); - if (const RecordType *FieldRecTy = FTy->getAs<RecordType>()) - DiagnoseRecursiveConstFields(S, VD, FieldRecTy, Loc, Range, - OEK, DiagnosticEmitted, true); + ++NextToCheckIndex; } } @@ -11230,6 +11468,12 @@ static bool IgnoreCommaOperand(const Expr *E) { if (CE->getCastKind() == CK_ToVoid) { return true; } + + // static_cast<void> on a dependent type will not show up as CK_ToVoid. + if (CE->getCastKind() == CK_Dependent && E->getType()->isVoidType() && + CE->getSubExpr()->getType()->isDependentType()) { + return true; + } } return false; @@ -11253,8 +11497,11 @@ void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) { // The whitelisted locations are the initialization and increment portions // of a for loop. The additional checks are on the condition of // if statements, do/while loops, and for loops. + // Differences in scope flags for C89 mode requires the extra logic. const unsigned ForIncrementFlags = - Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope; + getLangOpts().C99 || getLangOpts().CPlusPlus + ? Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope + : Scope::ContinueScope | Scope::BreakScope; const unsigned ForInitFlags = Scope::ControlScope | Scope::DeclScope; const unsigned ScopeFlags = getCurScope()->getFlags(); if ((ScopeFlags & ForIncrementFlags) == ForIncrementFlags || @@ -11882,7 +12129,7 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr, /// is usually indicative of introspection within the Objective-C pointer. static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R, SourceLocation OpLoc) { - if (!S.getLangOpts().ObjC1) + if (!S.getLangOpts().ObjC) return; const Expr *ObjCPointerExpr = nullptr, *OtherExpr = nullptr; @@ -12650,6 +12897,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, break; case UO_AddrOf: resultType = CheckAddressOfOperand(Input, OpLoc); + CheckAddressOfNoDeref(InputExpr); RecordModifiableNonNullParam(*this, InputExpr); break; case UO_Deref: { @@ -12814,6 +13062,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, auto *UO = new (Context) UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow); + + if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) && + !isa<ArrayType>(UO->getType().getDesugaredType(Context))) + ExprEvalContexts.back().PossibleDerefs.insert(UO); + // Convert the result back to a half vector. if (ConvertHalfVec) return convertVector(UO, Context.HalfTy, *this); @@ -13301,7 +13554,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, // Drop the parameters. FunctionProtoType::ExtProtoInfo EPI; EPI.HasTrailingReturn = false; - EPI.TypeQuals |= DeclSpec::TQ_const; + EPI.TypeQuals.addConst(); T = Context.getFunctionType(Context.DependentTy, None, EPI); Sig = Context.getTrivialTypeSourceInfo(T); } @@ -13428,6 +13681,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, PopExpressionEvaluationContext(); BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back()); + BlockDecl *BD = BSI->TheDecl; if (BSI->HasImplicitReturnType) deduceClosureReturnType(*BSI); @@ -13438,7 +13692,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (!BSI->ReturnType.isNull()) RetTy = BSI->ReturnType; - bool NoReturn = BSI->TheDecl->hasAttr<NoReturnAttr>(); + bool NoReturn = BD->hasAttr<NoReturnAttr>(); QualType BlockTy; // Set the captured variables on the block. @@ -13451,7 +13705,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, Cap.isNested(), Cap.getInitExpr()); Captures.push_back(NewCap); } - BSI->TheDecl->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0); + BD->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0); // If the user wrote a function type in some form, try to use that. if (!BSI->FunctionType.isNull()) { @@ -13476,7 +13730,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, } else { const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - EPI.TypeQuals = 0; // FIXME: silently? + EPI.TypeQuals = Qualifiers(); EPI.ExtInfo = Ext; BlockTy = Context.getFunctionType(RetTy, FPT->getParamTypes(), EPI); } @@ -13488,7 +13742,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BlockTy = Context.getFunctionType(RetTy, None, EPI); } - DiagnoseUnusedParameters(BSI->TheDecl->parameters()); + DiagnoseUnusedParameters(BD->parameters()); BlockTy = Context.getBlockPointerType(BlockTy); // If needed, diagnose invalid gotos and switches in the block. @@ -13496,19 +13750,19 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, !PP.isCodeCompletionEnabled()) DiagnoseInvalidJumps(cast<CompoundStmt>(Body)); - BSI->TheDecl->setBody(cast<CompoundStmt>(Body)); + BD->setBody(cast<CompoundStmt>(Body)); if (Body && getCurFunction()->HasPotentialAvailabilityViolations) - DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl); + DiagnoseUnguardedAvailabilityViolations(BD); // Try to apply the named return value optimization. We have to check again // if we can do this, though, because blocks keep return statements around // to deduce an implicit return type. if (getLangOpts().CPlusPlus && RetTy->isRecordType() && - !BSI->TheDecl->isDependentContext()) + !BD->isDependentContext()) computeNRVO(Body, BSI); - BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); + BlockExpr *Result = new (Context) BlockExpr(BD, BlockTy); AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result); @@ -13530,6 +13784,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, } } + if (getCurFunction()) + getCurFunction()->addBlock(BD); + return Result; } @@ -13669,7 +13926,7 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp, bool Diagnose) { - if (!getLangOpts().ObjC1) + if (!getLangOpts().ObjC) return false; const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>(); @@ -14038,11 +14295,14 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, return ExprError(); } + if (!isa<ConstantExpr>(E)) + E = ConstantExpr::Create(Context, E); + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) - *Result = E->EvaluateKnownConstInt(Context); + *Result = E->EvaluateKnownConstIntCheckOverflow(Context); return E; } @@ -14173,6 +14433,51 @@ Sema::PushExpressionEvaluationContext( PushExpressionEvaluationContext(NewContext, ClosureContextDecl, ExprContext); } +namespace { + +const DeclRefExpr *CheckPossibleDeref(Sema &S, const Expr *PossibleDeref) { + PossibleDeref = PossibleDeref->IgnoreParenImpCasts(); + if (const auto *E = dyn_cast<UnaryOperator>(PossibleDeref)) { + if (E->getOpcode() == UO_Deref) + return CheckPossibleDeref(S, E->getSubExpr()); + } else if (const auto *E = dyn_cast<ArraySubscriptExpr>(PossibleDeref)) { + return CheckPossibleDeref(S, E->getBase()); + } else if (const auto *E = dyn_cast<MemberExpr>(PossibleDeref)) { + return CheckPossibleDeref(S, E->getBase()); + } else if (const auto E = dyn_cast<DeclRefExpr>(PossibleDeref)) { + QualType Inner; + QualType Ty = E->getType(); + if (const auto *Ptr = Ty->getAs<PointerType>()) + Inner = Ptr->getPointeeType(); + else if (const auto *Arr = S.Context.getAsArrayType(Ty)) + Inner = Arr->getElementType(); + else + return nullptr; + + if (Inner->hasAttr(attr::NoDeref)) + return E; + } + return nullptr; +} + +} // namespace + +void Sema::WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec) { + for (const Expr *E : Rec.PossibleDerefs) { + const DeclRefExpr *DeclRef = CheckPossibleDeref(*this, E); + if (DeclRef) { + const ValueDecl *Decl = DeclRef->getDecl(); + Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type) + << Decl->getName() << E->getSourceRange(); + Diag(Decl->getLocation(), diag::note_previous_decl) << Decl->getName(); + } else { + Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type_no_decl) + << E->getSourceRange(); + } + } + Rec.PossibleDerefs.clear(); +} + void Sema::PopExpressionEvaluationContext() { ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); unsigned NumTypos = Rec.NumTypos; @@ -14212,6 +14517,8 @@ void Sema::PopExpressionEvaluationContext() { } } + WarnOnPendingNoDerefs(Rec); + // When are coming out of an unevaluated context, clear out any // temporaries that we may have created as part of the evaluation of // the expression in that context: they aren't relevant because they @@ -14232,11 +14539,8 @@ void Sema::PopExpressionEvaluationContext() { // Pop the current expression evaluation context off the stack. ExprEvalContexts.pop_back(); - if (!ExprEvalContexts.empty()) - ExprEvalContexts.back().NumTypos += NumTypos; - else - assert(NumTypos == 0 && "There are outstanding typos after popping the " - "last ExpressionEvaluationContextRecord"); + // The global expression evaluation context record is never popped. + ExprEvalContexts.back().NumTypos += NumTypos; } void Sema::DiscardCleanupsInEvaluationContext() { @@ -14838,6 +15142,21 @@ static void addAsFieldToClosureType(Sema &S, LambdaScopeInfo *LSI, = FieldDecl::Create(S.Context, Lambda, Loc, Loc, nullptr, FieldType, S.Context.getTrivialTypeSourceInfo(FieldType, Loc), nullptr, false, ICIS_NoInit); + // If the variable being captured has an invalid type, mark the lambda class + // as invalid as well. + if (!FieldType->isDependentType()) { + if (S.RequireCompleteType(Loc, FieldType, diag::err_field_incomplete)) { + Lambda->setInvalidDecl(); + Field->setInvalidDecl(); + } else { + NamedDecl *Def; + FieldType->isIncompleteType(&Def); + if (Def && Def->isInvalidDecl()) { + Lambda->setInvalidDecl(); + Field->setInvalidDecl(); + } + } + } Field->setImplicit(true); Field->setAccess(AS_private); Lambda->addDecl(Field); @@ -16468,6 +16787,9 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: #include "clang/Basic/OpenCLImageTypes.def" +#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ + case BuiltinType::Id: +#include "clang/Basic/OpenCLExtensionTypes.def" #define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id: #define PLACEHOLDER_TYPE(Id, SingletonId) #include "clang/AST/BuiltinTypes.def" diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index dd5dfaacf2..2b054c4b0f 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1094,7 +1094,7 @@ QualType Sema::getCurrentThisType() { Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, Decl *ContextDecl, - unsigned CXXThisTypeQuals, + Qualifiers CXXThisTypeQuals, bool Enabled) : S(S), OldCXXThisTypeOverride(S.CXXThisTypeOverride), Enabled(false) { @@ -1107,11 +1107,10 @@ Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S, else Record = cast<CXXRecordDecl>(ContextDecl); - // We care only for CVR qualifiers here, so cut everything else. - CXXThisTypeQuals &= Qualifiers::FastMask; - S.CXXThisTypeOverride - = S.Context.getPointerType( - S.Context.getRecordType(Record).withCVRQualifiers(CXXThisTypeQuals)); + QualType T = S.Context.getRecordType(Record); + T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals); + + S.CXXThisTypeOverride = S.Context.getPointerType(T); this->Enabled = true; } @@ -2816,9 +2815,10 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, // Global allocation functions should always be visible. Alloc->setVisibleDespiteOwningModule(); - // Implicit sized deallocation functions always have default visibility. - Alloc->addAttr( - VisibilityAttr::CreateImplicit(Context, VisibilityAttr::Default)); + Alloc->addAttr(VisibilityAttr::CreateImplicit( + Context, LangOpts.GlobalAllocationFunctionVisibilityHidden + ? VisibilityAttr::Hidden + : VisibilityAttr::Default)); llvm::SmallVector<ParmVarDecl *, 3> ParamDecls; for (QualType T : Params) { @@ -4236,14 +4236,9 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } case ICK_Zero_Event_Conversion: - From = ImpCastExprToType(From, ToType, - CK_ZeroToOCLEvent, - From->getValueKind()).get(); - break; - case ICK_Zero_Queue_Conversion: From = ImpCastExprToType(From, ToType, - CK_ZeroToOCLQueue, + CK_ZeroToOCLOpaqueType, From->getValueKind()).get(); break; @@ -4276,10 +4271,24 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Qualification: { // The qualification keeps the category of the inner expression, unless the // target type isn't a reference. - ExprValueKind VK = ToType->isReferenceType() ? - From->getValueKind() : VK_RValue; - From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), - CK_NoOp, VK, /*BasePath=*/nullptr, CCK).get(); + ExprValueKind VK = + ToType->isReferenceType() ? From->getValueKind() : VK_RValue; + + CastKind CK = CK_NoOp; + + if (ToType->isReferenceType() && + ToType->getPointeeType().getAddressSpace() != + From->getType().getAddressSpace()) + CK = CK_AddressSpaceConversion; + + if (ToType->isPointerType() && + ToType->getPointeeType().getAddressSpace() != + From->getType()->getPointeeType().getAddressSpace()) + CK = CK_AddressSpaceConversion; + + From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK, VK, + /*BasePath=*/nullptr, CCK) + .get(); if (SCS.DeprecatedStringLiteralToCharPtr && !getLangOpts().WritableStrings) { @@ -7764,41 +7773,24 @@ Sema::CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl, ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, bool DiscardedValue, - bool IsConstexpr, - bool IsLambdaInitCaptureInitializer) { + bool IsConstexpr) { ExprResult FullExpr = FE; if (!FullExpr.get()) return ExprError(); - // If we are an init-expression in a lambdas init-capture, we should not - // diagnose an unexpanded pack now (will be diagnosed once lambda-expr - // containing full-expression is done). - // template<class ... Ts> void test(Ts ... t) { - // test([&a(t)]() { <-- (t) is an init-expr that shouldn't be diagnosed now. - // return a; - // }() ...); - // } - // FIXME: This is a hack. It would be better if we pushed the lambda scope - // when we parse the lambda introducer, and teach capturing (but not - // unexpanded pack detection) to walk over LambdaScopeInfos which don't have a - // corresponding class yet (that is, have LambdaScopeInfo either represent a - // lambda where we've entered the introducer but not the body, or represent a - // lambda where we've entered the body, depending on where the - // parser/instantiation has got to). - if (!IsLambdaInitCaptureInitializer && - DiagnoseUnexpandedParameterPack(FullExpr.get())) + if (DiagnoseUnexpandedParameterPack(FullExpr.get())) return ExprError(); - // Top-level expressions default to 'id' when we're in a debugger. - if (DiscardedValue && getLangOpts().DebuggerCastResultToId && - FullExpr.get()->getType() == Context.UnknownAnyTy) { - FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType()); - if (FullExpr.isInvalid()) - return ExprError(); - } - if (DiscardedValue) { + // Top-level expressions default to 'id' when we're in a debugger. + if (getLangOpts().DebuggerCastResultToId && + FullExpr.get()->getType() == Context.UnknownAnyTy) { + FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType()); + if (FullExpr.isInvalid()) + return ExprError(); + } + FullExpr = CheckPlaceholderExpr(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index e6d2b5068f..b2b21ba9ee 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -496,7 +496,7 @@ Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, // allows this, while still reporting an error if T is a struct pointer. if (!IsArrow) { const PointerType *PT = BaseType->getAs<PointerType>(); - if (PT && (!getLangOpts().ObjC1 || + if (PT && (!getLangOpts().ObjC || PT->getPointeeType()->isRecordType())) { assert(BaseExpr && "cannot happen with implicit member accesses"); Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) @@ -1708,9 +1708,31 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, } ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl}; - return BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS, - TemplateKWLoc, FirstQualifierInScope, - NameInfo, TemplateArgs, S, &ExtraArgs); + ExprResult Res = BuildMemberReferenceExpr( + Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc, + FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs); + + if (!Res.isInvalid() && isa<MemberExpr>(Res.get())) + CheckMemberAccessOfNoDeref(cast<MemberExpr>(Res.get())); + + return Res; +} + +void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) { + QualType ResultTy = E->getType(); + + // Do not warn on member accesses to arrays since this returns an array + // lvalue and does not actually dereference memory. + if (isa<ArrayType>(ResultTy)) + return; + + if (E->isArrow()) { + if (const auto *Ptr = dyn_cast<PointerType>( + E->getBase()->getType().getDesugaredType(Context))) { + if (Ptr->getPointeeType()->hasAttr(attr::NoDeref)) + ExprEvalContexts.back().PossibleDerefs.insert(E); + } + } } ExprResult diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index bee75e4ae6..9eaf747ae7 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -3892,7 +3892,7 @@ static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr, } void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) { - if (!getLangOpts().ObjC1) + if (!getLangOpts().ObjC) return; // warn in presence of __bridge casting to or from a toll free bridge cast. ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType()); @@ -3964,7 +3964,7 @@ void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) { bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr, CastKind &Kind) { - if (!getLangOpts().ObjC1) + if (!getLangOpts().ObjC) return false; ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType()); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 958dd66612..57277f6e82 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1192,6 +1192,10 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, if (!VerifyOnly) SemaRef.Diag(IList->getBeginLoc(), diag::err_init_objc_class) << DeclType; hadError = true; + } else if (DeclType->isOCLIntelSubgroupAVCType()) { + // Checks for scalar type are sufficient for these types too. + CheckScalarType(Entity, IList, DeclType, Index, StructuredList, + StructuredIndex); } else { if (!VerifyOnly) SemaRef.Diag(IList->getBeginLoc(), diag::err_illegal_initializer_type) @@ -3261,8 +3265,7 @@ void InitializationSequence::Step::Destroy() { case SK_StdInitializerList: case SK_StdInitializerListConstructorCall: case SK_OCLSamplerInit: - case SK_OCLZeroEvent: - case SK_OCLZeroQueue: + case SK_OCLZeroOpaqueType: break; case SK_ConversionSequence: @@ -3548,16 +3551,9 @@ void InitializationSequence::AddOCLSamplerInitStep(QualType T) { Steps.push_back(S); } -void InitializationSequence::AddOCLZeroEventStep(QualType T) { - Step S; - S.Kind = SK_OCLZeroEvent; - S.Type = T; - Steps.push_back(S); -} - -void InitializationSequence::AddOCLZeroQueueStep(QualType T) { +void InitializationSequence::AddOCLZeroOpaqueTypeStep(QualType T) { Step S; - S.Kind = SK_OCLZeroQueue; + S.Kind = SK_OCLZeroOpaqueType; S.Type = T; Steps.push_back(S); } @@ -4885,6 +4881,13 @@ static void TryDefaultInitialization(Sema &S, return; } + // As an extension, and to fix Core issue 1013, zero initialize nullptr_t. + // Since there is only 1 valid value of nullptr_t, we can just use that. + if (DestType->isNullPtrType()) { + Sequence.AddZeroInitializationStep(Entity.getType()); + return; + } + // - otherwise, no initialization is performed. // If a program calls for the default initialization of an object of @@ -5260,39 +5263,51 @@ static bool TryOCLSamplerInitialization(Sema &S, return true; } -// -// OpenCL 1.2 spec, s6.12.10 -// -// The event argument can also be used to associate the -// async_work_group_copy with a previous async copy allowing -// an event to be shared by multiple async copies; otherwise -// event should be zero. -// -static bool TryOCLZeroEventInitialization(Sema &S, - InitializationSequence &Sequence, - QualType DestType, - Expr *Initializer) { - if (!S.getLangOpts().OpenCL || !DestType->isEventT() || - !Initializer->isIntegerConstantExpr(S.getASTContext()) || - (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0)) - return false; - - Sequence.AddOCLZeroEventStep(DestType); - return true; +static bool IsZeroInitializer(Expr *Initializer, Sema &S) { + return Initializer->isIntegerConstantExpr(S.getASTContext()) && + (Initializer->EvaluateKnownConstInt(S.getASTContext()) == 0); } -static bool TryOCLZeroQueueInitialization(Sema &S, - InitializationSequence &Sequence, - QualType DestType, - Expr *Initializer) { - if (!S.getLangOpts().OpenCL || S.getLangOpts().OpenCLVersion < 200 || - !DestType->isQueueT() || - !Initializer->isIntegerConstantExpr(S.getASTContext()) || - (Initializer->EvaluateKnownConstInt(S.getASTContext()) != 0)) +static bool TryOCLZeroOpaqueTypeInitialization(Sema &S, + InitializationSequence &Sequence, + QualType DestType, + Expr *Initializer) { + if (!S.getLangOpts().OpenCL) return false; - Sequence.AddOCLZeroQueueStep(DestType); - return true; + // + // OpenCL 1.2 spec, s6.12.10 + // + // The event argument can also be used to associate the + // async_work_group_copy with a previous async copy allowing + // an event to be shared by multiple async copies; otherwise + // event should be zero. + // + if (DestType->isEventT() || DestType->isQueueT()) { + if (!IsZeroInitializer(Initializer, S)) + return false; + + Sequence.AddOCLZeroOpaqueTypeStep(DestType); + return true; + } + + // We should allow zero initialization for all types defined in the + // cl_intel_device_side_avc_motion_estimation extension, except + // intel_sub_group_avc_mce_payload_t and intel_sub_group_avc_mce_result_t. + if (S.getOpenCLOptions().isEnabled( + "cl_intel_device_side_avc_motion_estimation") && + DestType->isOCLIntelSubgroupAVCType()) { + if (DestType->isOCLIntelSubgroupAVCMcePayloadType() || + DestType->isOCLIntelSubgroupAVCMceResultType()) + return false; + if (!IsZeroInitializer(Initializer, S)) + return false; + + Sequence.AddOCLZeroOpaqueTypeStep(DestType); + return true; + } + + return false; } InitializationSequence::InitializationSequence(Sema &S, @@ -5397,7 +5412,7 @@ void InitializationSequence::InitializeFrom(Sema &S, Expr *Initializer = nullptr; if (Args.size() == 1) { Initializer = Args[0]; - if (S.getLangOpts().ObjC1) { + if (S.getLangOpts().ObjC) { if (S.CheckObjCBridgeRelatedConversions(Initializer->getBeginLoc(), DestType, Initializer->getType(), Initializer) || @@ -5519,7 +5534,8 @@ void InitializationSequence::InitializeFrom(Sema &S, // array from a compound literal that creates an array of the same // type, so long as the initializer has no side effects. if (!S.getLangOpts().CPlusPlus && Initializer && - isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) && + (isa<ConstantExpr>(Initializer->IgnoreParens()) || + isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) && Initializer->getType()->isArrayType()) { const ArrayType *SourceAT = Context.getAsArrayType(Initializer->getType()); @@ -5566,12 +5582,9 @@ void InitializationSequence::InitializeFrom(Sema &S, if (TryOCLSamplerInitialization(S, *this, DestType, Initializer)) return; - if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer)) + if (TryOCLZeroOpaqueTypeInitialization(S, *this, DestType, Initializer)) return; - if (TryOCLZeroQueueInitialization(S, *this, DestType, Initializer)) - return; - // Handle initialization in C AddCAssignmentStep(DestType); MaybeProduceObjCObject(S, *this, Entity); @@ -6180,7 +6193,10 @@ PerformConstructorInitialization(Sema &S, TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo(); if (!TSInfo) TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc); - SourceRange ParenOrBraceRange = Kind.getParenOrBraceRange(); + SourceRange ParenOrBraceRange = + (Kind.getKind() == InitializationKind::IK_DirectList) + ? SourceRange(LBraceLoc, RBraceLoc) + : Kind.getParenOrBraceRange(); if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>( Step.Function.FoundDecl.getDecl())) { @@ -6441,7 +6457,7 @@ static bool isVarOnPath(IndirectLocalPath &Path, VarDecl *VD) { } static bool pathContainsInit(IndirectLocalPath &Path) { - return std::any_of(Path.begin(), Path.end(), [=](IndirectLocalPathEntry E) { + return llvm::any_of(Path, [=](IndirectLocalPathEntry E) { return E.Kind == IndirectLocalPathEntry::DefaultInit || E.Kind == IndirectLocalPathEntry::VarInit; }); @@ -6529,8 +6545,8 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, do { Old = Init; - if (auto *EWC = dyn_cast<ExprWithCleanups>(Init)) - Init = EWC->getSubExpr(); + if (auto *FE = dyn_cast<FullExpr>(Init)) + Init = FE->getSubExpr(); if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) { // If this is just redundant braces around an initializer, step over it. @@ -6653,8 +6669,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, Init = DIE->getExpr(); } - if (auto *EWC = dyn_cast<ExprWithCleanups>(Init)) - Init = EWC->getSubExpr(); + if (auto *FE = dyn_cast<FullExpr>(Init)) + Init = FE->getSubExpr(); // Dig out the expression which constructs the extended temporary. Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments()); @@ -6786,6 +6802,20 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path, return; } + // The lifetime of an init-capture is that of the closure object constructed + // by a lambda-expression. + if (auto *LE = dyn_cast<LambdaExpr>(Init)) { + for (Expr *E : LE->capture_inits()) { + if (!E) + continue; + if (E->isGLValue()) + visitLocalsRetainedByReferenceBinding(Path, E, RK_ReferenceBinding, + Visit); + else + visitLocalsRetainedByInitializer(Path, E, Visit, true); + } + } + if (isa<CallExpr>(Init) || isa<CXXConstructExpr>(Init)) return visitLifetimeBoundArguments(Path, Init, Visit); @@ -7238,12 +7268,20 @@ ExprResult Sema::TemporaryMaterializationConversion(Expr *E) { return CreateMaterializeTemporaryExpr(E->getType(), E, false); } -ExprResult -InitializationSequence::Perform(Sema &S, - const InitializedEntity &Entity, - const InitializationKind &Kind, - MultiExprArg Args, - QualType *ResultType) { +ExprResult Sema::PerformQualificationConversion(Expr *E, QualType Ty, + ExprValueKind VK, + CheckedConversionKind CCK) { + CastKind CK = (Ty.getAddressSpace() != E->getType().getAddressSpace()) + ? CK_AddressSpaceConversion + : CK_NoOp; + return ImpCastExprToType(E, Ty, CK, VK, /*BasePath=*/nullptr, CCK); +} + +ExprResult InitializationSequence::Perform(Sema &S, + const InitializedEntity &Entity, + const InitializationKind &Kind, + MultiExprArg Args, + QualType *ResultType) { if (Failed()) { Diagnose(S, Entity, Kind, Args); return ExprError(); @@ -7393,8 +7431,7 @@ InitializationSequence::Perform(Sema &S, case SK_ProduceObjCObject: case SK_StdInitializerList: case SK_OCLSamplerInit: - case SK_OCLZeroEvent: - case SK_OCLZeroQueue: { + case SK_OCLZeroOpaqueType: { assert(Args.size() == 1); CurInit = Args[0]; if (!CurInit.get()) return ExprError(); @@ -7632,12 +7669,11 @@ InitializationSequence::Perform(Sema &S, case SK_QualificationConversionRValue: { // Perform a qualification conversion; these can never go wrong. ExprValueKind VK = - Step->Kind == SK_QualificationConversionLValue ? - VK_LValue : - (Step->Kind == SK_QualificationConversionXValue ? - VK_XValue : - VK_RValue); - CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK); + Step->Kind == SK_QualificationConversionLValue + ? VK_LValue + : (Step->Kind == SK_QualificationConversionXValue ? VK_XValue + : VK_RValue); + CurInit = S.PerformQualificationConversion(CurInit.get(), Step->Type, VK); break; } @@ -7658,6 +7694,18 @@ InitializationSequence::Perform(Sema &S, case SK_ConversionSequence: case SK_ConversionSequenceNoNarrowing: { + if (const auto *FromPtrType = + CurInit.get()->getType()->getAs<PointerType>()) { + if (const auto *ToPtrType = Step->Type->getAs<PointerType>()) { + if (FromPtrType->getPointeeType()->hasAttr(attr::NoDeref) && + !ToPtrType->getPointeeType()->hasAttr(attr::NoDeref)) { + S.Diag(CurInit.get()->getExprLoc(), + diag::warn_noderef_to_dereferenceable_pointer) + << CurInit.get()->getSourceRange(); + } + } + } + Sema::CheckedConversionKind CCK = Kind.isCStyleCast()? Sema::CCK_CStyleCast : Kind.isFunctionalCast()? Sema::CCK_FunctionalCast @@ -7824,6 +7872,7 @@ InitializationSequence::Perform(Sema &S, case SK_CAssignment: { QualType SourceType = CurInit.get()->getType(); + // Save off the initial CurInit in case we need to emit a diagnostic ExprResult InitialCurInit = CurInit; ExprResult Result = CurInit; @@ -7959,7 +8008,7 @@ InitializationSequence::Perform(Sema &S, } case SK_OCLSamplerInit: { - // Sampler initialzation have 5 cases: + // Sampler initialization have 5 cases: // 1. function argument passing // 1a. argument is a file-scope variable // 1b. argument is a function-scope variable @@ -8021,8 +8070,9 @@ InitializationSequence::Perform(Sema &S, break; } - llvm::APSInt Result; - Init->EvaluateAsInt(Result, S.Context); + Expr::EvalResult EVResult; + Init->EvaluateAsInt(EVResult, S.Context); + llvm::APSInt Result = EVResult.Val.getInt(); const uint64_t SamplerValue = Result.getLimitedValue(); // 32-bit value of sampler's initializer is interpreted as // bit-field with the following structure: @@ -8032,7 +8082,9 @@ InitializationSequence::Perform(Sema &S, // defined in SPIR spec v1.2 and also opencl-c.h unsigned AddressingMode = (0x0E & SamplerValue) >> 1; unsigned FilterMode = (0x30 & SamplerValue) >> 4; - if (FilterMode != 1 && FilterMode != 2) + if (FilterMode != 1 && FilterMode != 2 && + !S.getOpenCLOptions().isEnabled( + "cl_intel_device_side_avc_motion_estimation")) S.Diag(Kind.getLocation(), diag::warn_sampler_initializer_invalid_bits) << "Filter Mode"; @@ -8048,21 +8100,13 @@ InitializationSequence::Perform(Sema &S, CK_IntToOCLSampler); break; } - case SK_OCLZeroEvent: { - assert(Step->Type->isEventT() && - "Event initialization on non-event type."); + case SK_OCLZeroOpaqueType: { + assert((Step->Type->isEventT() || Step->Type->isQueueT() || + Step->Type->isOCLIntelSubgroupAVCType()) && + "Wrong type for initialization of OpenCL opaque type."); CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, - CK_ZeroToOCLEvent, - CurInit.get()->getValueKind()); - break; - } - case SK_OCLZeroQueue: { - assert(Step->Type->isQueueT() && - "Event initialization on non queue type."); - - CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, - CK_ZeroToOCLQueue, + CK_ZeroToOCLOpaqueType, CurInit.get()->getValueKind()); break; } @@ -8255,7 +8299,8 @@ bool InitializationSequence::Diagnose(Sema &S, break; case FK_UTF8StringIntoPlainChar: S.Diag(Kind.getLocation(), - diag::err_array_init_utf8_string_into_char); + diag::err_array_init_utf8_string_into_char) + << S.getLangOpts().CPlusPlus2a; break; case FK_ArrayTypeMismatch: case FK_NonConstantArrayInit: @@ -8945,12 +8990,8 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "OpenCL sampler_t from integer constant"; break; - case SK_OCLZeroEvent: - OS << "OpenCL event_t from zero"; - break; - - case SK_OCLZeroQueue: - OS << "OpenCL queue_t from zero"; + case SK_OCLZeroOpaqueType: + OS << "OpenCL opaque type from zero"; break; } diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 8000cb4fbf..6dc93d0761 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -493,7 +493,9 @@ void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) { LSI->finishedExplicitCaptures(); } -void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) { +void Sema::addLambdaParameters( + ArrayRef<LambdaIntroducer::LambdaCapture> Captures, + CXXMethodDecl *CallOperator, Scope *CurScope) { // Introduce our parameters into the function scope for (unsigned p = 0, NumParams = CallOperator->getNumParams(); p < NumParams; ++p) { @@ -501,7 +503,19 @@ void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) { // If this has an identifier, add it to the scope stack. if (CurScope && Param->getIdentifier()) { - CheckShadow(CurScope, Param); + bool Error = false; + // Resolution of CWG 2211 in C++17 renders shadowing ill-formed, but we + // retroactively apply it. + for (const auto &Capture : Captures) { + if (Capture.Id == Param->getIdentifier()) { + Error = true; + Diag(Param->getLocation(), diag::err_parameter_shadow_capture); + Diag(Capture.Loc, diag::note_var_explicitly_captured_here) + << Capture.Id << true; + } + } + if (!Error) + CheckShadow(CurScope, Param); PushOnScopeChains(Param, CurScope); } @@ -775,16 +789,6 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc, if (Result.isInvalid()) return QualType(); - Init = Result.getAs<Expr>(); - - // The init-capture initialization is a full-expression that must be - // processed as one before we enter the declcontext of the lambda's - // call-operator. - Result = ActOnFinishFullExpr(Init, Loc, /*DiscardedValue*/ false, - /*IsConstexpr*/ false, - /*IsLambdaInitCaptureInitializer*/ true); - if (Result.isInvalid()) - return QualType(); Init = Result.getAs<Expr>(); return DeducedType; @@ -855,7 +859,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/true)); EPI.HasTrailingReturn = true; - EPI.TypeQuals |= DeclSpec::TQ_const; + EPI.TypeQuals.addConst(); // C++1y [expr.prim.lambda]: // The lambda return type is 'auto', which is replaced by the // trailing-return type if provided and/or deduced from 'return' @@ -1152,7 +1156,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; // Add lambda parameters into scope. - addLambdaParameters(Method, CurScope); + addLambdaParameters(Intro.Captures, Method, CurScope); // Enter a new evaluation context to insulate the lambda from any // cleanups from the enclosing full-expression. @@ -1194,7 +1198,7 @@ QualType Sema::getLambdaConversionFunctionResultType( CallingConv CC = Context.getDefaultCallingConvention( CallOpProto->isVariadic(), /*IsCXXMethod=*/false); InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC); - InvokerExtInfo.TypeQuals = 0; + InvokerExtInfo.TypeQuals = Qualifiers(); assert(InvokerExtInfo.RefQualifier == RQ_None && "Lambda's call operator should not have a reference qualifier"); return Context.getFunctionType(CallOpProto->getReturnType(), @@ -1225,7 +1229,8 @@ static void addFunctionPointerConversion(Sema &S, S.Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/true)); // The conversion function is always const. - ConvExtInfo.TypeQuals = Qualifiers::Const; + ConvExtInfo.TypeQuals = Qualifiers(); + ConvExtInfo.TypeQuals.addConst(); QualType ConvTy = S.Context.getFunctionType(PtrToFunctionTy, None, ConvExtInfo); @@ -1373,7 +1378,8 @@ static void addBlockPointerConversion(Sema &S, FunctionProtoType::ExtProtoInfo ConversionEPI( S.Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/true)); - ConversionEPI.TypeQuals = Qualifiers::Const; + ConversionEPI.TypeQuals = Qualifiers(); + ConversionEPI.TypeQuals.addConst(); QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, None, ConversionEPI); SourceLocation Loc = IntroducerRange.getBegin(); @@ -1632,7 +1638,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, // same parameter and return types as the closure type's function call // operator. // FIXME: Fix generic lambda to block conversions. - if (getLangOpts().Blocks && getLangOpts().ObjC1 && !IsGenericLambda) + if (getLangOpts().Blocks && getLangOpts().ObjC && !IsGenericLambda) addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 6a1aae6241..a8a3651c5d 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1600,9 +1600,9 @@ bool Sema::isModuleVisible(const Module *M, bool ModulePrivate) { return false; // Check whether M is transitively exported to an import of the lookup set. - return std::any_of(LookupModules.begin(), LookupModules.end(), - [&](const Module *LookupM) { - return LookupM->isModuleVisible(M); }); + return llvm::any_of(LookupModules, [&](const Module *LookupM) { + return LookupM->isModuleVisible(M); + }); } bool Sema::isVisibleSlow(const NamedDecl *D) { @@ -3619,8 +3619,9 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, // Find results in this base class (and its bases). ShadowContextRAII Shadow(Visited); - LookupVisibleDecls(RD, Result, QualifiedNameLookup, true, Consumer, - Visited, IncludeDependentBases, LoadExternal); + LookupVisibleDecls(RD, Result, QualifiedNameLookup, /*InBaseClass=*/true, + Consumer, Visited, IncludeDependentBases, + LoadExternal); } } @@ -4061,7 +4062,7 @@ void TypoCorrectionConsumer::addNamespaces( } // Do not transform this into an iterator-based loop. The loop body can // trigger the creation of further types (through lazy deserialization) and - // invalide iterators into this list. + // invalid iterators into this list. auto &Types = SemaRef.getASTContext().getTypes(); for (unsigned I = 0; I != Types.size(); ++I) { const auto *TI = Types[I]; @@ -4202,7 +4203,7 @@ void TypoCorrectionConsumer::performQualifiedLookups() { SS->getScopeRep()->print(OldOStream, SemaRef.getPrintingPolicy()); OldOStream << Typo->getName(); // If correction candidate would be an identical written qualified - // identifer, then the existing CXXScopeSpec probably included a + // identifier, then the existing CXXScopeSpec probably included a // typedef that didn't get accounted for properly. if (OldOStream.str() == NewQualified) break; diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 75351ebabd..2daf45411e 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -138,9 +138,11 @@ private: /// 'ordered' clause, the second one is true if the regions has 'ordered' /// clause, false otherwise. llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; + unsigned AssociatedLoops = 1; + const Decl *PossiblyLoopCounter = nullptr; bool NowaitRegion = false; bool CancelRegion = false; - unsigned AssociatedLoops = 1; + bool LoopStart = false; SourceLocation InnerTeamsRegionLoc; /// Reference to the taskgroup task_reduction reference expression. Expr *TaskgroupReductionRef = nullptr; @@ -162,6 +164,9 @@ private: OpenMPClauseKind ClauseKindMode = OMPC_unknown; Sema &SemaRef; bool ForceCapturing = false; + /// true if all the vaiables in the target executable directives must be + /// captured by reference. + bool ForceCaptureByReferenceInTargetExecutable = false; CriticalsWithHintsTy Criticals; using iterator = StackTy::const_reverse_iterator; @@ -193,6 +198,13 @@ public: bool isForceVarCapturing() const { return ForceCapturing; } void setForceVarCapturing(bool V) { ForceCapturing = V; } + void setForceCaptureByReferenceInTargetExecutable(bool V) { + ForceCaptureByReferenceInTargetExecutable = V; + } + bool isForceCaptureByReferenceInTargetExecutable() const { + return ForceCaptureByReferenceInTargetExecutable; + } + void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc) { if (Stack.empty() || @@ -208,6 +220,33 @@ public: Stack.back().first.pop_back(); } + /// Marks that we're started loop parsing. + void loopInit() { + assert(isOpenMPLoopDirective(getCurrentDirective()) && + "Expected loop-based directive."); + Stack.back().first.back().LoopStart = true; + } + /// Start capturing of the variables in the loop context. + void loopStart() { + assert(isOpenMPLoopDirective(getCurrentDirective()) && + "Expected loop-based directive."); + Stack.back().first.back().LoopStart = false; + } + /// true, if variables are captured, false otherwise. + bool isLoopStarted() const { + assert(isOpenMPLoopDirective(getCurrentDirective()) && + "Expected loop-based directive."); + return !Stack.back().first.back().LoopStart; + } + /// Marks (or clears) declaration as possibly loop counter. + void resetPossibleLoopCounter(const Decl *D = nullptr) { + Stack.back().first.back().PossiblyLoopCounter = + D ? D->getCanonicalDecl() : D; + } + /// Gets the possible loop counter decl. + const Decl *getPossiblyLoopCunter() const { + return Stack.back().first.back().PossiblyLoopCounter; + } /// Start new OpenMP region stack in new non-capturing function. void pushFunction() { const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); @@ -354,7 +393,7 @@ public: return OMPD_unknown; return std::next(Stack.back().first.rbegin())->Directive; } - + /// Add requires decl to internal vector void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); @@ -381,7 +420,7 @@ public: } return IsDuplicate; } - + /// Set default data sharing attribute to none. void setDefaultDSANone(SourceLocation Loc) { assert(!isStackEmpty()); @@ -630,8 +669,8 @@ bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { } // namespace static const Expr *getExprAsWritten(const Expr *E) { - if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) - E = ExprTemp->getSubExpr(); + if (const auto *FE = dyn_cast<FullExpr>(E)) + E = FE->getSubExpr(); if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) E = MTE->GetTemporaryExpr(); @@ -1236,10 +1275,16 @@ bool DSAStackTy::hasExplicitDSA( return false; std::advance(StartI, Level); auto I = StartI->SharingMap.find(D); - return (I != StartI->SharingMap.end()) && + if ((I != StartI->SharingMap.end()) && I->getSecond().RefExpr.getPointer() && CPred(I->getSecond().Attributes) && - (!NotLastprivate || !I->getSecond().RefExpr.getInt()); + (!NotLastprivate || !I->getSecond().RefExpr.getInt())) + return true; + // Check predetermined rules for the loop control variables. + auto LI = StartI->LCVMap.find(D); + if (LI != StartI->LCVMap.end()) + return CPred(OMPC_private); + return false; } bool DSAStackTy::hasExplicitDirective( @@ -1406,6 +1451,8 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { // By default, all the data that has a scalar type is mapped by copy // (except for reduction variables). IsByRef = + (DSAStack->isForceCaptureByReferenceInTargetExecutable() && + !Ty->isAnyPointerType()) || !Ty->isScalarType() || DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || DSAStack->hasExplicitDSA( @@ -1415,10 +1462,12 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { IsByRef = - !DSAStack->hasExplicitDSA( - D, - [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, - Level, /*NotLastprivate=*/true) && + ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && + !Ty->isAnyPointerType()) || + !DSAStack->hasExplicitDSA( + D, + [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, + Level, /*NotLastprivate=*/true)) && // If the variable is artificial and must be captured by value - try to // capture by value. !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && @@ -1480,6 +1529,49 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { return VD; } } + // Capture variables captured by reference in lambdas for target-based + // directives. + if (VD && !DSAStack->isClauseParsingMode()) { + if (const auto *RD = VD->getType() + .getCanonicalType() + .getNonReferenceType() + ->getAsCXXRecordDecl()) { + bool SavedForceCaptureByReferenceInTargetExecutable = + DSAStack->isForceCaptureByReferenceInTargetExecutable(); + DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); + if (RD->isLambda()) { + llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; + FieldDecl *ThisCapture; + RD->getCaptureFields(Captures, ThisCapture); + for (const LambdaCapture &LC : RD->captures()) { + if (LC.getCaptureKind() == LCK_ByRef) { + VarDecl *VD = LC.getCapturedVar(); + DeclContext *VDC = VD->getDeclContext(); + if (!VDC->Encloses(CurContext)) + continue; + DSAStackTy::DSAVarData DVarPrivate = + DSAStack->getTopDSA(VD, /*FromParent=*/false); + // Do not capture already captured variables. + if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && + DVarPrivate.CKind == OMPC_unknown && + !DSAStack->checkMappableExprComponentListsForDecl( + D, /*CurrentRegionOnly=*/true, + [](OMPClauseMappableExprCommon:: + MappableExprComponentListRef, + OpenMPClauseKind) { return true; })) + MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); + } else if (LC.getCaptureKind() == LCK_This) { + QualType ThisTy = getCurrentThisType(); + if (!ThisTy.isNull() && + Context.typesAreCompatible(ThisTy, ThisCapture->getType())) + CheckCXXThisCapture(LC.getLocation()); + } + } + } + DSAStack->setForceCaptureByReferenceInTargetExecutable( + SavedForceCaptureByReferenceInTargetExecutable); + } + } if (DSAStack->getCurrentDirective() != OMPD_unknown && (!DSAStack->isClauseParsingMode() || @@ -1510,8 +1602,28 @@ void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, FunctionScopesIndex -= Regions.size(); } +void Sema::startOpenMPLoop() { + assert(LangOpts.OpenMP && "OpenMP must be enabled."); + if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) + DSAStack->loopInit(); +} + bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { assert(LangOpts.OpenMP && "OpenMP is not allowed"); + if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { + if (DSAStack->getAssociatedLoops() > 0 && + !DSAStack->isLoopStarted()) { + DSAStack->resetPossibleLoopCounter(D); + DSAStack->loopStart(); + return true; + } + if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || + DSAStack->isLoopControlVariable(D).first) && + !DSAStack->hasExplicitDSA( + D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && + !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) + return true; + } return DSAStack->hasExplicitDSA( D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || (DSAStack->isClauseParsingMode() && @@ -2021,6 +2133,30 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; + void VisitSubCaptures(OMPExecutableDirective *S) { + // Check implicitly captured variables. + if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) + return; + for (const CapturedStmt::Capture &Cap : + S->getInnermostCapturedStmt()->captures()) { + if (!Cap.capturesVariable()) + continue; + VarDecl *VD = Cap.getCapturedVar(); + // Do not try to map the variable if it or its sub-component was mapped + // already. + if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && + Stack->checkMappableExprComponentListsForDecl( + VD, /*CurrentRegionOnly=*/true, + [](OMPClauseMappableExprCommon::MappableExprComponentListRef, + OpenMPClauseKind) { return true; })) + continue; + DeclRefExpr *DRE = buildDeclRefExpr( + SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), + Cap.getLocation(), /*RefersToCapture=*/true); + Visit(DRE); + } + } + public: void VisitDeclRefExpr(DeclRefExpr *E) { if (E->isTypeDependent() || E->isValueDependent() || @@ -2181,8 +2317,14 @@ public: // Define implicit data-sharing attributes for task. DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && - !Stack->isLoopControlVariable(FD).first) - ImplicitFirstprivate.push_back(E); + !Stack->isLoopControlVariable(FD).first) { + // Check if there is a captured expression for the current field in the + // region. Do not mark it as firstprivate unless there is no captured + // expression. + // TODO: try to make it firstprivate. + if (DVar.CKind != OMPC_unknown) + ImplicitFirstprivate.push_back(E); + } return; } if (isOpenMPTargetExecutionDirective(DKind)) { @@ -2242,11 +2384,20 @@ public: } } } + // Check implicitly captured variables. + VisitSubCaptures(S); } void VisitStmt(Stmt *S) { for (Stmt *C : S->children()) { - if (C && !isa<OMPExecutableDirective>(C)) - Visit(C); + if (C) { + if (auto *OED = dyn_cast<OMPExecutableDirective>(C)) { + // Check implicitly captured variables in the task-based directives to + // check if they must be firstprivatized. + VisitSubCaptures(OED); + } else { + Visit(C); + } + } } } @@ -3760,7 +3911,8 @@ class OpenMPIterationSpaceChecker { /// Var <= UB /// UB > Var /// UB >= Var - bool TestIsLessOp = false; + /// This will have no value when the condition is != + llvm::Optional<bool> TestIsLessOp; /// This flag is true when condition is strict ( < or > ). bool TestIsStrictOp = false; /// This flag is true when step is subtracted on each iteration. @@ -3826,8 +3978,8 @@ private: /// Helper to set loop counter variable and its initializer. bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); /// Helper to set upper bound. - bool setUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, - SourceLocation SL); + bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, + SourceRange SR, SourceLocation SL); /// Helper to set loop increment. bool setStep(Expr *NewStep, bool Subtract); }; @@ -3862,15 +4014,17 @@ bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, return false; } -bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, bool LessOp, bool StrictOp, - SourceRange SR, SourceLocation SL) { +bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp, + bool StrictOp, SourceRange SR, + SourceLocation SL) { // State consistency checking to ensure correct usage. assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); if (!NewUB) return true; UB = NewUB; - TestIsLessOp = LessOp; + if (LessOp) + TestIsLessOp = LessOp; TestIsStrictOp = StrictOp; ConditionSrcRange = SR; ConditionLoc = SL; @@ -3910,18 +4064,23 @@ bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { bool IsConstPos = IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); bool IsConstZero = IsConstant && !Result.getBoolValue(); + + // != with increment is treated as <; != with decrement is treated as > + if (!TestIsLessOp.hasValue()) + TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); if (UB && (IsConstZero || - (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) - : (IsConstPos || (IsUnsigned && !Subtract))))) { + (TestIsLessOp.getValue() ? + (IsConstNeg || (IsUnsigned && Subtract)) : + (IsConstPos || (IsUnsigned && !Subtract))))) { SemaRef.Diag(NewStep->getExprLoc(), diag::err_omp_loop_incr_not_compatible) - << LCDecl << TestIsLessOp << NewStep->getSourceRange(); + << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); SemaRef.Diag(ConditionLoc, diag::note_omp_loop_cond_requres_compatible_incr) - << TestIsLessOp << ConditionSrcRange; + << TestIsLessOp.getValue() << ConditionSrcRange; return true; } - if (TestIsLessOp == Subtract) { + if (TestIsLessOp.getValue() == Subtract) { NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) .get(); @@ -4062,7 +4221,12 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), BO->getSourceRange(), BO->getOperatorLoc()); - } + } else if (BO->getOpcode() == BO_NE) + return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? + BO->getRHS() : BO->getLHS(), + /*LessOp=*/llvm::None, + /*StrictOp=*/true, + BO->getSourceRange(), BO->getOperatorLoc()); } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { if (CE->getNumArgs() == 2) { auto Op = CE->getOperator(); @@ -4080,6 +4244,14 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), CE->getOperatorLoc()); break; + case OO_ExclaimEqual: + return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? + CE->getArg(1) : CE->getArg(0), + /*LessOp=*/llvm::None, + /*StrictOp=*/true, + CE->getSourceRange(), + CE->getOperatorLoc()); + break; default: break; } @@ -4228,8 +4400,8 @@ Expr *OpenMPIterationSpaceChecker::buildNumIterations( if (VarType->isIntegerType() || VarType->isPointerType() || SemaRef.getLangOpts().CPlusPlus) { // Upper - Lower - Expr *UBExpr = TestIsLessOp ? UB : LB; - Expr *LBExpr = TestIsLessOp ? LB : UB; + Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; + Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); if (!Upper || !Lower) @@ -4330,8 +4502,9 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond( ExprResult CondExpr = SemaRef.BuildBinOp(S, DefaultLoc, - TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) - : (TestIsStrictOp ? BO_GT : BO_GE), + TestIsLessOp.getValue() ? + (TestIsStrictOp ? BO_LT : BO_LE) : + (TestIsStrictOp ? BO_GT : BO_GE), NewLB.get(), NewUB.get()); if (CondExpr.isUsable()) { if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), @@ -4409,9 +4582,9 @@ Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( SemaRef.getLangOpts().CPlusPlus) { // Upper - Lower Expr *Upper = - TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); + TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); Expr *Lower = - TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; + TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; if (!Upper || !Lower) return nullptr; @@ -4493,6 +4666,15 @@ void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { } } DSAStack->addLoopControlVariable(D, VD); + const Decl *LD = DSAStack->getPossiblyLoopCunter(); + if (LD != D->getCanonicalDecl()) { + DSAStack->resetPossibleLoopCounter(); + if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) + MarkDeclarationsReferencedInExpr( + buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), + Var->getType().getNonLValueExprType(Context), + ForLoc, /*RefersToCapture=*/true)); + } } } DSAStack->setAssociatedLoops(AssociatedLoops - 1); @@ -4866,15 +5048,16 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, unsigned NestedLoopCount = 1; if (CollapseLoopCountExpr) { // Found 'collapse' clause - calculate collapse number. - llvm::APSInt Result; + Expr::EvalResult Result; if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) - NestedLoopCount = Result.getLimitedValue(); + NestedLoopCount = Result.Val.getInt().getLimitedValue(); } unsigned OrderedLoopCount = 1; if (OrderedLoopCountExpr) { // Found 'ordered' clause - calculate collapse number. - llvm::APSInt Result; - if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { + Expr::EvalResult EVResult; + if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { + llvm::APSInt Result = EVResult.Val.getInt(); if (Result.getLimitedValue() < NestedLoopCount) { SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), diag::err_omp_wrong_ordered_loop_count) @@ -5201,6 +5384,13 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get()); + ExprResult CombDistCond; + if (isOpenMPLoopBoundSharingDirective(DKind)) { + CombDistCond = + SemaRef.BuildBinOp( + CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get()); + } + ExprResult CombCond; if (isOpenMPLoopBoundSharingDirective(DKind)) { CombCond = @@ -5275,7 +5465,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // on PrevUB instead of NumIterations - used to implement 'for' when found // in combination with 'distribute', like in 'distribute parallel for' SourceLocation DistIncLoc = AStmt->getBeginLoc(); - ExprResult DistCond, DistInc, PrevEUB; + ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; if (isOpenMPLoopBoundSharingDirective(DKind)) { DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); assert(DistCond.isUsable() && "distribute cond expr was not built"); @@ -5298,6 +5488,11 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), CondOp.get()); PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); + + // Build IV <= PrevUB to be used in parallel for is in combination with + // a distribute directive with schedule(static, 1) + ParForInDistCond = + SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get()); } // Build updates and final values of the loop counters. @@ -5421,6 +5616,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.DistCombinedFields.Cond = CombCond.get(); Built.DistCombinedFields.NLB = CombNextLB.get(); Built.DistCombinedFields.NUB = CombNextUB.get(); + Built.DistCombinedFields.DistCond = CombDistCond.get(); + Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); return NestedLoopCount; } @@ -5456,7 +5653,6 @@ static bool checkSimdlenSafelenSpecified(Sema &S, } if (Simdlen && Safelen) { - llvm::APSInt SimdlenRes, SafelenRes; const Expr *SimdlenLength = Simdlen->getSimdlen(); const Expr *SafelenLength = Safelen->getSafelen(); if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || @@ -5467,8 +5663,11 @@ static bool checkSimdlenSafelenSpecified(Sema &S, SafelenLength->isInstantiationDependent() || SafelenLength->containsUnexpandedParameterPack()) return false; - SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); - SafelenLength->EvaluateAsInt(SafelenRes, S.Context); + Expr::EvalResult SimdlenResult, SafelenResult; + SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); + SafelenLength->EvaluateAsInt(SafelenResult, S.Context); + llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); + llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] // If both simdlen and safelen clauses are specified, the value of the // simdlen parameter must be less than or equal to the value of the safelen @@ -8011,6 +8210,10 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_use_device_ptr: case OMPC_is_device_ptr: case OMPC_unified_address: + case OMPC_unified_shared_memory: + case OMPC_reverse_offload: + case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -8533,6 +8736,10 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_use_device_ptr: case OMPC_is_device_ptr: case OMPC_unified_address: + case OMPC_unified_shared_memory: + case OMPC_reverse_offload: + case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Unexpected OpenMP clause."); } return CaptureRegion; @@ -8801,6 +9008,11 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, LParenLoc, EndLoc); break; + case OMPC_atomic_default_mem_order: + Res = ActOnOpenMPAtomicDefaultMemOrderClause( + static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), + ArgumentLoc, StartLoc, LParenLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -8851,6 +9063,9 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_use_device_ptr: case OMPC_is_device_ptr: case OMPC_unified_address: + case OMPC_unified_shared_memory: + case OMPC_reverse_offload: + case OMPC_dynamic_allocators: llvm_unreachable("Clause is not allowed."); } return Res; @@ -8923,6 +9138,21 @@ OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( + OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { + if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { + Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) + << getListOfPossibleValues( + OMPC_atomic_default_mem_order, /*First=*/0, + /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) + << getOpenMPClauseName(OMPC_atomic_default_mem_order); + return nullptr; + } + return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, + LParenLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -9008,6 +9238,10 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_use_device_ptr: case OMPC_is_device_ptr: case OMPC_unified_address: + case OMPC_unified_shared_memory: + case OMPC_reverse_offload: + case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -9166,6 +9400,15 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_unified_address: Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); break; + case OMPC_unified_shared_memory: + Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); + break; + case OMPC_reverse_offload: + Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); + break; + case OMPC_dynamic_allocators: + Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -9205,6 +9448,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_from: case OMPC_use_device_ptr: case OMPC_is_device_ptr: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -9271,6 +9515,21 @@ OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); +} + +OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, @@ -9379,6 +9638,10 @@ OMPClause *Sema::ActOnOpenMPVarListClause( case OMPC_unknown: case OMPC_uniform: case OMPC_unified_address: + case OMPC_unified_shared_memory: + case OMPC_reverse_offload: + case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -10409,10 +10672,11 @@ static bool checkOMPArraySectionConstantForReduction( SingleElement = true; ArraySizes.push_back(llvm::APSInt::get(1)); } else { - llvm::APSInt ConstantLengthValue; - if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) + Expr::EvalResult Result; + if (!Length->EvaluateAsInt(Result, Context)) return false; + llvm::APSInt ConstantLengthValue = Result.Val.getInt(); SingleElement = (ConstantLengthValue.getSExtValue() == 1); ArraySizes.push_back(ConstantLengthValue); } @@ -10433,9 +10697,12 @@ static bool checkOMPArraySectionConstantForReduction( // This is an array subscript which has implicit length 1! ArraySizes.push_back(llvm::APSInt::get(1)); } else { - llvm::APSInt ConstantLengthValue; - if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || - ConstantLengthValue.getSExtValue() != 1) + Expr::EvalResult Result; + if (!Length->EvaluateAsInt(Result, Context)) + return false; + + llvm::APSInt ConstantLengthValue = Result.Val.getInt(); + if (ConstantLengthValue.getSExtValue() != 1) return false; ArraySizes.push_back(ConstantLengthValue); @@ -11958,9 +12225,11 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, // If there is a lower bound that does not evaluates to zero, we are not // covering the whole dimension. if (LowerBound) { - llvm::APSInt ConstLowerBound; - if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) + Expr::EvalResult Result; + if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) return false; // Can't get the integer value as a constant. + + llvm::APSInt ConstLowerBound = Result.Val.getInt(); if (ConstLowerBound.getSExtValue()) return true; } @@ -11980,10 +12249,11 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, if (!CATy) return false; - llvm::APSInt ConstLength; - if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) + Expr::EvalResult Result; + if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) return false; // Can't get the integer value as a constant. + llvm::APSInt ConstLength = Result.Val.getInt(); return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); } @@ -12014,10 +12284,11 @@ static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, } // Check if the length evaluates to 1. - llvm::APSInt ConstLength; - if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) + Expr::EvalResult Result; + if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) return false; // Can't get the integer value as a constant. + llvm::APSInt ConstLength = Result.Val.getInt(); return ConstLength.getSExtValue() != 1; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index f4ec04a1b2..4c7d61d79e 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1142,8 +1142,9 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, // function yet (because we haven't yet resolved whether this is a static // or non-static member function). Add it now, on the assumption that this // is a redeclaration of OldMethod. - unsigned OldQuals = OldMethod->getTypeQualifiers(); - unsigned NewQuals = NewMethod->getTypeQualifiers(); + // FIXME: OpenCL: Need to consider address spaces + unsigned OldQuals = OldMethod->getTypeQualifiers().getCVRUQualifiers(); + unsigned NewQuals = NewMethod->getTypeQualifiers().getCVRUQualifiers(); if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() && !isa<CXXConstructorDecl>(NewMethod)) NewQuals |= Qualifiers::Const; @@ -1418,7 +1419,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, bool AllowObjCWritebackConversion = getLangOpts().ObjCAutoRefCount && (Action == AA_Passing || Action == AA_Sending); - if (getLangOpts().ObjC1) + if (getLangOpts().ObjC) CheckObjCBridgeRelatedConversions(From->getBeginLoc(), ToType, From->getType(), From); ICS = ::TryImplicitConversion(*this, From, ToType, @@ -2395,7 +2396,7 @@ static QualType AdoptQualifiers(ASTContext &Context, QualType T, Qualifiers Qs){ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType, bool &IncompatibleObjC) { - if (!getLangOpts().ObjC1) + if (!getLangOpts().ObjC) return false; // The set of qualifiers on the type we're converting from. @@ -2823,8 +2824,9 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, return; } - unsigned FromQuals = FromFunction->getTypeQuals(), - ToQuals = ToFunction->getTypeQuals(); + // FIXME: OpenCL: Need to consider address spaces + unsigned FromQuals = FromFunction->getTypeQuals().getCVRUQualifiers(); + unsigned ToQuals = ToFunction->getTypeQuals().getCVRUQualifiers(); if (FromQuals != ToQuals) { PDiag << ft_qualifer_mismatch << ToQuals << FromQuals; return; @@ -3516,7 +3518,7 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) { static ImplicitConversionSequence::CompareKind compareConversionFunctions(Sema &S, FunctionDecl *Function1, FunctionDecl *Function2) { - if (!S.getLangOpts().ObjC1 || !S.getLangOpts().CPlusPlus11) + if (!S.getLangOpts().ObjC || !S.getLangOpts().CPlusPlus11) return ImplicitConversionSequence::Indistinguishable; // Objective-C++: @@ -3900,6 +3902,31 @@ CompareStandardConversionSequences(Sema &S, SourceLocation Loc, S.Context.getTypeSize(SCS1.getToType(2))) return ImplicitConversionSequence::Better; + // Prefer a compatible vector conversion over a lax vector conversion + // For example: + // + // typedef float __v4sf __attribute__((__vector_size__(16))); + // void f(vector float); + // void f(vector signed int); + // int main() { + // __v4sf a; + // f(a); + // } + // Here, we'd like to choose f(vector float) and not + // report an ambiguous call error + if (SCS1.Second == ICK_Vector_Conversion && + SCS2.Second == ICK_Vector_Conversion) { + bool SCS1IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes( + SCS1.getFromType(), SCS1.getToType(2)); + bool SCS2IsCompatibleVectorConversion = S.Context.areCompatibleVectorTypes( + SCS2.getFromType(), SCS2.getToType(2)); + + if (SCS1IsCompatibleVectorConversion != SCS2IsCompatibleVectorConversion) + return SCS1IsCompatibleVectorConversion + ? ImplicitConversionSequence::Better + : ImplicitConversionSequence::Worse; + } + return ImplicitConversionSequence::Indistinguishable; } @@ -5040,9 +5067,15 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, QualType ClassType = S.Context.getTypeDeclType(ActingContext); // [class.dtor]p2: A destructor can be invoked for a const, volatile or // const volatile object. - unsigned Quals = isa<CXXDestructorDecl>(Method) ? - Qualifiers::Const | Qualifiers::Volatile : Method->getTypeQualifiers(); - QualType ImplicitParamType = S.Context.getCVRQualifiedType(ClassType, Quals); + Qualifiers Quals; + if (isa<CXXDestructorDecl>(Method)) { + Quals.addConst(); + Quals.addVolatile(); + } else { + Quals = Method->getTypeQualifiers(); + } + + QualType ImplicitParamType = S.Context.getQualifiedType(ClassType, Quals); // Set up the conversion sequence as a "bad" conversion, to allow us // to exit early. @@ -5108,7 +5141,7 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, break; case RQ_LValue: - if (!FromClassification.isLValue() && Quals != Qualifiers::Const) { + if (!FromClassification.isLValue() && !Quals.hasOnlyConst()) { // non-const lvalue reference cannot bind to an rvalue ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, FromType, ImplicitParamType); @@ -5224,9 +5257,14 @@ Sema::PerformObjectArgumentInitialization(Expr *From, From = FromRes.get(); } - if (!Context.hasSameType(From->getType(), DestType)) - From = ImpCastExprToType(From, DestType, CK_NoOp, + if (!Context.hasSameType(From->getType(), DestType)) { + if (From->getType().getAddressSpace() != DestType.getAddressSpace()) + From = ImpCastExprToType(From, DestType, CK_AddressSpaceConversion, + From->getValueKind()).get(); + else + From = ImpCastExprToType(From, DestType, CK_NoOp, From->getValueKind()).get(); + } return From; } @@ -5444,7 +5482,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, if (Notes.empty()) { // It's a constant expression. - return Result; + return ConstantExpr::Create(S.Context, Result.get()); } } @@ -5921,15 +5959,13 @@ static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, /// \param PartialOverloading true if we are performing "partial" overloading /// based on an incomplete set of function arguments. This feature is used by /// code completion. -void -Sema::AddOverloadCandidate(FunctionDecl *Function, - DeclAccessPair FoundDecl, - ArrayRef<Expr *> Args, - OverloadCandidateSet &CandidateSet, - bool SuppressUserConversions, - bool PartialOverloading, - bool AllowExplicit, - ConversionSequenceList EarlyConversions) { +void Sema::AddOverloadCandidate(FunctionDecl *Function, + DeclAccessPair FoundDecl, ArrayRef<Expr *> Args, + OverloadCandidateSet &CandidateSet, + bool SuppressUserConversions, + bool PartialOverloading, bool AllowExplicit, + ADLCallKind IsADLCandidate, + ConversionSequenceList EarlyConversions) { const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>()); assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -5988,6 +6024,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, Candidate.Function = Function; Candidate.Viable = true; Candidate.IsSurrogate = false; + Candidate.IsADLCandidate = IsADLCandidate; Candidate.IgnoreObjectArgument = false; Candidate.ExplicitCallArguments = Args.size(); @@ -6404,7 +6441,12 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, if (Expr *E = Args[0]) { // Use the explicit base to restrict the lookup: ObjectType = E->getType(); - ObjectClassification = E->Classify(Context); + // Pointers in the object arguments are implicitly dereferenced, so we + // always classify them as l-values. + if (!ObjectType.isNull() && ObjectType->isPointerType()) + ObjectClassification = Expr::Classification::makeSimpleLValue(); + else + ObjectClassification = E->Classify(Context); } // .. else there is an implicit base. FunctionArgs = Args.slice(1); } @@ -6685,14 +6727,11 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, /// Add a C++ function template specialization as a candidate /// in the candidate set, using template argument deduction to produce /// an appropriate function template specialization. -void -Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, - DeclAccessPair FoundDecl, - TemplateArgumentListInfo *ExplicitTemplateArgs, - ArrayRef<Expr *> Args, - OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions, - bool PartialOverloading) { +void Sema::AddTemplateOverloadCandidate( + FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, + TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, + OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, + bool PartialOverloading, ADLCallKind IsADLCandidate) { if (!CandidateSet.isNewCandidate(FunctionTemplate)) return; @@ -6721,6 +6760,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; Candidate.IsSurrogate = false; + Candidate.IsADLCandidate = IsADLCandidate; // Ignore the object argument if there is one, since we don't have an object // type. Candidate.IgnoreObjectArgument = @@ -6742,7 +6782,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, assert(Specialization && "Missing function template specialization?"); AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions, PartialOverloading, - /*AllowExplicit*/false, Conversions); + /*AllowExplicit*/ false, IsADLCandidate, Conversions); } /// Check that implicit conversion sequences can be formed for each argument @@ -8905,16 +8945,20 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, // set. for (ADLResult::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) { DeclAccessPair FoundDecl = DeclAccessPair::make(*I, AS_none); + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) { if (ExplicitTemplateArgs) continue; - AddOverloadCandidate(FD, FoundDecl, Args, CandidateSet, false, - PartialOverloading); - } else - AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I), - FoundDecl, ExplicitTemplateArgs, - Args, CandidateSet, PartialOverloading); + AddOverloadCandidate(FD, FoundDecl, Args, CandidateSet, + /*SupressUserConversions=*/false, PartialOverloading, + /*AllowExplicit=*/false, ADLCallKind::UsesADL); + } else { + AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I), FoundDecl, + ExplicitTemplateArgs, Args, CandidateSet, + /*SupressUserConversions=*/false, + PartialOverloading, ADLCallKind::UsesADL); + } } } @@ -8947,25 +8991,28 @@ static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1, auto Cand1Attrs = Cand1->specific_attrs<EnableIfAttr>(); auto Cand2Attrs = Cand2->specific_attrs<EnableIfAttr>(); - auto Cand1I = Cand1Attrs.begin(); llvm::FoldingSetNodeID Cand1ID, Cand2ID; - for (EnableIfAttr *Cand2A : Cand2Attrs) { - Cand1ID.clear(); - Cand2ID.clear(); + for (auto Pair : zip_longest(Cand1Attrs, Cand2Attrs)) { + Optional<EnableIfAttr *> Cand1A = std::get<0>(Pair); + Optional<EnableIfAttr *> Cand2A = std::get<1>(Pair); // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1 - // has fewer enable_if attributes than Cand2. - auto Cand1A = Cand1I++; - if (Cand1A == Cand1Attrs.end()) + // has fewer enable_if attributes than Cand2, and vice versa. + if (!Cand1A) return Comparison::Worse; + if (!Cand2A) + return Comparison::Better; - Cand1A->getCond()->Profile(Cand1ID, S.getASTContext(), true); - Cand2A->getCond()->Profile(Cand2ID, S.getASTContext(), true); + Cand1ID.clear(); + Cand2ID.clear(); + + (*Cand1A)->getCond()->Profile(Cand1ID, S.getASTContext(), true); + (*Cand2A)->getCond()->Profile(Cand2ID, S.getASTContext(), true); if (Cand1ID != Cand2ID) return Comparison::Worse; } - return Cand1I == Cand1Attrs.end() ? Comparison::Equal : Comparison::Better; + return Comparison::Equal; } static bool isBetterMultiversionCandidate(const OverloadCandidate &Cand1, @@ -9984,7 +10031,7 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, DeductionFailure.getFirstArg()->getNonTypeTemplateArgumentType(); QualType T2 = DeductionFailure.getSecondArg()->getNonTypeTemplateArgumentType(); - if (!S.Context.hasSameType(T1, T2)) { + if (!T1.isNull() && !T2.isNull() && !S.Context.hasSameType(T1, T2)) { S.Diag(Templated->getLocation(), diag::note_ovl_candidate_inconsistent_deduction_types) << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << T1 @@ -10242,7 +10289,8 @@ static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { FunctionDecl *Callee = Cand->Function; S.Diag(Callee->getLocation(), - diag::note_ovl_candidate_disabled_by_extension); + diag::note_ovl_candidate_disabled_by_extension) + << S.getOpenCLExtensionsFromDeclExtMap(Callee); } /// Generates a 'note' diagnostic for an overload candidate. We've @@ -10996,7 +11044,7 @@ private: // Note: We explicitly leave Matches unmodified if there isn't a clear best // option, so we can potentially give the user a better error - if (!std::all_of(Matches.begin(), Matches.end(), IsBestOrInferiorToBest)) + if (!llvm::all_of(Matches, IsBestOrInferiorToBest)) return false; Matches[0] = *Best; Matches.resize(1); @@ -11987,7 +12035,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, return ExprError(); Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc, - ExecConfig); + ExecConfig, /*IsExecConfig=*/false, + (*Best)->IsADLCandidate); } case OR_No_Viable_Function: { @@ -12039,7 +12088,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, FunctionDecl *FDecl = (*Best)->Function; Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, RParenLoc, - ExecConfig); + ExecConfig, /*IsExecConfig=*/false, + (*Best)->IsADLCandidate); } } @@ -12228,9 +12278,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, ResultTy = ResultTy.getNonLValueExprType(Context); Args[0] = Input; - CallExpr *TheCall = - new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray, - ResultTy, VK, OpLoc, FPOptions()); + CallExpr *TheCall = new (Context) + CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray, ResultTy, + VK, OpLoc, FPOptions(), Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); @@ -12460,10 +12510,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, ExprValueKind VK = Expr::getValueKindForType(ResultTy); ResultTy = ResultTy.getNonLValueExprType(Context); - CXXOperatorCallExpr *TheCall = - new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), - Args, ResultTy, VK, OpLoc, - FPFeatures); + CXXOperatorCallExpr *TheCall = new (Context) + CXXOperatorCallExpr(Context, Op, FnExpr.get(), Args, ResultTy, VK, + OpLoc, FPFeatures, Best->IsADLCandidate); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) @@ -12790,7 +12839,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // Check that the object type isn't more qualified than the // member function we're calling. - Qualifiers funcQuals = Qualifiers::fromCVRMask(proto->getTypeQuals()); + Qualifiers funcQuals = proto->getTypeQuals(); QualType objectType = op->getLHS()->getType(); if (op->getOpcode() == BO_PtrMemI) @@ -12810,7 +12859,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, CXXMemberCallExpr *call = new (Context) CXXMemberCallExpr(Context, MemExprE, Args, - resultType, valueKind, RParenLoc); + resultType, valueKind, RParenLoc, + proto->getNumParams()); if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getBeginLoc(), call, nullptr)) @@ -12960,9 +13010,11 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, ResultType = ResultType.getNonLValueExprType(Context); assert(Method && "Member call to something that isn't a method?"); + const auto *Proto = Method->getType()->getAs<FunctionProtoType>(); CXXMemberCallExpr *TheCall = new (Context) CXXMemberCallExpr(Context, MemExprE, Args, - ResultType, VK, RParenLoc); + ResultType, VK, RParenLoc, + Proto->getNumParams()); // Check for a valid return type. if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(), @@ -12982,8 +13034,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, } // Convert the rest of the arguments - const FunctionProtoType *Proto = - Method->getType()->getAs<FunctionProtoType>(); if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args, RParenLoc)) return ExprError(); @@ -13231,29 +13281,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, if (NewFn.isInvalid()) return true; + // The number of argument slots to allocate in the call. If we have default + // arguments we need to allocate space for them as well. We additionally + // need one more slot for the object parameter. + unsigned NumArgsSlots = 1 + std::max<unsigned>(Args.size(), NumParams); + // Build the full argument list for the method call (the implicit object // parameter is placed at the beginning of the list). - SmallVector<Expr *, 8> MethodArgs(Args.size() + 1); - MethodArgs[0] = Object.get(); - std::copy(Args.begin(), Args.end(), MethodArgs.begin() + 1); - - // Once we've built TheCall, all of the expressions are properly - // owned. - QualType ResultTy = Method->getReturnType(); - ExprValueKind VK = Expr::getValueKindForType(ResultTy); - ResultTy = ResultTy.getNonLValueExprType(Context); - - CXXOperatorCallExpr *TheCall = new (Context) - CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, - VK, RParenLoc, FPOptions()); - - if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) - return true; - - // We may have default arguments. If so, we need to allocate more - // slots in the call for them. - if (Args.size() < NumParams) - TheCall->setNumArgs(Context, NumParams + 1); + SmallVector<Expr *, 8> MethodArgs(NumArgsSlots); bool IsError = false; @@ -13265,7 +13300,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, IsError = true; else Object = ObjRes; - TheCall->setArg(0, Object.get()); + MethodArgs[0] = Object.get(); // Check the argument types. for (unsigned i = 0; i != NumParams; i++) { @@ -13294,7 +13329,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, Arg = DefArg.getAs<Expr>(); } - TheCall->setArg(i + 1, Arg); + MethodArgs[i + 1] = Arg; } // If this is a variadic call, handle args passed through "...". @@ -13304,14 +13339,27 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, nullptr); IsError |= Arg.isInvalid(); - TheCall->setArg(i + 1, Arg.get()); + MethodArgs[i + 1] = Arg.get(); } } - if (IsError) return true; + if (IsError) + return true; DiagnoseSentinelCalls(Method, LParenLoc, Args); + // Once we've built TheCall, all of the expressions are properly owned. + QualType ResultTy = Method->getReturnType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); + + CXXOperatorCallExpr *TheCall = new (Context) + CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, + VK, RParenLoc, FPOptions()); + + if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) + return true; + if (CheckFunctionCall(Method, TheCall, Proto)) return true; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index f0d1947582..cc3c25cfb5 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -246,7 +246,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { // we might want to make a more specific diagnostic. Check for one of these // cases now. unsigned DiagID = diag::warn_unused_expr; - if (const ExprWithCleanups *Temps = dyn_cast<ExprWithCleanups>(E)) + if (const FullExpr *Temps = dyn_cast<FullExpr>(E)) E = Temps->getSubExpr(); if (const CXXBindTemporaryExpr *TempExpr = dyn_cast<CXXBindTemporaryExpr>(E)) E = TempExpr->getSubExpr(); @@ -462,8 +462,8 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal, return StmtError(); } - CaseStmt *CS = new (Context) - CaseStmt(LHSVal.get(), RHSVal.get(), CaseLoc, DotDotDotLoc, ColonLoc); + auto *CS = CaseStmt::Create(Context, LHSVal.get(), RHSVal.get(), + CaseLoc, DotDotDotLoc, ColonLoc); getCurFunction()->SwitchStack.back().getPointer()->addSwitchCase(CS); return CS; } @@ -472,7 +472,7 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal, void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) { DiagnoseUnusedExprResult(SubStmt); - CaseStmt *CS = static_cast<CaseStmt*>(caseStmt); + auto *CS = static_cast<CaseStmt *>(caseStmt); CS->setSubStmt(SubStmt); } @@ -551,8 +551,9 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr, Stmt *InitStmt, false); Expr *CondExpr = Cond.get().second; - if (!Diags.isIgnored(diag::warn_comma_operator, - CondExpr->getExprLoc())) + // Only call the CommaVisitor when not C89 due to differences in scope flags. + if ((getLangOpts().C99 || getLangOpts().CPlusPlus) && + !Diags.isIgnored(diag::warn_comma_operator, CondExpr->getExprLoc())) CommaVisitor(*this).Visit(CondExpr); if (!elseStmt) @@ -576,9 +577,8 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, DiagnoseUnusedExprResult(thenStmt); DiagnoseUnusedExprResult(elseStmt); - return new (Context) - IfStmt(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first, - Cond.get().second, thenStmt, ElseLoc, elseStmt); + return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first, + Cond.get().second, thenStmt, ElseLoc, elseStmt); } namespace { @@ -631,8 +631,8 @@ static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs, /// GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of /// potentially integral-promoted expression @p expr. static QualType GetTypeBeforeIntegralPromotion(const Expr *&E) { - if (const auto *CleanUps = dyn_cast<ExprWithCleanups>(E)) - E = CleanUps->getSubExpr(); + if (const auto *FE = dyn_cast<FullExpr>(E)) + E = FE->getSubExpr(); while (const auto *ImpCast = dyn_cast<ImplicitCastExpr>(E)) { if (ImpCast->getCastKind() != CK_IntegralCast) break; E = ImpCast->getSubExpr(); @@ -727,8 +727,7 @@ StmtResult Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, setFunctionHasBranchIntoScope(); - SwitchStmt *SS = new (Context) - SwitchStmt(Context, InitStmt, Cond.get().first, CondExpr); + auto *SS = SwitchStmt::Create(Context, InitStmt, Cond.get().first, CondExpr); getCurFunction()->SwitchStack.push_back( FunctionScopeInfo::SwitchInfo(SS, false)); return SS; @@ -946,8 +945,11 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, llvm::APSInt ConstantCondValue; bool HasConstantCond = false; if (!HasDependentValue && !TheDefaultStmt) { - HasConstantCond = CondExpr->EvaluateAsInt(ConstantCondValue, Context, + Expr::EvalResult Result; + HasConstantCond = CondExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects); + if (Result.Val.isInt()) + ConstantCondValue = Result.Val.getInt(); assert(!HasConstantCond || (ConstantCondValue.getBitWidth() == CondWidth && ConstantCondValue.isSigned() == CondIsSigned)); @@ -1307,8 +1309,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); - return new (Context) - WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc); + return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body, + WhileLoc); } StmtResult @@ -1328,6 +1330,11 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, return StmtError(); Cond = CondResult.get(); + // Only call the CommaVisitor for C89 due to differences in scope flags. + if (Cond && !getLangOpts().C99 && !getLangOpts().CPlusPlus && + !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc())) + CommaVisitor(*this).Visit(Cond); + DiagnoseUnusedExprResult(Body); return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen); @@ -1409,7 +1416,11 @@ namespace { void VisitDeclRefExpr(DeclRefExpr *E) { VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()); - if (!VD) return; + if (!VD) { + // Don't allow unhandled Decl types. + Simple = false; + return; + } Ranges.push_back(E->getSourceRange()); @@ -3218,7 +3229,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { return StmtError(); RetValExp = ER.get(); } - return new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr); + return ReturnStmt::Create(Context, ReturnLoc, RetValExp, + /* NRVOCandidate=*/nullptr); } if (HasDeducedReturnType) { @@ -3344,8 +3356,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { return StmtError(); RetValExp = ER.get(); } - ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, - NRVOCandidate); + auto *Result = + ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate); // If we need to check for the named return value optimization, // or if we need to infer the return type, @@ -3574,7 +3586,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { return StmtError(); RetValExp = ER.get(); } - return new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr); + return ReturnStmt::Create(Context, ReturnLoc, RetValExp, + /* NRVOCandidate=*/nullptr); } // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing @@ -3669,7 +3682,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } } - Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr); + Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, + /* NRVOCandidate=*/nullptr); } else if (!RetValExp && !HasDependentReturnType) { FunctionDecl *FD = getCurFunctionDecl(); @@ -3691,7 +3705,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { else Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/; - Result = new (Context) ReturnStmt(ReturnLoc); + Result = ReturnStmt::Create(Context, ReturnLoc, /* RetExpr=*/nullptr, + /* NRVOCandidate=*/nullptr); } else { assert(RetValExp || HasDependentReturnType); const VarDecl *NRVOCandidate = nullptr; @@ -3744,7 +3759,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { return StmtError(); RetValExp = ER.get(); } - Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate); + Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate); } // If we need to check for the named return value optimization, save the diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 359bfb4464..d209266049 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -27,6 +27,58 @@ using namespace clang; using namespace sema; +/// Remove the upper-level LValueToRValue cast from an expression. +static void removeLValueToRValueCast(Expr *E) { + Expr *Parent = E; + Expr *ExprUnderCast = nullptr; + SmallVector<Expr *, 8> ParentsToUpdate; + + while (true) { + ParentsToUpdate.push_back(Parent); + if (auto *ParenE = dyn_cast<ParenExpr>(Parent)) { + Parent = ParenE->getSubExpr(); + continue; + } + + Expr *Child = nullptr; + CastExpr *ParentCast = dyn_cast<CastExpr>(Parent); + if (ParentCast) + Child = ParentCast->getSubExpr(); + else + return; + + if (auto *CastE = dyn_cast<CastExpr>(Child)) + if (CastE->getCastKind() == CK_LValueToRValue) { + ExprUnderCast = CastE->getSubExpr(); + // LValueToRValue cast inside GCCAsmStmt requires an explicit cast. + ParentCast->setSubExpr(ExprUnderCast); + break; + } + Parent = Child; + } + + // Update parent expressions to have same ValueType as the underlying. + assert(ExprUnderCast && + "Should be reachable only if LValueToRValue cast was found!"); + auto ValueKind = ExprUnderCast->getValueKind(); + for (Expr *E : ParentsToUpdate) + E->setValueKind(ValueKind); +} + +/// Emit a warning about usage of "noop"-like casts for lvalues (GNU extension) +/// and fix the argument with removing LValueToRValue cast from the expression. +static void emitAndFixInvalidAsmCastLValue(const Expr *LVal, Expr *BadArgument, + Sema &S) { + if (!S.getLangOpts().HeinousExtensions) { + S.Diag(LVal->getBeginLoc(), diag::err_invalid_asm_cast_lvalue) + << BadArgument->getSourceRange(); + } else { + S.Diag(LVal->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue) + << BadArgument->getSourceRange(); + } + removeLValueToRValueCast(BadArgument); +} + /// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently /// ignore "noop" casts in places where an lvalue is required by an inline asm. /// We emulate this behavior when -fheinous-gnu-extensions is specified, but @@ -34,7 +86,7 @@ using namespace sema; /// /// This method checks to see if the argument is an acceptable l-value and /// returns false if it is a case we can handle. -static bool CheckAsmLValue(const Expr *E, Sema &S) { +static bool CheckAsmLValue(Expr *E, Sema &S) { // Type dependent expressions will be checked during instantiation. if (E->isTypeDependent()) return false; @@ -46,12 +98,7 @@ static bool CheckAsmLValue(const Expr *E, Sema &S) { // are supposed to allow. const Expr *E2 = E->IgnoreParenNoopCasts(S.Context); if (E != E2 && E2->isLValue()) { - if (!S.getLangOpts().HeinousExtensions) - S.Diag(E2->getBeginLoc(), diag::err_invalid_asm_cast_lvalue) - << E->getSourceRange(); - else - S.Diag(E2->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue) - << E->getSourceRange(); + emitAndFixInvalidAsmCastLValue(E2, E, S); // Accept, even if we emitted an error diagnostic. return false; } @@ -264,13 +311,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, break; case Expr::MLV_LValueCast: { const Expr *LVal = OutputExpr->IgnoreParenNoopCasts(Context); - if (!getLangOpts().HeinousExtensions) { - Diag(LVal->getBeginLoc(), diag::err_invalid_asm_cast_lvalue) - << OutputExpr->getSourceRange(); - } else { - Diag(LVal->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue) - << OutputExpr->getSourceRange(); - } + emitAndFixInvalidAsmCastLValue(LVal, OutputExpr, *this); // Accept, even if we emitted an error diagnostic. break; } @@ -337,11 +378,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, << InputExpr->getSourceRange()); } else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) { if (!InputExpr->isValueDependent()) { - llvm::APSInt Result; - if (!InputExpr->EvaluateAsInt(Result, Context)) + Expr::EvalResult EVResult; + if (!InputExpr->EvaluateAsInt(EVResult, Context)) return StmtError( Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected) << Info.getConstraintStr() << InputExpr->getSourceRange()); + llvm::APSInt Result = EVResult.Val.getInt(); if (!Info.isValidAsmImmediate(Result)) return StmtError(Diag(InputExpr->getBeginLoc(), diag::err_invalid_asm_value_for_constraint) diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp index c720aff064..353cd60c4a 100644 --- a/lib/Sema/SemaStmtAttr.cpp +++ b/lib/Sema/SemaStmtAttr.cpp @@ -16,7 +16,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/LoopHint.h" #include "clang/Sema/ScopeInfo.h" #include "llvm/ADT/StringExtras.h" diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 61e51de349..c1763528df 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3052,8 +3052,42 @@ static Expr *lookThroughRangesV3Condition(Preprocessor &PP, Expr *Cond) { return Cond; } +namespace { + +// A PrinterHelper that prints more helpful diagnostics for some sub-expressions +// within failing boolean expression, such as substituting template parameters +// for actual types. +class FailedBooleanConditionPrinterHelper : public PrinterHelper { +public: + explicit FailedBooleanConditionPrinterHelper(const PrintingPolicy &P) + : Policy(P) {} + + bool handledStmt(Stmt *E, raw_ostream &OS) override { + const auto *DR = dyn_cast<DeclRefExpr>(E); + if (DR && DR->getQualifier()) { + // If this is a qualified name, expand the template arguments in nested + // qualifiers. + DR->getQualifier()->print(OS, Policy, true); + // Then print the decl itself. + const ValueDecl *VD = DR->getDecl(); + OS << VD->getName(); + if (const auto *IV = dyn_cast<VarTemplateSpecializationDecl>(VD)) { + // This is a template variable, print the expanded template arguments. + printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy); + } + return true; + } + return false; + } + +private: + const PrintingPolicy Policy; +}; + +} // end anonymous namespace + std::pair<Expr *, std::string> -Sema::findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond) { +Sema::findFailedBooleanCondition(Expr *Cond) { Cond = lookThroughRangesV3Condition(PP, Cond); // Separate out all of the terms in a conjunction. @@ -3082,18 +3116,14 @@ Sema::findFailedBooleanCondition(Expr *Cond, bool AllowTopLevelCond) { break; } } - - if (!FailedCond) { - if (!AllowTopLevelCond) - return { nullptr, "" }; - + if (!FailedCond) FailedCond = Cond->IgnoreParenImpCasts(); - } std::string Description; { llvm::raw_string_ostream Out(Description); - FailedCond->printPretty(Out, nullptr, getPrintingPolicy()); + FailedBooleanConditionPrinterHelper Helper(getPrintingPolicy()); + FailedCond->printPretty(Out, &Helper, getPrintingPolicy()); } return { FailedCond, Description }; } @@ -3177,9 +3207,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, Expr *FailedCond; std::string FailedDescription; std::tie(FailedCond, FailedDescription) = - findFailedBooleanCondition( - TemplateArgs[0].getSourceExpression(), - /*AllowTopLevelCond=*/true); + findFailedBooleanCondition(TemplateArgs[0].getSourceExpression()); // Remove the old SFINAE diagnostic. PartialDiagnosticAt OldDiag = @@ -4434,7 +4462,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef, // If the argument type is dependent, instantiate it now based // on the previously-computed template arguments. - if (ArgType->getType()->isDependentType()) { + if (ArgType->getType()->isInstantiationDependentType()) { Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Param, Template, Converted, SourceRange(TemplateLoc, RAngleLoc)); @@ -8107,7 +8135,7 @@ bool Sema::CheckFunctionTemplateSpecialization( if (OldMD && OldMD->isConst()) { const FunctionProtoType *FPT = FT->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - EPI.TypeQuals |= Qualifiers::Const; + EPI.TypeQuals.addConst(); FT = Context.getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI); } @@ -9173,10 +9201,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, if (!HasNoEffect) { // Instantiate static data member or variable template. Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); - if (PrevTemplate) { - // Merge attributes. - ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes()); - } + // Merge attributes. + ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes()); if (TSK == TSK_ExplicitInstantiationDefinition) InstantiateVariableDefinition(D.getIdentifierLoc(), Prev); } @@ -9629,7 +9655,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, Expr *FailedCond; std::string FailedDescription; std::tie(FailedCond, FailedDescription) = - findFailedBooleanCondition(Cond, /*AllowTopLevelCond=*/true); + findFailedBooleanCondition(Cond); Diag(FailedCond->getExprLoc(), diag::err_typename_nested_not_found_requirement) diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 192ab8eb24..155d842c58 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -178,6 +178,8 @@ getDeducedParameterFromExpr(TemplateDeductionInfo &Info, Expr *E) { while (true) { if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E)) E = IC->getSubExpr(); + else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) + E = CE->getSubExpr(); else if (SubstNonTypeTemplateParmExpr *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) E = Subst->getReplacement(); @@ -3076,7 +3078,7 @@ Sema::SubstituteExplicitTemplateArguments( // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq // and the end of the function-definition, member-declarator, or // declarator. - unsigned ThisTypeQuals = 0; + Qualifiers ThisTypeQuals; CXXRecordDecl *ThisContext = nullptr; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) { ThisContext = Method->getParent(); @@ -4655,8 +4657,7 @@ AddImplicitObjectParameterType(ASTContext &Context, // The standard doesn't say explicitly, but we pick the appropriate kind of // reference type based on [over.match.funcs]p4. QualType ArgTy = Context.getTypeDeclType(Method->getParent()); - ArgTy = Context.getQualifiedType(ArgTy, - Qualifiers::fromCVRMask(Method->getTypeQualifiers())); + ArgTy = Context.getQualifiedType(ArgTy, Method->getTypeQualifiers()); if (Method->getRefQualifier() == RQ_RValue) ArgTy = Context.getRValueReferenceType(ArgTy); else @@ -5225,6 +5226,8 @@ MarkUsedTemplateParameters(ASTContext &Ctx, while (true) { if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) E = ICE->getSubExpr(); + else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) + E = CE->getSubExpr(); else if (const SubstNonTypeTemplateParmExpr *Subst = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) E = Subst->getReplacement(); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 5666cf04a2..96abeed824 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -675,7 +675,7 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { // context, depending on what else is on the stack. if (isa<TypeAliasTemplateDecl>(Active->Entity)) break; - // Fall through. + LLVM_FALLTHROUGH; case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: case CodeSynthesisContext::ExceptionSpecInstantiation: // This is a template instantiation, so there is no SFINAE. @@ -907,7 +907,7 @@ namespace { QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals, + Qualifiers ThisTypeQuals, Fn TransformExceptionSpec); ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, @@ -1167,7 +1167,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) { if (!E->isTypeDependent()) return E; - return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType()); + return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind()); } ExprResult @@ -1427,7 +1427,7 @@ template<typename Fn> QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals, + Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) { // We need a local instantiation scope for this function prototype. LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); @@ -1666,7 +1666,7 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, SourceLocation Loc, DeclarationName Entity, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals) { + Qualifiers ThisTypeQuals) { assert(!CodeSynthesisContexts.empty() && "Cannot perform an instantiation without some context on the " "instantiation stack"); @@ -2148,7 +2148,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl); CXXRecordDecl *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()); - CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0, + CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(), ND && ND->isCXXInstanceMember()); Attr *NewAttr = @@ -2343,7 +2343,7 @@ bool Sema::InstantiateInClassInitializer( // Instantiate the initializer. ActOnStartCXXInClassMemberInitializer(); - CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), /*TypeQuals=*/0); + CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), Qualifiers()); ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs, /*CXXDirectInit=*/false); @@ -2574,10 +2574,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, for (auto *D : Instantiation->decls()) { bool SuppressNew = false; if (auto *Function = dyn_cast<FunctionDecl>(D)) { - if (FunctionDecl *Pattern - = Function->getInstantiatedFromMemberFunction()) { - MemberSpecializationInfo *MSInfo - = Function->getMemberSpecializationInfo(); + if (FunctionDecl *Pattern = + Function->getInstantiatedFromMemberFunction()) { + + if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + + MemberSpecializationInfo *MSInfo = + Function->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); if (MSInfo->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) @@ -2618,6 +2622,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Var->isStaticDataMember()) { + if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); if (MSInfo->getTemplateSpecializationKind() @@ -2649,6 +2656,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) { + if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + // Always skip the injected-class-name, along with any // redeclarations of nested classes, since both would cause us // to try to instantiate the members of a class twice. diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5f2b05c089..31353e45ba 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -295,7 +295,7 @@ static void instantiateOMPDeclareSimdDeclAttr( PVD, FD->getParamDecl(PVD->getFunctionScopeIndex())); return S.SubstExpr(E, TemplateArgs); } - Sema::CXXThisScopeRAII ThisScope(S, ThisContext, /*TypeQuals=*/0, + Sema::CXXThisScopeRAII ThisScope(S, ThisContext, Qualifiers(), FD->isCXXInstanceMember()); return S.SubstExpr(E, TemplateArgs); }; @@ -355,7 +355,7 @@ void Sema::InstantiateAttrsForDecl( // applicable to template declaration, we'll need to add them here. CXXThisScopeRAII ThisScope( *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()), - /*TypeQuals*/ 0, ND->isCXXInstanceMember()); + Qualifiers(), ND->isCXXInstanceMember()); Attr *NewAttr = sema::instantiateTemplateAttributeForDecl( TmplAttr, Context, *this, TemplateArgs); @@ -365,6 +365,20 @@ void Sema::InstantiateAttrsForDecl( } } +static Sema::RetainOwnershipKind +attrToRetainOwnershipKind(const Attr *A) { + switch (A->getKind()) { + case clang::attr::CFConsumed: + return Sema::RetainOwnershipKind::CF; + case clang::attr::OSConsumed: + return Sema::RetainOwnershipKind::OS; + case clang::attr::NSConsumed: + return Sema::RetainOwnershipKind::NS; + default: + llvm_unreachable("Wrong argument supplied"); + } +} + void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, Decl *New, LateInstantiatedAttrVec *LateAttrs, @@ -438,11 +452,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, continue; } - if (isa<NSConsumedAttr>(TmplAttr) || isa<CFConsumedAttr>(TmplAttr)) { - AddNSConsumedAttr(TmplAttr->getRange(), New, - TmplAttr->getSpellingListIndex(), - isa<NSConsumedAttr>(TmplAttr), - /*template instantiation*/ true); + if (isa<NSConsumedAttr>(TmplAttr) || isa<OSConsumedAttr>(TmplAttr) || + isa<CFConsumedAttr>(TmplAttr)) { + AddXConsumedAttr(New, TmplAttr->getRange(), + TmplAttr->getSpellingListIndex(), + attrToRetainOwnershipKind(TmplAttr), + /*template instantiation=*/true); continue; } @@ -459,7 +474,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, NamedDecl *ND = dyn_cast<NamedDecl>(New); CXXRecordDecl *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()); - CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0, + CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(), ND && ND->isCXXInstanceMember()); Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context, @@ -748,6 +763,9 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, Var->setImplicit(D->isImplicit()); + if (Var->isStaticLocal()) + SemaRef.CheckStaticLocalForDllExport(Var); + return Var; } @@ -1799,7 +1817,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, // If the original function was part of a friend declaration, // inherit its namespace state and add it to the owner. if (isFriend) { - PrincipalDecl->setObjectOfFriendDecl(); + Function->setObjectOfFriendDecl(); + if (FunctionTemplateDecl *FT = Function->getDescribedFunctionTemplate()) + FT->setObjectOfFriendDecl(); DC->makeDeclVisibleInContext(PrincipalDecl); bool QueuedInstantiation = false; @@ -2684,26 +2704,28 @@ Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) { } Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( - ClassScopeFunctionSpecializationDecl *Decl) { + ClassScopeFunctionSpecializationDecl *Decl) { CXXMethodDecl *OldFD = Decl->getSpecialization(); CXXMethodDecl *NewFD = cast_or_null<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, nullptr, true)); if (!NewFD) return nullptr; - LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, - Sema::ForExternalRedeclaration); - - TemplateArgumentListInfo TemplateArgs; - TemplateArgumentListInfo *TemplateArgsPtr = nullptr; + TemplateArgumentListInfo ExplicitTemplateArgs; + TemplateArgumentListInfo *ExplicitTemplateArgsPtr = nullptr; if (Decl->hasExplicitTemplateArgs()) { - TemplateArgs = Decl->templateArgs(); - TemplateArgsPtr = &TemplateArgs; + if (SemaRef.Subst(Decl->templateArgs().getArgumentArray(), + Decl->templateArgs().size(), ExplicitTemplateArgs, + TemplateArgs)) + return nullptr; + ExplicitTemplateArgsPtr = &ExplicitTemplateArgs; } + LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, + Sema::ForExternalRedeclaration); SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext); - if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, TemplateArgsPtr, - Previous)) { + if (SemaRef.CheckFunctionTemplateSpecialization( + NewFD, ExplicitTemplateArgsPtr, Previous)) { NewFD->setInvalidDecl(); return NewFD; } @@ -2800,7 +2822,7 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( cast<DeclRefExpr>(D->getCombinerOut())->getDecl(), cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl()); auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner); - Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, /*TypeQuals*/ 0, + Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(), ThisContext); SubstCombiner = SemaRef.SubstExpr(D->getCombiner(), TemplateArgs).get(); SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner); @@ -3419,7 +3441,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, assert(Params.empty() && "parameter vector is non-empty at start"); CXXRecordDecl *ThisContext = nullptr; - unsigned ThisTypeQuals = 0; + Qualifiers ThisTypeQuals; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { ThisContext = cast<CXXRecordDecl>(Owner); ThisTypeQuals = Method->getTypeQualifiers(); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 7d1d4c5d7e..3338cec5eb 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -976,6 +976,7 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, PDiag(diag::note_parameter_pack_here)); ParameterPack = Corrected.getCorrectionDecl(); } + break; case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 27dbf70498..bd4a0e1407 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -116,6 +116,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr, case ParsedAttr::AT_Pascal: \ case ParsedAttr::AT_SwiftCall: \ case ParsedAttr::AT_VectorCall: \ + case ParsedAttr::AT_AArch64VectorPcs: \ case ParsedAttr::AT_MSABI: \ case ParsedAttr::AT_SysVABI: \ case ParsedAttr::AT_Pcs: \ @@ -182,11 +183,15 @@ namespace { SmallVector<TypeAttrPair, 8> AttrsForTypes; bool AttrsForTypesSorted = true; + /// Flag to indicate we parsed a noderef attribute. This is used for + /// validating that noderef was used on a pointer or array. + bool parsedNoDeref; + public: TypeProcessingState(Sema &sema, Declarator &declarator) - : sema(sema), declarator(declarator), - chunkIndex(declarator.getNumTypeObjects()), - trivial(true), hasSavedAttrs(false) {} + : sema(sema), declarator(declarator), + chunkIndex(declarator.getNumTypeObjects()), trivial(true), + hasSavedAttrs(false), parsedNoDeref(false) {} Sema &getSema() const { return sema; @@ -277,6 +282,10 @@ namespace { llvm_unreachable("no Attr* for AttributedType*"); } + void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; } + + bool didParseNoDeref() const { return parsedNoDeref; } + ~TypeProcessingState() { if (trivial) return; @@ -1864,8 +1873,7 @@ static QualType inferARCLifetimeForPointee(Sema &S, QualType type, } static std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy){ - std::string Quals = - Qualifiers::fromCVRMask(FnTy->getTypeQuals()).getAsString(); + std::string Quals = FnTy->getTypeQuals().getAsString(); switch (FnTy->getRefQualifier()) { case RQ_None: @@ -1907,7 +1915,7 @@ static bool checkQualifiedFunction(Sema &S, QualType T, SourceLocation Loc, QualifiedFunctionKind QFK) { // Does T refer to a function type with a cv-qualifier or a ref-qualifier? const FunctionProtoType *FPT = T->getAs<FunctionProtoType>(); - if (!FPT || (FPT->getTypeQuals() == 0 && FPT->getRefQualifier() == RQ_None)) + if (!FPT || (FPT->getTypeQuals().empty() && FPT->getRefQualifier() == RQ_None)) return false; S.Diag(Loc, diag::err_compound_qualified_function_type) @@ -3886,6 +3894,11 @@ static bool hasOuterPointerLikeChunk(const Declarator &D, unsigned endIndex) { return false; } +static bool IsNoDerefableChunk(DeclaratorChunk Chunk) { + return (Chunk.Kind == DeclaratorChunk::Pointer || + Chunk.Kind == DeclaratorChunk::Array); +} + template<typename AttrT> static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &Attr) { Attr.setUsedAsTypeAttr(); @@ -3936,7 +3949,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Does T refer to a function type with a cv-qualifier or a ref-qualifier? bool IsQualifiedFunction = T->isFunctionProtoType() && - (T->castAs<FunctionProtoType>()->getTypeQuals() != 0 || + (!T->castAs<FunctionProtoType>()->getTypeQuals().empty() || T->castAs<FunctionProtoType>()->getRefQualifier() != RQ_None); // If T is 'decltype(auto)', the only declarators we can have are parens @@ -4279,6 +4292,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, } } + bool ExpectNoDerefChunk = + state.getCurrentAttributes().hasAttribute(ParsedAttr::AT_NoDeref); + // Walk the DeclTypeInfo, building the recursive type as we go. // DeclTypeInfos are ordered from the identifier out, which is // opposite of what we want :). @@ -4324,7 +4340,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, inferPointerNullability(SimplePointerKind::Pointer, DeclType.Loc, DeclType.EndLoc, DeclType.getAttrs()); - if (LangOpts.ObjC1 && T->getAs<ObjCObjectType>()) { + if (LangOpts.ObjC && T->getAs<ObjCObjectType>()) { T = Context.getObjCObjectPointerType(T); if (DeclType.Ptr.TypeQuals) T = S.BuildQualifiedType(T, DeclType.Loc, DeclType.Ptr.TypeQuals); @@ -4682,7 +4698,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, EPI.ExtInfo = EI; EPI.Variadic = FTI.isVariadic; EPI.HasTrailingReturn = FTI.hasTrailingReturnType(); - EPI.TypeQuals = FTI.TypeQuals; + EPI.TypeQuals.addCVRUQualifiers(FTI.TypeQuals); EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None : FTI.RefQualifierIsLValueRef? RQ_LValue : RQ_RValue; @@ -4809,7 +4825,24 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, Exceptions, EPI.ExceptionSpec); - T = Context.getFunctionType(T, ParamTys, EPI); + const auto &Spec = D.getCXXScopeSpec(); + // OpenCLCPlusPlus: A class member function has an address space. + if (state.getSema().getLangOpts().OpenCLCPlusPlus && + ((!Spec.isEmpty() && + Spec.getScopeRep()->getKind() == NestedNameSpecifier::TypeSpec) || + state.getDeclarator().getContext() == + DeclaratorContext::MemberContext)) { + LangAS CurAS = EPI.TypeQuals.getAddressSpace(); + // If a class member function's address space is not set, set it to + // __generic. + LangAS AS = + (CurAS == LangAS::Default ? LangAS::opencl_generic : CurAS); + EPI.TypeQuals.addAddressSpace(AS); + T = Context.getFunctionType(T, ParamTys, EPI); + T = state.getSema().Context.getAddrSpaceQualType(T, AS); + } else { + T = Context.getFunctionType(T, ParamTys, EPI); + } } break; } @@ -4888,8 +4921,22 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // See if there are any attributes on this declarator chunk. processTypeAttrs(state, T, TAL_DeclChunk, DeclType.getAttrs()); + + if (DeclType.Kind != DeclaratorChunk::Paren) { + if (ExpectNoDerefChunk) { + if (!IsNoDerefableChunk(DeclType)) + S.Diag(DeclType.Loc, diag::warn_noderef_on_non_pointer_or_array); + ExpectNoDerefChunk = false; + } + + ExpectNoDerefChunk = state.didParseNoDeref(); + } } + if (ExpectNoDerefChunk) + S.Diag(state.getDeclarator().getBeginLoc(), + diag::warn_noderef_on_non_pointer_or_array); + // GNU warning -Wstrict-prototypes // Warn if a function declaration is without a prototype. // This warning is issued for all kinds of unprototyped function @@ -5000,7 +5047,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, // Strip the cv-qualifiers and ref-qualifiers from the type. FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo(); - EPI.TypeQuals = 0; + EPI.TypeQuals.removeCVRQualifiers(); EPI.RefQualifier = RQ_None; T = Context.getFunctionType(FnTy->getReturnType(), FnTy->getParamTypes(), @@ -5238,7 +5285,7 @@ TypeSourceInfo *Sema::GetTypeForDeclaratorCast(Declarator &D, QualType FromTy) { TypeSourceInfo *ReturnTypeInfo = nullptr; QualType declSpecTy = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo); - if (getLangOpts().ObjC1) { + if (getLangOpts().ObjC) { Qualifiers::ObjCLifetime ownership = Context.getInnerObjCOwnership(FromTy); if (ownership != Qualifiers::OCL_None) transferARCOwnership(state, declSpecTy, ownership); @@ -6653,6 +6700,8 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) { return createSimpleAttr<SwiftCallAttr>(Ctx, Attr); case ParsedAttr::AT_VectorCall: return createSimpleAttr<VectorCallAttr>(Ctx, Attr); + case ParsedAttr::AT_AArch64VectorPcs: + return createSimpleAttr<AArch64VectorPcsAttr>(Ctx, Attr); case ParsedAttr::AT_Pcs: { // The attribute may have had a fixit applied where we treated an // identifier as a string literal. The contents of the string are valid, @@ -7177,7 +7226,8 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State, bool IsPointee = ChunkIndex > 0 && (D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Pointer || - D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::BlockPointer); + D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::BlockPointer || + D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Reference); bool IsFuncReturnType = ChunkIndex > 0 && D.getTypeObject(ChunkIndex - 1).Kind == DeclaratorChunk::Function; @@ -7197,10 +7247,13 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State, !IsPointee) || // Do not deduce addr space of the void type, e.g. in f(void), otherwise // it will fail some sema check. - (T->isVoidType() && !IsPointee)) + (T->isVoidType() && !IsPointee) || + // Do not deduce address spaces for dependent types because they might end + // up instantiating to a type with an explicit address space qualifier. + T->isDependentType()) return; - LangAS ImpAddr; + LangAS ImpAddr = LangAS::Default; // Put OpenCL automatic variable in private address space. // OpenCL v1.2 s6.5: // The default address space name for arguments to a function in a @@ -7222,7 +7275,9 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State, if (IsPointee) { ImpAddr = LangAS::opencl_generic; } else { - if (D.getContext() == DeclaratorContext::FileContext) { + if (D.getContext() == DeclaratorContext::TemplateArgContext) { + // Do not deduce address space for non-pointee type in template arg. + } else if (D.getContext() == DeclaratorContext::FileContext) { ImpAddr = LangAS::opencl_global; } else { if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || @@ -7262,6 +7317,9 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, // sure we visit every element once. Copy the attributes list, and iterate // over that. ParsedAttributesView AttrsCopy{attrs}; + + state.setParsedNoDeref(false); + for (ParsedAttr &attr : AttrsCopy) { // Skip attributes that were marked to be invalid. @@ -7273,7 +7331,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, // not appertain to a DeclaratorChunk. If we handle them as type // attributes, accept them in that position and diagnose the GCC // incompatibility. - if (attr.getScopeName() && attr.getScopeName()->isStr("gnu")) { + if (attr.isGNUScope()) { bool IsTypeAttr = attr.isTypeAttr(); if (TAL == TAL_DeclChunk) { state.getSema().Diag(attr.getLoc(), @@ -7359,6 +7417,15 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type, HandleLifetimeBoundAttr(state, type, attr); break; + case ParsedAttr::AT_NoDeref: { + ASTContext &Ctx = state.getSema().Context; + type = state.getAttributedType(createSimpleAttr<NoDerefAttr>(Ctx, attr), + type, type); + attr.setUsedAsTypeAttr(); + state.setParsedNoDeref(true); + break; + } + MS_TYPE_ATTRS_CASELIST: if (!handleMSPointerTypeQualifierAttr(state, attr, type)) attr.setUsedAsTypeAttr(); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index a75d307563..3f4b21eb55 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -597,7 +597,7 @@ public: QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals, + Qualifiers ThisTypeQuals, Fn TransformExceptionSpec); bool TransformExceptionSpec(SourceLocation Loc, @@ -684,15 +684,13 @@ public: OMPClause *Transform ## Class(Class *S); #include "clang/Basic/OpenMPKinds.def" - /// Build a new qualified type given its unqualified type and type - /// qualifiers. + /// Build a new qualified type given its unqualified type and type location. /// /// By default, this routine adds type qualifiers only to types that can /// have qualifiers, and silently suppresses those qualifiers that are not /// permitted. Subclasses may override this routine to provide different /// behavior. - QualType RebuildQualifiedType(QualType T, SourceLocation Loc, - Qualifiers Quals); + QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL); /// Build a new pointer type given its pointee type. /// @@ -2096,8 +2094,8 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT) { - return getSema().BuildPredefinedExpr(Loc, IT); + PredefinedExpr::IdentKind IK) { + return getSema().BuildPredefinedExpr(Loc, IK); } /// Build a new expression that references a declaration. @@ -3344,8 +3342,8 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init, if (!Init) return Init; - if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init)) - Init = ExprTemp->getSubExpr(); + if (auto *FE = dyn_cast<FullExpr>(Init)) + Init = FE->getSubExpr(); if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) Init = AIL->getCommonExpr(); @@ -4228,8 +4226,9 @@ TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) { return nullptr; if (QTL) { - Result = getDerived().RebuildQualifiedType( - Result, QTL.getBeginLoc(), QTL.getType().getLocalQualifiers()); + Result = getDerived().RebuildQualifiedType(Result, QTL); + if (Result.isNull()) + return nullptr; TLB.TypeWasModifiedSafely(Result); } @@ -4240,13 +4239,14 @@ template<typename Derived> QualType TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, QualifiedTypeLoc T) { - Qualifiers Quals = T.getType().getLocalQualifiers(); - QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc()); if (Result.isNull()) return QualType(); - Result = getDerived().RebuildQualifiedType(Result, T.getBeginLoc(), Quals); + Result = getDerived().RebuildQualifiedType(Result, T); + + if (Result.isNull()) + return QualType(); // RebuildQualifiedType might have updated the type, but not in a way // that invalidates the TypeLoc. (There's no location information for @@ -4256,15 +4256,29 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, return Result; } -template<typename Derived> +template <typename Derived> QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T, - SourceLocation Loc, - Qualifiers Quals) { + QualifiedTypeLoc TL) { + + SourceLocation Loc = TL.getBeginLoc(); + Qualifiers Quals = TL.getType().getLocalQualifiers(); + + if (((T.getAddressSpace() != LangAS::Default && + Quals.getAddressSpace() != LangAS::Default)) && + T.getAddressSpace() != Quals.getAddressSpace()) { + SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst) + << TL.getType() << T; + return QualType(); + } + // C++ [dcl.fct]p7: // [When] adding cv-qualifications on top of the function type [...] the // cv-qualifiers are ignored. - if (T->isFunctionType()) + if (T->isFunctionType()) { + T = SemaRef.getASTContext().getAddrSpaceQualType(T, + Quals.getAddressSpace()); return T; + } // C++ [dcl.ref]p1: // when the cv-qualifiers are introduced through the use of a typedef-name @@ -5231,7 +5245,7 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, SmallVector<QualType, 4> ExceptionStorage; TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. return getDerived().TransformFunctionProtoType( - TLB, TL, nullptr, 0, + TLB, TL, nullptr, Qualifiers(), [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { return This->TransformExceptionSpec(TL.getBeginLoc(), ESI, ExceptionStorage, Changed); @@ -5241,7 +5255,7 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, template<typename Derived> template<typename Fn> QualType TreeTransform<Derived>::TransformFunctionProtoType( TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals, Fn TransformExceptionSpec) { + Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) { // Transform the parameters and return type. // @@ -5284,6 +5298,13 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType( if (ResultType.isNull()) return QualType(); + // Return type can not be qualified with an address space. + if (ResultType.getAddressSpace() != LangAS::Default) { + SemaRef.Diag(TL.getReturnLoc().getBeginLoc(), + diag::err_attribute_address_function_type); + return QualType(); + } + if (getDerived().TransformFunctionTypeParams( TL.getBeginLoc(), TL.getParams(), TL.getTypePtr()->param_type_begin(), @@ -6770,6 +6791,9 @@ TreeTransform<Derived>::TransformDoStmt(DoStmt *S) { template<typename Derived> StmtResult TreeTransform<Derived>::TransformForStmt(ForStmt *S) { + if (getSema().getLangOpts().OpenMP) + getSema().startOpenMPLoop(); + // Transform the initialization statement StmtResult Init = getDerived().TransformStmt(S->getInit()); if (Init.isInvalid()) @@ -8437,6 +8461,33 @@ OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause( } template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause( + OMPUnifiedSharedMemoryClause *C) { + llvm_unreachable( + "unified_shared_memory clause cannot appear in dependent context"); +} + +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause( + OMPReverseOffloadClause *C) { + llvm_unreachable("reverse_offload clause cannot appear in dependent context"); +} + +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause( + OMPDynamicAllocatorsClause *C) { + llvm_unreachable( + "dynamic_allocators clause cannot appear in dependent context"); +} + +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause( + OMPAtomicDefaultMemOrderClause *C) { + llvm_unreachable( + "atomic_default_mem_order clause cannot appear in dependent context"); +} + +template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { llvm::SmallVector<Expr *, 16> Vars; @@ -8896,12 +8947,18 @@ TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { //===----------------------------------------------------------------------===// template<typename Derived> ExprResult +TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) { + return TransformExpr(E->getSubExpr()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) { if (!E->isTypeDependent()) return E; return getDerived().RebuildPredefinedExpr(E->getLocation(), - E->getIdentType()); + E->getIdentKind()); } template<typename Derived> @@ -10970,7 +11027,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { SmallVector<QualType, 4> ExceptionStorage; TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. QualType NewCallOpType = TransformFunctionProtoType( - NewCallOpTLBuilder, OldCallOpFPTL, nullptr, 0, + NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(), [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI, ExceptionStorage, Changed); |